aboutsummaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authorYaroslav <contact@yaroslavps.com>2020-03-17 15:19:15 +0300
committerYaroslav <contact@yaroslavps.com>2020-03-17 15:19:15 +0300
commita9e50293dceb237d665ba56903d414f5302ca4ff (patch)
tree185d310ba37366b37a11e1d695571759b11784a2 /content
parent2dace68a24ca0fc4355b2ebceea8eaa1be36fd10 (diff)
downloadyaroslavps.com-a9e50293dceb237d665ba56903d414f5302ca4ff.tar.gz
yaroslavps.com-a9e50293dceb237d665ba56903d414f5302ca4ff.zip
started migration of weblog articles
Diffstat (limited to 'content')
-rw-r--r--content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt1/index.md2
-rw-r--r--content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md365
-rw-r--r--content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/result.pngbin0 -> 117627 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/add_category.pngbin0 -> 65640 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/add_post.pngbin0 -> 126321 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/admin1.pngbin0 -> 56066 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/first_launch.pngbin0 -> 57183 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/index.md251
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/multilang_post.pngbin0 -> 156002 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/pinned_post.pngbin0 -> 101399 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/pinned_post2.pngbin0 -> 151217 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/post_en_español.pngbin0 -> 60136 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/post_en_español2.pngbin0 -> 121267 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/preview.pngbin0 -> 156488 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/publish_post.pngbin0 -> 90949 bytes
-rw-r--r--content/weblog/2018-07-23_w3blog-blog-engine/published_post.pngbin0 -> 110872 bytes
-rw-r--r--content/weblog/2018-08-03_how-to-break-and-repair-pip/index.es.md62
-rw-r--r--content/weblog/2018-08-03_how-to-break-and-repair-pip/index.md59
-rw-r--r--content/weblog/2018-08-03_how-to-break-and-repair-pip/index.ru.md61
19 files changed, 799 insertions, 1 deletions
diff --git a/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt1/index.md b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt1/index.md
index b961a83..9590946 100644
--- a/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt1/index.md
+++ b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt1/index.md
@@ -1,6 +1,6 @@
+++
title = "Building and deploying a personal site with blog. Part 1"
-date = 2018-07-21T20:46:00Z
+date = 2018-07-21T21:46:00Z
+++
I will be explaining in this guide how I built, and how I deployed this site.
diff --git a/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md
new file mode 100644
index 0000000..5bfd1f1
--- /dev/null
+++ b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md
@@ -0,0 +1,365 @@
++++
+title = "Building and deploying a personal site with blog. Part 2"
+date = 2018-07-21T22:26:00Z
++++
+
+Welcome back, this post is a continuation of the previous post in which I wrote
+about how to initialize and setup a Django project for a personal site with
+blog locally. Now we will be focusing on the juicy part, getting your site
+deployed so that everyone on the interwebz can get to see ~~your nice new dank
+memes in your very own site!~~ the fruits of your sweat and blood.
+
+<!-- more -->
+
+_You might want to read [part one](/weblog/building-deploying-personal-site-with-blog-pt1/)_
+
+## Part II: Deploying your site
+
+I will assume that you already have bought a VPS or dedicated server in any of
+the many hosting services available online, or maybe if you are cool enough,
+might even have a machine of your own with a properly setup static IP address.
+Note that if you are using shared hosting, the deployment process is usually
+already automatized if they have support for Python and Django, if they don't
+support Python and Django, you need to get another hosting solution.
+
+If you still don't have any kind of hosting, and you are looking for a nice and
+comfy VPS for your projects, I would recommend using DigitalOcean, you can get
+a VPS powerful enough for Django and other Python web projects for as low as
+$5. You can follow this referral link if you have decided to try DigitalOcean,
+it will give a $10 credit for your first account, enough for two whole months
+on their most inexpensive VPS.
+
+Once you have your server set and ready to go, we can continue with the fun
+part. Deploying your site. I will be assuming that you have a Debian-based
+distro in your server.
+
+
+
+### First steps
+
+First let's make sure that our server is up to date
+
+```sh
+$ sudo apt-get update
+$ sudo apt-get upgrade
+```
+
+Next, we need to install all the needed packages
+
+```sh
+$ sudo apt-get install python3 python3-pip python-virtualenv postgresql nginx supervisor
+```
+
+You can set the virtual environment with your login user, or create another
+user exclusively to run your Django project and other related stuff.
+
+You can add a user to run the app like so
+
+```sh
+$ adduser webuser
+```
+
+Let's go ahead and create a directory for virtual environments and create the environment for our project
+
+```sh
+$ virtualenv mysite -p python3
+```
+
+Now we source the environment
+
+```sh
+$ source mysite/bin/activate
+```
+
+And use pip to install the necessary modules
+
+```sh
+$ pip install Django Pillow psycopg2 django-summernote w3blog
+```
+
+After that, we start and enable postgresql
+
+```sh
+$ sudo systemctl start postgresql
+$ sudo systemctl enable postgresql
+```
+
+Login to the postgres shell, set the password for user postgres, and create the
+database for our project
+
+```sh
+$ sudo su - postgres
+$ psql
+postgres=# \password
+postgres=# create database mysitedb;
+```
+
+In this case, I am using the postgres user directly since I am using this
+server just for myself, and I only use PSQL for my blog. However, if you host
+multiple projects, and/or multiple users have a more direct access to postgres,
+you might want to create separate users and roles for each database or group of
+databases.
+
+### Copying your Django project to the server
+
+One way to copy your project files to the server would be using scp, for
+example
+
+```sh
+scp -r /path/to/project user@serveripordomain:/home/webuser/
+```
+
+Or if you are already hosting your project as a git repository in a service
+like GitHub or BitBucket, you could clone directly into you repository in the
+home folder, like so
+
+```sh
+$ git clone https:/github.com/user/repo
+```
+
+After the files have been copied, we need to set some things up for our Django
+project. Before running this commads, you might need to export the needed
+environmental variables, if you set up your Django settings using environmental
+variables as I wrote in the first part. Otherwise, you might want to edit your
+settings.py file now with the correct settings.
+
+First we collect static files
+
+```sh
+$ ./manage.py collectstatic
+```
+
+Then, we migrate our models to the database
+
+```sh
+$ ./manage.py migrate
+```
+
+And after migrating we create a superuser for the Django admin
+
+```sh
+$ ./manage.py createsuperuser
+```
+
+If you get an authentication error while performing any of the above commands,
+you will have to edit the following file
+
+```sh
+$ sudoedit /etc/postgresql/9.1/main/pg_hba.conf
+```
+
+Change this line
+
+```
+local all postgres peer
+```
+
+So that it looks like this
+
+```
+local all postgres md5
+```
+
+### Configuring the server
+
+I will be assuming that you are going to use nginx as a proxy server for
+Django. There are other alternatives such as Apache, but I found nginx to be a
+really powerful and easy to setup server.
+
+First, while in our virtual environment, we will install gunicorn. We might
+have been using Django's own development server while building and testing our
+app locally, but that's what it is, a development server. It is not mean for
+production, so we will use gunicorn for that
+
+```sh
+pip install gunicorn
+```
+
+Now we'll cd into our env's bin folder and create a file called
+`gunicorn_start`, and add the following lines to it:
+
+```sh
+#!/bin/bash
+NAME="mysite"
+# Our site's directory
+DIR=/home/webuser/mysite
+USER=webuser
+GROUP=webuser
+WORKERS=3
+BIND=127.0.0.1:8001
+DJANGO_SETTINGS_MODULE=mysite.settings
+DJANGO_WSGI_MODULE=mysite.wsgi
+LOG_LEVEL=error
+
+cd $DIR
+source /home/webuser/venvs/mysite/bin/activate
+
+export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
+export PYTHONPATH=$DIR:$PYTHONPATH
+
+# This are the environment variables needed for your Django settings
+# (see the first part of this guide)
+export SITE_SECRETKEY="YOURSECRETKEYGOESHERE"
+export SITE_DEBUG="false"
+export SITE_DBPASSWORD="YOURPOSTGRESPWDGOESHERE"
+export SITE_DBUSER="postgres"
+export SITE_HOST="localhost"
+export SITE_PORT="5342"
+
+exec /home/webuser/venvs/mysite/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
+ --name $NAME \
+ --workers $WORKERS \
+ --user=$USER \
+ --group=$GROUP \
+ --bind=$BIND \
+ --log-level=$LOG_LEVEL \
+ --log-file=-
+```
+
+And make it executable
+
+```sh
+$ chmod a+x gunicorn_start
+```
+
+That's almost it, but before actually running gunicorn, we will install one
+more program which will take care of the gunicorn server, so that if for any
+reason we need to reboot our server, it will restart gunicorn for us. It needs
+to be some kind of supervisor. Well why my dear friend, we are going to use
+Supervisor.
+
+But first, let's create a folder name logs inside our webuser's home folder,
+and create a file to be used to log any application errors:
+
+```sh
+$ mkdir logs
+$ touch logs/gunicorn.log
+```
+
+Now we create a new Supervisor config file:
+
+```sh
+$ sudoedit /etc/supervisor/conf.d/mysite.conf
+```
+
+Add the following:
+
+```cfg
+[program:mysite]
+command=/home/webuser/venvs/mysite/bin/gunicorn_start
+user=webuser
+autostart=true
+autorestart=true
+redirect_stderr=true
+stdout_logfile=/home/webuser/logs/gunicorn.log
+```
+
+We reread the Supervisor configuration files, and start the program:
+
+```sh
+$ sudo supervisorctl reread
+$ sudo supervisorctl update
+```
+
+And check the status to make sure it is running fine and dandy
+
+```sh
+$ sudo supervisorctl status mysite
+```
+
+Next we should configure nginx, and for that we are going to make the
+configuration file for our site. Open it up
+
+```sh
+$ sudoedit /etc/nginx/sites-available/mysite
+```
+
+And add the following lines
+
+```nginx
+server {
+ listen 80;
+ listen [::]:80;
+
+ server_name www.example.com;
+
+ location /static/ {
+ alias /home/webuser/mysite/static/;
+ }
+
+ location /media/ {
+ alias /home/webuser/mysite/media/;
+ }
+
+ location / {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Host $http_host;
+ proxy_redirect off;
+ proxy_pass http://127.0.0.1:8001;
+ }
+}
+```
+
+I won't be explaining in this guide how to setup an SSL certificate, since it
+is out of its scope, but, if you want to get a free certificate, I cant point
+you to letsencrypt.com. It is backed by many of the top internet organizations.
+If you already have an SSL certificate, and would like to use HTTPS, your file
+should look like this
+
+```nginx
+server {
+ listen 80;
+ listen [::]:80;
+ server_name www.example.com;
+ return 301 https://$host$request_uri;
+}
+
+server {
+ listen 443 ssl;
+
+ server_name www.example.com;
+ ssl_certificate /path/to/cert/fullchain.pem;
+ ssl_certificate_key /path/to/key/privkey.pem;
+ location /static/ {
+ alias /home/webuser/mysite/static/;
+ }
+ location /media/ {
+ alias /home/webuser/mysite/media/;
+ }
+ location / {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Host $http_host;
+ proxy_redirect off;
+ proxy_pass http://127.0.0.1:8001;
+ }
+}
+```
+
+After creating the needed config file, we create a symbolic link to it in sites-enabled
+
+```sh
+$ sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite
+```
+
+Remove the default nginx site
+
+```sh
+$ sudo rm /etc/nginx/sites-enabled/default
+```
+
+Finally, we restart nginx
+
+```sh
+$ sudo service nginx restart
+```
+
+Et voila!
+
+![It's alive!](result.png)
+
+## Final thoughts
+
+This was by no means the most comprehensive guide to Django, but it might help
+you get started on setting up your own projects, and most importantly, actually
+deploying them to a live server.
+
diff --git a/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/result.png b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/result.png
new file mode 100644
index 0000000..586f708
--- /dev/null
+++ b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/result.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/add_category.png b/content/weblog/2018-07-23_w3blog-blog-engine/add_category.png
new file mode 100644
index 0000000..0aaef6f
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/add_category.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/add_post.png b/content/weblog/2018-07-23_w3blog-blog-engine/add_post.png
new file mode 100644
index 0000000..b0a2fd1
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/add_post.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/admin1.png b/content/weblog/2018-07-23_w3blog-blog-engine/admin1.png
new file mode 100644
index 0000000..68df825
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/admin1.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/first_launch.png b/content/weblog/2018-07-23_w3blog-blog-engine/first_launch.png
new file mode 100644
index 0000000..f185cca
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/first_launch.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/index.md b/content/weblog/2018-07-23_w3blog-blog-engine/index.md
new file mode 100644
index 0000000..d6c88d2
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/index.md
@@ -0,0 +1,251 @@
++++
+title = "w3blog, a simple blog engine"
+date = 2018-07-23T02:05:00Z
++++
+
+![w3blog](preview.png)
+
+In this post I will be explaining how to use my blog engine for the Django
+framework, w3blog.
+
+<!-- more -->
+
+## First, an introduction
+
+I decided to create my own blog engine because I didn't find one for Django
+that satisfied my needs. That is, I wanted a simple to setup, but customizable
+blog engine that offered multilingual capabilities since I wanted to write my
+blog in three different languages (English, Spanish and Russian). I wanted to
+be able to write posts in different languages and make use of Django's built-in
+localization engine, so that if user's locale is, for example, Spanish, so that
+they would immediately see the posts in Spanish, if they are already translated
+to Spanish.
+
+The following is a short list of features of w3blog:
+
+* Users can post anonymous comments, if enabled
+* Allow only registered users to post comments through Django's built-in
+ authentication engine, if enabled
+* Can use own base template
+* RSS
+* Turn on or off the sidebar, and chose to show categories, archive list, none,
+ or both in the sidebar
+* Show or hide the author of the post, and whether it shows the author's name
+ or username
+* Enable or disable multilingual features
+
+These are features available as of the writing of this post (v0.4.2). In the
+next version (v0.5.x) I plan on adding the ability to further customize the
+sidebar without having to modify the internal templates of the app.
+
+I will be showing you further down below how to setup the engine to customize these features.
+
+## Setup
+
+First of all, you need to install a couple of python modules with pip. w3blog
+itself, and django-summernote. Check out https://summernote.org/ for more
+information about it.
+
+```sh
+$ pip install w3blog django-summernote
+```
+
+After installing them, we need to add to the settings.py list of installed apps
+
+```py
+INSTALLED_APPS = [
+ '...',
+ 'django_summernote',
+ 'weblog',
+]
+```
+
+And add the following urls to our project's main urls.py
+
+```py
+url(r'^blog/', include('weblog.urls')),
+url(r'^summernote/', include('django_summernote.urls')),
+```
+
+So if we now run our development server and go to our browser to the respective
+link, we should now see something similar to the following
+
+![w3blog home page on first launch](first_launch.jpg)
+
+After creating a django super user and going to the admin, we can now see a
+weblog section with two models: Blog posts and Categories.
+
+![Admin panel on first launch](admin1.png)
+
+We can add a category
+
+![Adding a category](add_category.png)
+
+We could try and add a post now
+
+![Adding a post](add_post.png)
+
+Chose a slug (the portion of the url for the post), the categor(y/ies), whether
+we want it to be available to the reader after saving (Published) and the date
+and time of publication.
+
+![Publishing a post](publish_post.png)
+
+After adding our post, the page now looks like this
+
+![A published post](published_post.png)
+
+I will better explain what the options above mean next.
+
+## Configuration
+
+That already looks much like a blog, but what if we wanted to use our own base
+template (the one containing the header/navbar), or show the categories on the
+sidebar. If you want to change the settings for w3blog, you need to add the
+`WEBLOG_SETTINGS` dictionary to your settings.py. The following are available
+settings that you can change (with their defaults):
+
+```py
+WEBLOG_SETTINGS = {
+ 'enable_comments': False,
+ 'allow_anon_comments': False,
+ 'multilingual': True,
+ 'blog_title': 'Django-Weblog',
+ 'base_template': 'weblog_base.html',
+ 'show_author': True,
+ 'use_authors_username': True,
+ 'show_sidebar': True,
+ 'show_categories': False,
+ 'show_archive': True,
+ 'posts_per_page': 10,
+ 'enable_rss': True,
+ 'home_title': 'Welcome to the blog!',
+}
+```
+
+So most of them are pretty self explanatory, but I will explain them to avoid
+confusion nonetheless:
+
+* enable_comments -- set to True to enable users to post comments on the posts.
+* allow_anon_comments -- allow anonymous comments.
+* multilingual -- enable multilingual features, i.e. translations of posts.
+* blog_title -- the title of the blog, will be used on the blog's homepage and
+ title tag
+* base_template -- which base template to use. If not set, will use w3blog's
+ default template.
+* show_author -- set to True to display the author of the post on each post
+* use_authors_username -- set to True to use the author's username (e.g.
+ author66) instead of their full name (e.g. John Smith).
+* show_sidebar -- set to True to show the sidebar (where the category and
+ archive lists reside).
+* show_categories -- set to True to show the categories list on the sidebar
+ (won't show if you disabled the sidebar)
+* show_archive -- set to True to show the archive list on the sidebar (won't
+ show if you disabled the sidebar)
+* posts_per_page -- the number of pages to display per page.
+* enable_rss -- set to True to enable the RSS feed (/rss)
+* home_title -- if set, it will display on the blog's home page instead of
+ blog_title (but blog_title will display in the title tag).
+
+Now, you most probably will want to use your own template, in that case, make
+sure to add the following to your template's head tag
+
+```jinja2
+<meta charset="utf-8">
+<meta content="width=device-width, initial-scale=1" name="viewport">
+<title>{{ blog_title }} - {% block title_block %} Home {% endblock %}</title>
+<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
+<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous">
+<link rel="stylesheet" href="{% static '/weblog/css/weblog.css' %}">
+<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
+<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
+<script src="{% static '/weblog/js/weblog.js' %}" defer></script>
+```
+
+Another option, if you don't want to use bootstrap, would be to use your own
+css files using bootstrap's classes. You will want to check the templates'
+source code of my engine for reference in [w3blog's GitHub
+page](https://github.com/Yaroslav-95/w3blog/blob/master/weblog/templates/weblog_base.html).
+
+## Using w3blog
+
+Let us go back a little bit and discuss how to use w3blog. As we saw in the
+beginning, you can add posts and categories through the admin. Let's focus on
+the adding posts part by checking this screenshot
+
+As you can see, there are several option there to chose from
+
+* Preview image -- use this to upload an image that you want to be displayed in
+ the preview of your post (in the home/category/archive page)
+* Preview text -- use this to set the text that will be displayed in the
+ preview of your post. If you don't set it, w3blog will automatically use the
+ first paragraph of your post's body as preview text.
+* Original language (ISO) -- the ISO code of the original language of your post
+ (e.g. "en"). This setting is not mandatory, and if you don't set and have
+ translations for your post, it will assume that the original language is the
+ one set in your settings.py file (LANGUAGE variable).
+* Slug (URL) -- this will be the url part of your post. If you still don't
+ understand what a slug is, Check out this link.
+* Categories -- the category or categories that your post will belong to. If
+ none are set, your post will be categorized under an "Uncategorized"
+ category. Important note here: you should not set the slug of a category to
+ "misc" since that is already used by weblog to display posts without a
+ category.
+* Pin blog post -- use this if you want to pin the post to the home page and
+ show above the rest of the posts
+* Pinned post priority -- if you pinned several posts, you use this to set
+ their priority
+* Published -- this sets whether the post is available to your readers. This
+ can be useful, for example, when you've started writing a post, but haven't
+ finished and want to save a draft of it, so you don't check this checkbox so
+ that it doesn't display in your blog.
+* Publish date -- date and time the post was published.
+
+Let's try making a new post and setting it to pinned, to see what happens
+
+![Adding a pinned post](pinned_post.png)
+
+So it will appear in our homepage at the very beginning
+
+![A pinned post](pinned_post2.png)
+
+## Translations
+
+Adding a translation to a post is really simple if we have the multilingual
+feature enabled in the settings. While adding our post, or after adding it, we
+can go to the bottom of the add blog post page and add it. We will see some
+similar options to the ones for the original blog post.
+
+Let's suppose I want to add a Spanish translation. For that, I would type in
+"es" as Language, and then just type the title, content, and if needed, the
+preview image and text for my Spanish translation.
+
+![Creando un post en español](post_en_español.png)
+
+After saving, if we go to the blog with computer or browser with Spanish
+language locale set, we will the site in spanish with the aforementioned's post
+Spanish translation
+
+![Este es un post en español](post_en_español2.png)
+
+Or if we go to the post itself, we will see an option to choose to read the option in a different language.
+
+![Multi-language post](multilang_post.png)
+
+Similarly, we can add translations for each category, if we so wish.
+
+So, this is basically it on how to use w3blog to set up your own blog using
+Django. I hope this post and my blog engine were useful to you. If you have any
+questions you can ~~leave a comment here, or~~ contact me at my email
+[contact@yaroslavps.com](mailto:contact@yaroslavps.com)
+
+If you have found a bug or problem with w3blog, be sure to open an issue on
+GitHub. The app is currently only translated to English, Spanish, and Russian,
+so if you are willing to provide a translation for your language or any other
+language that you know, you can send a pull request with the translated
+strings, or download the strings for the git repository, translate them, and
+send them to me so that I can compile them and add them to the project myself.
+
+Thank you very much for reading this post, and I will be very happy to see your
+projects using my blog engine!
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/multilang_post.png b/content/weblog/2018-07-23_w3blog-blog-engine/multilang_post.png
new file mode 100644
index 0000000..22be9c9
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/multilang_post.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/pinned_post.png b/content/weblog/2018-07-23_w3blog-blog-engine/pinned_post.png
new file mode 100644
index 0000000..82f3cbf
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/pinned_post.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/pinned_post2.png b/content/weblog/2018-07-23_w3blog-blog-engine/pinned_post2.png
new file mode 100644
index 0000000..ea237d6
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/pinned_post2.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/post_en_español.png b/content/weblog/2018-07-23_w3blog-blog-engine/post_en_español.png
new file mode 100644
index 0000000..c4f17d0
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/post_en_español.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/post_en_español2.png b/content/weblog/2018-07-23_w3blog-blog-engine/post_en_español2.png
new file mode 100644
index 0000000..7de284b
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/post_en_español2.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/preview.png b/content/weblog/2018-07-23_w3blog-blog-engine/preview.png
new file mode 100644
index 0000000..85c1b32
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/preview.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/publish_post.png b/content/weblog/2018-07-23_w3blog-blog-engine/publish_post.png
new file mode 100644
index 0000000..a5f267f
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/publish_post.png
Binary files differ
diff --git a/content/weblog/2018-07-23_w3blog-blog-engine/published_post.png b/content/weblog/2018-07-23_w3blog-blog-engine/published_post.png
new file mode 100644
index 0000000..fe09dc2
--- /dev/null
+++ b/content/weblog/2018-07-23_w3blog-blog-engine/published_post.png
Binary files differ
diff --git a/content/weblog/2018-08-03_how-to-break-and-repair-pip/index.es.md b/content/weblog/2018-08-03_how-to-break-and-repair-pip/index.es.md
new file mode 100644
index 0000000..6458da7
--- /dev/null
+++ b/content/weblog/2018-08-03_how-to-break-and-repair-pip/index.es.md
@@ -0,0 +1,62 @@
++++
+title = "How to break pip, and how to repair it..."
+date = 2018-08-03T22:00:00Z
++++
+
+A veces, un programa nos puede sugerir hacer algo, y posiblemente sigas el
+consejo que te haya ofrecido porque ¿Por qué no? Confías en los desarrolladores
+que lo hicieron, y como han hecho un maravilloso trabajo desarrollando el
+programa, seguramente saben de lo que hablan.
+
+<!-- more -->
+
+Sin embargo, esto no parece ser así con pip. Me encontré con este error en mi
+laptop y en mi computadora de escritorio, en las cuales tengo instalado
+Manjaro, y logré corregirlo en mi portátil. Sin embargo, cuando me volví a
+encontrar con el problema en mi computadora de escritorio, ya se me había
+olvidado como repararlo. El problema: cuando intentas instalar algún modulo a
+nivel de sistema con pip (por ejemplo, pywal), sale un excepción como
+'ModuleNotFoundError' que previene la instalación de dicho módulo.
+
+Primero escribiré qué es lo que NO hay que hacer para evitar el problema.
+
+Probablemente te salga un mensaje como éste después de haber usado pip
+
+```sh
+You are using pip version x.x.x, however version x.x is available.
+You should consider upgrading via the 'pip install --upgrade pip' command.
+```
+
+Si te sale éste mensajito al estar usando pip fuera de un medio virtual
+(virtual environment), NO le hagas caso. Ni siquiera le mires. Simplemente
+ignóralo. Yo le hice caso, y mira a lo que me llevo. Por hacerle caso ahora
+estoy escribiendo una entrada acerca de como arreglar este rollo por haberle
+hecho caso al mensaje. Al menos ignóralo si estás usando una distribución
+basada en Arch. No sé cómo sea en las demás, ya que no me acuerdo haberme
+encontrado con este error cuando usaba Debian.
+
+Vaya, que si estás usando un medio virtual, claro que puedes, y deberías,
+actualizar pip como dice el mensaje. Pero si estás fuera de un medio virtual
+instalando paquetes a nivel de sistema, tu administrador de paquetes (pacman)
+se hará cargo de actualizar pip al momento en que actualices el resto del
+sistema (pacman -Syu).
+
+## La solución
+
+Si tú, desafortunadamente, al igual que yo, ya hiciste la chorrada de
+actualizar pip usando nada más y nada menos que pip, primero deberás eliminar
+los archivos de pip ejecutando el siguiente comando:
+
+```sh
+$ sudo rm -rf /usr/lib/python3.6/site-packages/pip /usr/lib/python3.6/site-packages/pkg_resources
+```
+
+Posteriormente, necesitarás reinstalar pip y setup tools:
+
+```sh
+$ sudo pacman -S python-setuptools python-pip
+```
+
+Y ya está ¡Así de fácil!.
+
+La solución la encontré en el siguiente foro: [https://bbs.archlinux.org/viewtopic.php?id=237451](https://bbs.archlinux.org/viewtopic.php?id=237451)
diff --git a/content/weblog/2018-08-03_how-to-break-and-repair-pip/index.md b/content/weblog/2018-08-03_how-to-break-and-repair-pip/index.md
new file mode 100644
index 0000000..c2aa000
--- /dev/null
+++ b/content/weblog/2018-08-03_how-to-break-and-repair-pip/index.md
@@ -0,0 +1,59 @@
++++
+title = "How to break pip, and how to repair it..."
+date = 2018-08-03T22:00:00Z
++++
+
+Sometimes a program may suggest to you something, and you may following said
+program's suggestion, because, why not, you trust the devs because they've done
+an amazing job developing the program, and heck, they should know what they are
+doing with their tools.
+
+<!-- more -->
+
+With pip, this does not seem to be the case however. I've come across this
+issue on my laptop and desktop computers running Manjaro, and while fixed it on
+my laptop, I forgot how to fix it by the time I encountered on my desktop. The
+problem: pip refuses to collect a package while trying to install any package
+system wide (e.g. pywal), exiting with an exception like 'ModuleNotFoundError'
+or something similar.
+
+First, I'll write down what NOT to do to avoid getting this error.
+
+You may get a message like this when after installing a package with pip
+
+```sh
+You are using pip version x.x.x, however version x.x is available.
+You should consider upgrading via the 'pip install --upgrade pip' command.
+```
+
+If you get the following while NOT using a virtual environment, don't pay
+attention to it. Don't even look at it. Just ignore it. I didn't, and now I am
+writing a post about how to fix the mess that it causes because of following
+that seemingly innocent and well-intended advice. At least not if you are using
+an Arch-based distribution, don't really know about how this is managed in
+other distributions, since I don't recall having this problem when using
+Debian.
+
+Now, if you are using a virtual environment, you obviously can and should
+upgrade pip this way. However, system-wide, your package manager (pacman)
+should take care of upgrading pip along with your other packages when you
+upgrade your system (pacman -Syu).
+
+## The fix
+
+If you unfortunately, like me, already ran the upgrade through pip, you should
+first delete some files, by running this command:
+
+```sh
+$ sudo rm -rf /usr/lib/python3.6/site-packages/pip /usr/lib/python3.6/site-packages/pkg_resources
+```
+
+Then, you should reinstall pip and setup tools:
+
+```sh
+$ sudo pacman -S python-setuptools python-pip
+```
+
+And that's it! Your pip should now be as good as new.
+
+I found the solution in this forum thread: [https://bbs.archlinux.org/viewtopic.php?id=237451](https://bbs.archlinux.org/viewtopic.php?id=237451)
diff --git a/content/weblog/2018-08-03_how-to-break-and-repair-pip/index.ru.md b/content/weblog/2018-08-03_how-to-break-and-repair-pip/index.ru.md
new file mode 100644
index 0000000..0a62d75
--- /dev/null
+++ b/content/weblog/2018-08-03_how-to-break-and-repair-pip/index.ru.md
@@ -0,0 +1,61 @@
++++
+title = "How to break pip, and how to repair it..."
+date = 2018-08-03T22:00:00Z
++++
+
+Бывает такое что программу которую мы используем предлагает нам какое-то
+действие. И подумаешь, почему бы не следовать совету, ведь разработчики
+красавчики сделали прекрасную работу разрабатывая эту программу, они наверно
+знают о чем они говорят.
+
+<!-- more -->
+
+С pip'ом походу это так не работает. Я столкнулся с этой проблемой сначала на
+моем ноутбуке, а затем на своем настольном компьютере (У меня на обоих стоит
+Manjaro). На своем ноутбуке я решил проблему, и когда снова с ней столкнулся на
+настольном, я забыл как ее решить. Проблема заключается в том что pip
+отказывается установить пакет, выдавая исключение, например
+'ModuleNotFoundError'.
+
+Сначала, я вам расскажу что НЕ надо делать чтобы избежать данную проблему.
+
+У вас терминале может появится следующее сообщение после того как вы
+пользовались pip'ом
+
+```sh
+You are using pip version x.x.x, however version x.x is available.
+You should consider upgrading via the 'pip install --upgrade pip' command.
+```
+
+Если вы видете такое, или похоже сообшение (например, тоже самое но на
+русском), не обращаете на него внимание. Даже не смотрите на него. Просто
+сделаете вид что его нет. Я послушался советом этого сообщения, и вот, из-за
+этого а теперь я пишу запись на своем блоге о том как решить ошибку которая
+возникает из-за того что следовал этим советом. По крайней мере не обращайте
+внимание на это сообщение если у вас дистрибутив основан на Arch. На счет
+других дистрибутивов я не знаю как следует поступать.
+
+Однако, если вы работаете в виртуальной среде, можно и надо использовать pip
+для обновления самого pip'a. Но если используем pip чтобы установить пакеты на
+уровне системы, то следует пользоваться своим менеджером пакетов (pacman) для
+обновления pip'a, поскольку сам менеджер пакетов обновит ваш pip вместе с
+остальными пакетами системы когда этого потребуется.
+
+## Решение
+
+Если вы, увы, как и я, послушались pip'a и обновили его через самого себя (то
+есть обновили pip используя сам pip) то сначала потребуется удалить некоторые
+файлы:
+
+```sh
+$ sudo rm -rf /usr/lib/python3.6/site-packages/pip /usr/lib/python3.6/site-packages/pkg_resources
+```
+
+Then, you should reinstall pip and setup tools:
+
+```sh
+$ sudo pacman -S python-setuptools python-pip
+```
+Вот и все! Ваш pip готов к работе.
+
+Решение проблемы я нашел на форумах arch: [https://bbs.archlinux.org/viewtopic.php?id=237451](https://bbs.archlinux.org/viewtopic.php?id=237451)