blog

Fix error in file detection

Author
Maarten Vangeneugden
Date
June 27, 2021, 1:35 p.m.
Hash
1e40d90bf6cad09f5bea5944ae63a1c2336e49fc
Parent
b51541052ba69b896a0e8c5286e8088bddd02c5d
Modified files
models.py
templates/blog/feed.rss
templates/blog/index.djhtml

models.py

3 additions and 3 deletions.

View changes Hide changes
1
1
from django.utils import translation
2
2
from django.template.defaultfilters import slugify
3
3
from django.db import models
4
4
import datetime
5
5
import os
6
6
7
7
def post_title_directory(instance, filename):
8
8
    """ Files will be uploaded to MEDIA_ROOT/blog/<year of publishing>/<blog
9
9
    title>
10
10
    The blog title is determined by the text before the first period (".") in
11
11
    the filename. So if the file has the name "Trains are bæ.en.md", the file
12
12
    will be stored in "blog/<this year>/Trains are bæ". Name your files
13
13
    properly!
14
14
    It should also be noted that all files are stored in the same folder if they
15
15
    belong to the same blogpost, regardless of language. The titles that are
16
16
    displayed to the user however, should be the titles of the files themselves,
17
17
    which should be in the native language. So if a blog post is titled
18
18
    "Universities of Belgium", its Dutch counterpart should be titled
19
19
    "Universiteiten van België", so the correct title can be derived from the
20
20
    filename.
21
21
22
22
    Recommended way to name the uploaded file: "<name of blog post in language
23
23
    it's written>.org". This removes the maximum amount of redundancy (e.g. the
24
24
    language of the file can be derived from the title, no ".fr.org" or something
25
25
    like that necessary), and can directly be used for the end user (the title
26
26
    is what should be displayed).
27
27
    """
28
28
    english_file_name = os.path.basename(instance.english_file.name) # TODO: Test if this returns the file name!
29
29
    english_title = english_file_name.rpartition(".")[0]
30
30
    year = datetime.date.today().year
31
31
32
32
    return "blog/{0}/{1}/{2}".format(year, english_title, filename)
33
33
34
34
class Post(models.Model):
35
35
    """ Represents a blog post. The title of the blog post is determnined by the name
36
36
    of the files.
37
37
    A blog post can be in 5 different languages: German, Spanish, English, French,
38
38
    and Dutch. For all these languages, a seperate field exists. Thus, a
39
39
    translated blog post has a seperate file for each translation, and is
40
40
    seperated from Django's internationalization/localization system.
41
41
    Only the English field is mandatory. The others may contain a value if a
42
42
    translated version exists, which will be displayed accordingly.
43
43
    """
44
44
    published = models.DateTimeField(auto_now_add=True)
45
45
    english_file = models.FileField(upload_to=post_title_directory, blank=False)
46
46
    dutch_file = models.FileField(upload_to=post_title_directory, blank=False)
47
47
    french_file = models.FileField(upload_to=post_title_directory, blank=True)
48
48
    german_file = models.FileField(upload_to=post_title_directory, blank=True)
49
49
    spanish_file = models.FileField(upload_to=post_title_directory, blank=True)
50
50
51
51
    title_en = models.CharField(max_length=64, unique=True, blank=False)
52
52
    title_nl = models.CharField(max_length=64, unique=True, blank=False)
53
53
    title_fr = models.CharField(max_length=64, blank=True)
54
54
    title_de = models.CharField(max_length=64, blank=True)
55
55
    title_es = models.CharField(max_length=64, blank=True)
56
56
    # PostgreSQL sees two null values as not unique, therefore I can't ask for unique names.
57
57
58
58
    slug_en  = models.SlugField(unique=True, blank=False, allow_unicode=True)
59
59
    slug_nl  = models.SlugField(unique=True, blank=False, allow_unicode=True)
60
60
    slug_fr  = models.SlugField(blank=True, allow_unicode=True)
61
61
    slug_de  = models.SlugField(blank=True, allow_unicode=True)
62
62
    slug_es  = models.SlugField(blank=True, allow_unicode=True)
63
63
64
64
    def __str__(self):
65
65
        return self.slug("en")
66
66
67
67
    def text_file(self, language_code=translation.get_language()):
68
68
        if language_code == "en":
69
69
            return self.english_file
70
70
        elif language_code == "nl":
71
71
            return self.dutch_file
72
72
        elif language_code == "de":
73
73
            if self.german_file is None:
74
-
                return self.english_file
+
74
                return self.english_file
75
75
            else:
76
76
                return self.german_file
77
77
        elif language_code == "fr":
78
78
            if self.french_file is None:
79
-
                return self.english_file
+
79
                return self.english_file
80
80
            else:
81
81
                return self.french_file
82
82
        elif language_code == "es":
83
83
            if self.spanish_file is None:
84
-
                return self.english_file
+
84
                return self.english_file
85
85
            else:
86
86
                return self.spanish_file
87
87
        return self.english_file
88
88
89
89
    def title(self, language_code=translation.get_language()):
90
90
        if language_code == "en":
91
91
            return self.title_en
92
92
        elif language_code == "nl":
93
93
            return self.title_nl
94
94
        elif language_code == "de":
95
95
            if self.title_de == "":
96
96
                return self.title_en
97
97
            else:
98
98
                return self.title_de
99
99
        elif language_code == "fr":
100
100
            if self.title_fr == "":
101
101
                return self.title_en
102
102
            else:
103
103
                return self.title_fr
104
104
        elif language_code == "es":
105
105
            if self.title_es == "":
106
106
                return self.title_en
107
107
            else:
108
108
                return self.title_es
109
109
        return self.title_en
110
110
111
111
    def slug(self, language_code=translation.get_language()):
112
112
        """ Returns a slug of the requested language, or None if no version exists in that language. """
113
113
        if language_code == "en":
114
114
            return self.slug_en
115
115
        elif language_code == "nl":
116
116
            return self.slug_nl
117
117
        elif language_code == "de":
118
118
            if self.slug_de == "":
119
119
                return self.slug_en
120
120
            else:
121
121
                return self.slug_de
122
122
        elif language_code == "fr":
123
123
            if self.slug_fr == "":
124
124
                return self.slug_en
125
125
            else:
126
126
                return self.slug_fr
127
127
        elif language_code == "es":
128
128
            if self.slug_es == "":
129
129
                return self.slug_en
130
130
            else:
131
131
                return self.slug_es
132
132
        return self.slug_en
133
133
134
134
class Comment(models.Model):
135
135
    """ Represents a comment on a blog post.
136
136
    Comments are not filtered by language; a
137
137
    comment made by someone reading the article in Dutch, that's written in
138
138
    Dutch, will show up (unedited) for somebody whom's reading the Spanish
139
139
    version.
140
140
    """
141
141
    date = models.DateTimeField(auto_now_add=True)
142
142
    name = models.CharField(max_length=64)
143
143
    text = models.TextField(max_length=1000)  # Should be more than enough.
144
144
    post = models.ForeignKey(
145
145
        Post,
146
146
        on_delete=models.CASCADE,
147
147
        null=False,
148
148
        )
149
149
    class meta:
150
150
        ordering = ['date']  # When printed, prints the oldest comment first.
151
151
152
152
class FeedItem(models.Model):
153
153
    """ An item that shows up in the RSS feed."""
154
154
    title = models.CharField(max_length=64)
155
155
    added = models.DateTimeField(auto_now_add=True)
156
156
    description = models.CharField(max_length=400)
157
157
    link = models.URLField()
158
158

templates/blog/feed.rss

4 additions and 1 deletion.

View changes Hide changes
1
1
<rss version="2.0">
2
-
    <channel>
+
2
+
3
    <channel>
3
4
    <title>RSS-kanaal voor maartenv.be</title>
+
5
    <title>RSS-kanaal voor maartenv.be</title>
4
6
    <link>https://maartenv.be</link>
5
7
    <description>The official RSS feed for the personal website of Maarten V.</description>
6
8
    {% for item in items %}
7
9
    <item>
8
10
        <title>{{ item.title }}</title>
9
11
        <link>{{ item.link }}</link>
10
12
        <description>{{ item.description }}</description>
+
13
        <description>{{ item.description }}</description>
11
14
        {% language 'en' %}
12
15
        <pubDate>{{ item.added|date:'r' }}</pubDate>
13
16
        {% endlanguage %}
14
17
    </item>
15
18
    {% endfor %}
16
19
    </channel>
17
20
</rss>
18
21

templates/blog/index.djhtml

2 additions and 3 deletions.

View changes Hide changes
1
1
{% load i18n %}
2
2
{% load static %}
3
3
4
4
{% block stylesheets %}
5
5
    {{ block.super }}
6
6
    <style>
7
7
    img {
8
8
    width: 80%;
9
9
     display: block;
10
10
  margin-left: auto;
11
11
  margin-right: auto;
12
12
    }
13
13
    video {
14
14
    width: 80%;
15
15
    } 
16
16
    </style>
17
17
{% endblock %}
18
18
19
19
{% block title %}{% trans "Maarten's blog" %}{% endblock title %}
20
20
21
21
{% block description %}{% blocktrans %}The always coherently put together, yet
22
22
fuzzy blog of whatever sprouts in my mind.{% endblocktrans %}
23
23
{% endblock description %}
24
24
25
25
{% block header %}
26
26
<header>                                                                                                                                                                                         
27
27
    <h1>{% trans "Notepad of a student" %}</h1>  
28
28
    <label for="nav-drawer-toggle"></label>
29
29
</header>
30
30
{% endblock header %}
31
31
32
32
{% block nav %}
33
33
<input id="nav-drawer-toggle" type="checkbox" />
34
34
<nav>
35
35
    <label for="nav-drawer-toggle"><!--🡨-->🡠</label>
36
36
    <h2>{% trans "Navigation" %}</h2>
37
37
    {% for title, date, blog_text, link in posts %}
38
38
    <a class="nav-link" href="{{ link }}">{{ title }}</a>
39
39
    {% endfor %}
40
40
    <hr class="half" />
41
41
    <a class="nav-link" href="{% url 'about-index' %}">{% trans "Front page" %}</a>
42
42
  </nav>
43
43
{% endblock nav %}
44
44
45
45
{% block main %}
46
46
47
47
<section class="emphasis">
48
48
    <h1>{% trans "Blog" %}</h1>
49
49
    <p>
50
50
        {% blocktrans %}Welcome to my blog. Here, I write
51
51
        about things that interest me. Politics, coding,
52
52
        studying, life, or anything else I fancy rambling
53
53
        about. If you're in luck, I may've written it in a
54
54
        language that you understand better than English.
55
55
        {% endblocktrans %}
56
56
    </p>
57
57
</section>
58
58
59
59
<!--<div class="fab">
60
-
    <a href="{% url 'blog-feed' %}" id="feed-fab"> 
+
60
    <a href="{% url 'blog-feed' %}" id="feed-fab"> 
61
61
    <i class="large material-icons">rss_feed</i>
62
-
    <b>RSS</b>
63
62
    </a>
64
63
</div>-->
65
-
+
64
66
65
<section>
67
66
    <h1>Monthly</h1>
68
67
    <a class="btn fill" href="{% url "monthly-archive" %}"> {% trans "Open archive" %}</a>
69
68
    {% include "blog/monthly.html" %}
70
69
</section>
71
70
72
71
<div class="cards">
73
72
    {% for title, date, blog_text, link in posts %}
74
73
        <div class="card">
75
74
            <h3>{{ title }}</h3>
76
75
            <h4>{{ date|date:"DATE_FORMAT" }}</h4>
77
76
        <p>{{ blog_text|safe|truncatewords_html:100 }}</p>
78
77
        <a class="btn outline" href="{{link}}">📚 {% trans "Read on" %}</a>
79
78
        </div>
80
79
    {% endfor %}
81
80
</div>
82
81
83
82
{% endblock main %}
84
83