blog

Fix bug in models.py and work on translations in views.py

Author
Maarten 'Vngngdn' Vangeneugden
Date
July 10, 2017, 2:36 p.m.
Hash
7dc40e1090171aa1afca0c8a35e0df77f3267f10
Parent
1957abb2ef5154f3fa0096f5079c6ea8a4d246e7
Modified files
models.py
views.py

models.py

1 addition and 1 deletion.

View changes Hide changes
1
1
from django.db import models
2
2
3
3
def post_title_directory(instance, filename):
4
4
    """ Files will be uploaded to MEDIA_ROOT/blog/<year of publishing>/<blog
5
5
    title>
6
6
    The blog title is determined by the text before the first period (".") in
7
7
    the filename. So if the file has the name "Trains are bæ.en.md", the file
8
8
    will be stored in "blog/<this year>/Trains are bæ". Name your files
9
9
    properly!
10
10
    It should also be noted that all files are stored in the same folder if they
11
11
    belong to the same blogpost, regardless of language. The titles that are
12
12
    displayed to the user however, should be the titles of the files themselves,
13
13
    which should be in the native language. So if a blog post is titled
14
14
    "Universities of Belgium", its Dutch counterpart should be titled
15
15
    "Universiteiten van België", so the correct title can be derived from the
16
16
    filename.
17
17
18
18
    Recommended way to name the uploaded file: "<name of blog post in language
19
19
    it's written>.md". This removes the maximum amount of redundancy (e.g. the
20
20
    language of the file can be derived from the title, no ".fr.md" or something
21
21
    like that necessary), and can directly be used for the end user (the title
22
22
    is what should be displayed).
23
23
    """
24
24
    english_file_name = instance.file_en.name # TODO: Test if this returns the file name!
25
25
    english_title = english_file_name.partition(".")[0] 
26
26
27
27
    return "blog/%Y/{0}".format(english_title)
28
28
29
29
class Post(models.Model):
30
30
    """ Represents a blog post. The title of the blog post is determnined by the name
31
31
    of the files.
32
32
    A blog post can be in 5 different languages: German, Spanish, English, French,
33
33
    and Dutch. For all these languages, a seperate field exists. Thus, a
34
34
    translated blog post has a seperate file for each translation, and is
35
35
    seperated from Django's internationalization/localization system.
36
36
    Only the English field is mandatory. The others may contain a value if a
37
37
    translated version exists, which will be displayed accordingly.
38
38
    """
39
39
    published = models.DateTimeField(auto_now_add=True)
40
40
    file_de = models.FileField(upload_to=post_title_directory, unique=True, blank=True)
41
41
    file_es = models.FileField(upload_to=post_title_directory, unique=True, blank=True)
42
42
    file_en = models.FileField(upload_to=post_title_directory, unique=True, blank=False)
43
43
    file_fr = models.FileField(upload_to=post_title_directory, unique=True, blank=True)
44
44
    file_nl = models.FileField(upload_to=post_title_directory, unique=True, blank=True)
45
45
    # Please note that there's no need to create any indexes, because unique
46
46
    # fields constitute an index already.
47
47
48
48
    def __str__():
49
-
        return self.file_en.name.partition(".")[0]
+
49
        return self.file_en.name.partition(".")[0]
50
50

views.py

42 additions and 29 deletions.

View changes Hide changes
1
1
2
2
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.
3
3
from django.http import HttpResponseRedirect, HttpResponse
4
4
from django.core.urlresolvers import reverse # Why?
5
5
from django.template import loader # This allows to actually load the template.
6
6
from django.contrib.auth.decorators import login_required
7
7
from django.contrib.auth import authenticate, login
8
8
from .models import Post
9
9
from django.core.exceptions import ObjectDoesNotExist
10
10
from markdown import markdown
11
11
12
-
# Common data:
13
-
footer_links = [
14
-
    ["Home", "/"],
15
-
    ]
16
-
+
12
17
13
# FIXME: Remove this template trash. THIS IS A VIEW, NOT A FUCKING TEMPLATE FFS
18
14
context = {
19
15
    'materialDesign_color': "green",
20
16
    'materialDesign_accentColor': "purple",
21
17
    'navbar_title': "Blog",
22
18
    'navbar_fixed': True,
23
19
    'navbar_backArrow': True,
24
20
    #'footer_title': "Maarten's blog",
25
21
    #'footer_description': "My personal scribbly notepad.",
26
22
    'footer_links': footer_links,
27
23
    }
28
24
29
25
def get_preferred_language(
30
-
        request,
31
-
        possible_locales = {'de','en','es','fr','nl'},
32
-
        default = 'en'):
33
-
    """ Returns the best language that can be offered to the user.
34
-
    An HTTP request header contains an Accept-Language field, in which the user
35
-
    lists his requested languages, in descending order for preferability. This
36
-
    function will read this field, and return a locale that can be offered by
37
-
    the website (possible_locales). If nothing suitable can be offered, the
38
-
    default is returned (English).
39
-
    """
40
-
    accepted_languages = request.META.HTTP_ACCEPT_LANGUAGE
41
-
    accepted_languages = accepted_languages.split(",")
42
-
    for accepted_language in accepted_languages:
43
-
        for possible_locale in possible_locales:
44
-
            if accepted_language.lower().startswith(possible_locale):
45
-
                return possible_locale
46
-
    return default  # No possible locale found, so return the default.
47
-
+
26
    """ Returns the language codes for which a blog post exists. This function
+
27
    always returns English (because that field mustn't be empty).
+
28
    So say a blog post has an English, Dutch and French version (which means
+
29
    file_en, file_fr and file_nl aren't empty), the function will return {"en",
+
30
    "fr", "nl"}. """
+
31
    available_languages = {"en"}
+
32
    if post.file_de is not none:
+
33
        available_languages.add("de")
+
34
    if post.file_es is not None:
+
35
        available_languages.add("es")
+
36
    if post.file_fr is not None:
+
37
        available_languages.add("fr")
+
38
    if post.file_nl is not None:
+
39
        available_languages.add("nl")
+
40
    return available_languages
+
41
+
42
def get_preferred_post_language(post, language):
+
43
    """ Returns the post language file that best suits the given language. This
+
44
    is handy if you know what language the user prefers, but aren't sure whether
+
45
    you can provide that language. This function will try to provide the file
+
46
    for that language, or return English if that's not possible. """
+
47
    if language == "de" and post.file_de is not None:
+
48
        return post.file_de
+
49
    if language == "es" and post.file_es is not None:
+
50
        return post.file_es
+
51
    if language == "fr" and post.file_fr is not None:
+
52
        return post.file_fr
+
53
    if language == "nl" and post.file_nl is not None:
+
54
        return post.file_nl
+
55
    return post.file_en  # Returned if all other choices wouldn't be satisfactory, or the requested language is English.
+
56
    
+
57
48
58
def index(request):
49
59
    template = "blog/index.html"
50
60
    posts = Post.objects.all()
51
61
+
62
52
63
    post_links = []
53
64
    for post in posts:
54
65
        title = str(post)
55
-
        date = post.published
+
66
        title = blog_file.file_name
+
67
        date = post.published
56
68
        # TODO: The link can possibly be reversed in the DTL, which is actually
57
-
        # a cleaner way to do it. Investigate.
+
69
        # a cleaner way to do it. Investigate.
58
70
        link = reverse("blog-post", args=[title])
59
-
        post_links.append([title, date, description, link])
+
71
        post_links.append([title, date, description, link])
60
72
61
73
    context = {
62
74
            'post_links': post_links,
63
75
            }
64
76
    return render(request, template, context)
65
77
66
78
def post(request, title):
67
79
    template = "blog/post.html"
68
80
    posts = Post.objects.get(file_en=title)
69
81
    blog_text = markdown(text_file)
70
-
+
82
    blog_file = get_preferred_post_language(post, language)
+
83
    blog_text = markdown(blog_file)
+
84
71
85
    context = {
72
86
        'article': blog_text,
73
87
        }
+
88
        }
74
89
    return render(request, template, context)
75
90
76
-
    
77
-