blog

Update and improve blog system

I've added a new URL pattern that can catch language specific URLs, which will be remapped to standard URL's in the background. I'm also in the process of rewriting the templates a bit, so that they will be displayed correctly. Additionally, Pandoc will now expect Org files, instead of Markdown formatted files.

Author
Maarten 'Vngngdn' Vangeneugden
Date
Jan. 3, 2018, 12:38 a.m.
Hash
1f838f93bc8a322bb126311c62c927a8a515ee29
Parent
e2546549968315b5db52e653efe0f7e29c5f0258
Modified files
templates/blog/index.html
templates/blog/post.html
urls.py
views.py

templates/blog/index.html

4 additions and 6 deletions.

View changes Hide changes
1
1
{% load i18n %}
2
2
3
3
{% block title %}{% trans "Maarten's blog" %}{% endblock title %}
4
4
5
5
{% block description %}{% blocktrans %}The always coherently put together, yet
6
6
fuzzy blog of whatever sprouts in my mind.{% endblocktrans %}
7
7
{% endblock description %}
8
8
9
9
{% block main %}
10
10
{% with color="brown" accent_color="yellow" %}
11
11
<div class="section {{ color }} z-depth-3">
12
12
    <div class="container">
13
13
        <div class="white-text">
14
14
            <h3>{% trans "Blog" %}</h3>
15
15
            <p>
16
16
                {% blocktrans %}Welcome to my blog. Here, I write
17
17
                about things that interest me. Politics, coding,
18
18
                studying, life, or anything else I fancy rambling
19
19
                about. If you're in luck, I may've written it in a
20
20
                language that you understand better than English.
21
21
                {% endblocktrans %}
22
22
            </p>
23
23
        </div>
24
24
    </div>
25
25
</div>
26
26
27
27
<div class="container">
28
28
    {% for title, date, description, link in post_links %}
29
-
        <h2 class="{{ color}}-text">{{ title }}</h2>
+
29
        <h2 class="{{ color}}-text">{{ title }}</h2>
30
30
        {# FIXME: Date is in all languages of the same format. Fix for each language #}
31
-
        <span class="grey-text">{{ date|date:"l j F Y" }}</span>
32
-
        <p class="hide-on-small-only">{{ description|safe|truncatewords_html:100 }}</p>
+
31
        <p class="hide-on-small-only">{{ description|safe|truncatewords_html:100 }}</p>
33
32
        {#<p class="hide-on-small-only">{% lorem %}</p>#}
34
-
        <a class="btn {{accent_color}} accent-4" href="{{link}}">
35
-
            {% trans "Read on"%}
36
-
        </a>
+
33
            📚 {% trans "Read on"%}
+
34
        </a>
37
35
        <hr />
38
36
    {% endfor %}
39
37
</div>
40
38
{% endwith %}
41
39
{% endblock main %}
42
40

templates/blog/post.html

6 additions and 5 deletions.

View changes Hide changes
1
1
{% load i18n %}
2
2
3
3
{% block title %}{{ post_title }} | Blog{% endblock title %}
4
-
+
4
5
5
{% block description %}{{ post_description }}{% endblock description %}
6
-
+
6
7
7
{% block main %}
8
8
{% with color="brown" accent_color="yellow" %}
9
9
<div class="section {{ color }} lighten-1 z-depth-3">
10
10
    <div class="container">
11
11
        <div class="white-text flow-text" style="font-family:serif;">
12
12
            {{ article|safe }}
13
13
        </div>
14
14
    </div>
15
15
</div>
16
16
{% comment %}
17
17
{% get_language_info for "en" as lang %}
18
18
    <a href="{% url 'blog_post' 'en' post_url %}" class="btn tooltipped"
19
19
    data-position="bottom" data-delay="50" data-tooltip="{% trans 'Share the English version' %}">{{lang.name_translated}}</a>
20
20
    <a href="{% url 'blog_post' l1nguage post %}" class="btn tooltipped" data-position="bottom" data-delay="50" data-tooltip="{% trans ">Hover me!</a>
21
-
    <a href="{% url 'blog_post' l1nguage post %}"class="btn tooltipped" data-position="bottom" data-delay="50" data-tooltip="{% trans ">Hover me!</a>
22
-
    <a href="{% url 'blog_post' l1nguage post %}"class="btn tooltipped" data-position="bottom" data-delay="50" data-tooltip="{% trans ">Hover me!</a>
23
-
    <a href="{% url 'blog_post' post_url %}" class="btn tooltipped" data-position="bottom" data-delay="50" data-tooltip="{% trans 'Multilingual link. Links to the version in the viewer's preferred language.' %}">🏳️‍🌈 {% trans "All possible languages" %}</a>
+
21
    <a href="{% url 'blog_post' 'de' post %}" class="btn tooltipped" data-position="bottom" data-delay="50" data-tooltip="{% trans ">Hover me!</a>
+
22
    <a href="{% url 'blog_post' 'fr' post %}"class="btn tooltipped" data-position="bottom" data-delay="50" data-tooltip="{% trans ">Hover me!</a>
+
23
    <a href="{% url 'blog_post' 'es' post %}"class="btn tooltipped" data-position="bottom" data-delay="50" data-tooltip="{% trans ">Hover me!</a>
+
24
    <a href="{% url 'blog_post' post_url %}" class="btn tooltipped" data-position="bottom" data-delay="50" data-tooltip="{% trans 'Multilingual link. Links to the version in the viewer's preferred language.' %}">🏳️‍🌈 {% trans "All possible languages" %}</a>
24
25
25
26
<div class="container">
26
27
    {% for title, date, description, link in post_links %}
27
28
        <h2 class="{{ color}}-text">{{ title }}</h2>
28
29
        {# FIXME: Date is in all languages of the same format. Fix for each language #}
29
30
        <span class="grey-text">{{ date|date:"l j F Y" }}</span>
30
31
        {#<p class="hide-on-small-only">{{ description }}</p>#}
31
32
        <p class="hide-on-small-only">{% lorem %}</p>
32
33
        <a class="btn {{accent_color}} accent-3" href="{{link}}">
33
34
            {% trans "Read on"%}
34
35
        </a>
35
36
        <hr />
36
37
    {% endfor %}
37
38
</div>
38
39
{% endcomment %}
39
40
{% endwith %}
40
41
{% endblock main %}
41
42

urls.py

3 additions and 2 deletions.

View changes Hide changes
1
1
2
2
from . import views # Imports the views from the same directory (which is views.py).
3
3
4
4
urlpatterns = [
5
5
        url(r'^$', views.index, name='blog-index'),
6
-
        url(r'^(?P<title>(.)+)$', views.post, name='blog-post'),
7
-
        ]
+
6
    url(r'^(?P<language>(.)+)/(?P<title>(.)+)$', views.post_lang, name='blog-post-language'),
+
7
    url(r'^(?P<title>(.)+)$', views.post, name='blog-post'),
+
8
        ]
8
9

views.py

17 additions and 14 deletions.

View changes Hide changes
1
1
import subprocess
2
2
3
3
from django.utils.translation import ugettext as _
4
4
from django.shortcuts import get_object_or_404, render # This allows to render the template with the view here. It's pretty cool and important.
5
5
from django.http import HttpResponseRedirect, HttpResponse
6
6
from django.core.urlresolvers import reverse # Why?
7
7
from django.template import loader # This allows to actually load the template.
8
8
from django.contrib.auth.decorators import login_required
9
9
from django.contrib.auth import authenticate, login
10
10
from .models import Post
11
11
from django.core.exceptions import ObjectDoesNotExist
12
12
from django.utils import translation
13
13
14
14
# FIXME: Remove this template trash. THIS IS A VIEW, NOT A FUCKING TEMPLATE FFS
+
15
SPANISH = "es"
+
16
FRENCH = "fr"
+
17
DUTCH = "nl"
+
18
ENGLISH = "en"
+
19
+
20
# FIXME: Remove this template trash. THIS IS A VIEW, NOT A FUCKING TEMPLATE FFS
15
21
context = {
16
22
    'materialDesign_color': "green",
17
23
    'materialDesign_accentColor': "purple",
18
24
    'navbar_title': "Blog",
19
25
    'navbar_fixed': True,
20
26
    'navbar_backArrow': True,
21
27
    #'footer_title': "Maarten's blog",
22
28
    #'footer_description': "My personal scribbly notepad.",
23
29
    #'footer_links': footer_links,
24
30
    }
25
31
26
32
def markdown_to_html(file_path):
27
33
    """ Converts the given Markdown formatted file to HTML.
28
34
    This function directly returns the resulting HTML code. This function uses
29
35
    the amazing Haskell library Pandoc to convert the file (and takes care
30
36
    of header id's and all that stuff).
31
37
    """
32
38
    return subprocess.check_output(["pandoc", "--from=markdown", "--to=html", "/srv/django/website/media/"+file_path])
33
-
+
39
    return subprocess.check_output(["pandoc", "--from=org", "--to=html", "/srv/django/website/media/"+file_path])
+
40
34
41
def get_available_post_languages(post):
35
42
    """ Returns the language codes for which a blog post exists. This function
36
43
    always returns English (because that field mustn't be empty).
37
44
    So say a blog post has an English, Dutch and French version (which means
38
45
    english_file, french_file and dutch_file aren't empty), the function will return {"en",
39
46
    "fr", "nl"}. """
40
47
    available_languages = {"en"}
41
-
    if post.german_file is not None:
+
48
    if post.german_file is not None:
42
49
        available_languages.add("de")
43
-
    if post.spanish_file is not None:
+
50
    if post.spanish_file is not None:
44
51
        available_languages.add("es")
45
-
    if post.french_file is not None:
+
52
    if post.french_file is not None:
46
53
        available_languages.add("fr")
47
-
    if post.dutch_file is not None:
+
54
    if post.dutch_file is not None:
48
55
        available_languages.add("nl")
49
-
    return available_languages
+
56
    return available_languages
50
57
51
58
def get_preferred_post_language(post, language):
52
59
    """ Returns the post language file that best suits the given language. This
53
60
    is handy if you know what language the user prefers, but aren't sure whether
54
61
    you can provide that language. This function will try to provide the file
55
62
    for that language, or return English if that's not possible. """
56
63
    if language == "de" and post.german_file is not None:
57
-
        return post.german_file
+
64
        return post.german_file
58
65
    if language == "es" and post.spanish_file is not None:
59
-
        return post.spanish_file
+
66
        return post.spanish_file
60
67
    if language == "fr" and post.french_file is not None:
61
-
        return post.french_file
+
68
        return post.french_file
62
69
    if language == "nl" and post.dutch_file is not None:
63
-
        return post.dutch_file
+
70
        return post.dutch_file
64
71
    return post.english_file  # Returned if all other choices wouldn't be satisfactory, or the requested language is English.
65
72
66
73
def index(request):
67
74
    template = "blog/index.html"
68
75
    posts = Post.objects.all()
69
76
    language = translation.get_language()
70
77
71
78
    post_links = []
72
79
    for post in posts:
73
80
        blog_file = get_preferred_post_language(post, language)
74
81
        # TODO: Find a cleaner way to determine the title. First and foremost:
75
82
        # If the language differs from English, the other language file needs to
76
83
        # be loaded. Plus: look for a built in function to remove the full path
77
84
        # and only return the file name.
78
85
        title = (blog_file.name.rpartition("/")[2]).rpartition(".")[0]
79
86
        date = post.published
80
87
        #description = "Lorem ipsum"
81
-
        blog_text = markdown_to_html(blog_file.name)
82
88
        #blog_text = blog_text.replace("\\n\\n", "</p><p>")
83
-
        #blog_text = blog_text.replace("\\n", " ")
84
-
        description = blog_text
85
-
        # TODO: The link can possibly be reversed in the DTL using the title, which is actually
86
89
        # a cleaner way to do it. Investigate.
87
90
        link = reverse("blog-post", args=[str(post)])
88
91
        post_links.append([title, date, description, link])
89
92
90
93
    context = {
91
94
            'post_links': post_links,
92
95
            'materialDesign_color': "brown",
93
96
            'materialDesign_accentColor': "yellow",
94
97
            'navbar_title': _("Notepad from a student"),
95
98
            'navbar_backArrow': True,
96
99
            }
97
100
    return render(request, template, context)
98
101
99
102
def post(request, title):
100
103
    template = "blog/post.html"
101
104
    posts = Post.objects.all()
102
105
    for post in posts:
103
106
        if str(post)==title:
104
107
            language = translation.get_language()
105
108
            blog_file = get_preferred_post_language(post, language)
106
109
            blog_text = markdown_to_html(blog_file.name)
107
110
            context = {
108
111
                'materialDesign_color': "brown",
109
112
                'materialDesign_accentColor': "yellow",
110
113
                'article': blog_text,
111
114
                'title': blog_file.name,
112
115
                'navbar_title': (blog_file.name.rpartition("/")[2]).rpartition(".")[0],
113
116
                'navbar_backArrow': True,
114
117
                }
115
118
            return render(request, template, context)
116
119