]> git.ipfire.org Git - ipfire.org.git/commitdiff
blog: Add history pages
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 18 Jul 2018 09:48:02 +0000 (10:48 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 18 Jul 2018 09:48:02 +0000 (10:48 +0100)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/backend/blog.py
src/templates/blog/author.html
src/templates/blog/base.html
src/templates/blog/modules/history-navigation.html [new file with mode: 0644]
src/templates/blog/modules/list.html [new file with mode: 0644]
src/templates/blog/year.html [new file with mode: 0644]
src/web/__init__.py
src/web/blog.py
src/web/ui_modules.py

index 8b9d93bb4d1b018dbb48870a36d9f45cc1b6df14..522d80ee0c7cffcbbbd5cf999e544a17f47caee5 100644 (file)
@@ -112,11 +112,14 @@ templates_blog_DATA = \
        src/templates/blog/index.html \
        src/templates/blog/post.html \
        src/templates/blog/search-results.html \
-       src/templates/blog/tag.html
+       src/templates/blog/tag.html \
+       src/templates/blog/year.html
 
 templates_blogdir = $(templatesdir)/blog
 
 templates_blog_modules_DATA = \
+       src/templates/blog/modules/history-navigation.html \
+       src/templates/blog/modules/list.html \
        src/templates/blog/modules/post.html \
        src/templates/blog/modules/posts.html
 
index 3b02acf18e6fb641b22d6bcbd6c9d657d31642f5..a287491676da98fafac543acea31ccde1d919f1f 100644 (file)
@@ -1,5 +1,7 @@
 #!/usr/bin/python
 
+import textile
+
 from . import misc
 
 class Blog(misc.Object):
@@ -43,6 +45,13 @@ class Blog(misc.Object):
                                AND published_at <= NOW() \
                        ORDER BY published_at DESC LIMIT %s", uid, limit)
 
+       def get_by_year(self, year):
+               return self._get_posts("SELECT * FROM blog \
+                       WHERE EXTRACT(year FROM published_at) = %s \
+                               AND published_at IS NOT NULL \
+                               AND published_at <= NOW() \
+                       ORDER BY published_at DESC", year)
+
        def search(self, query, limit=None):
                return self._get_posts("SELECT blog.* FROM blog \
                        LEFT JOIN blog_search_index search_index ON blog.id = search_index.post_id \
@@ -57,6 +66,15 @@ class Blog(misc.Object):
                """
                self.db.execute("REFRESH MATERIALIZED VIEW blog_search_index")
 
+       @property
+       def years(self):
+               res = self.db.query("SELECT DISTINCT EXTRACT(year FROM published_at)::integer AS year \
+                       FROM blog WHERE published_at IS NOT NULL AND published_at <= NOW() \
+                       ORDER BY year DESC")
+
+               for row in res:
+                       yield row.year
+
 
 class Post(misc.Object):
        def init(self, id, data=None):
@@ -85,12 +103,16 @@ class Post(misc.Object):
        def published_at(self):
                return self.data.published_at
 
+       @property
+       def markdown(self):
+               return self.data.markdown
+
        @property
        def html(self):
                """
                        Returns this post as rendered HTML
                """
-               return self.data.html
+               return self.data.html or textile.textile(self.markdown.decode("utf-8"))
 
        @property
        def tags(self):
index dc50dcaaf3c40a589ad0c4e74526d3a849a504f6..46ed84cf552bc4e82061c1b760fcc27664deb4dc 100644 (file)
@@ -7,14 +7,7 @@
                <div class="card-body">
                        <h5>{{ _("%s's posts") % author.name }}</h5>
 
-                       {% for post in posts %}
-                               <strong class="mb-0">
-                                       <a href="/post/{{ post.slug }}">{{ post.title }}</a>
-                               </strong>
-                               <p class="text-muted small">
-                                       {{ locale.format_date(post.published_at, shorter=True, relative=False) }}
-                               </p>
-                       {% end %}
+                       {% module BlogList(posts) %}
                </div>
        </div>
 {% end block %}
index 2f33607172073c2e4c582b083b37d95dc11f59f8..c69241459208f78d2923217709f92d910f88704d 100644 (file)
@@ -39,6 +39,8 @@
                                        </li>
                                </ul>
                        </nav>
+
+                       {% module BlogHistoryNavigation() %}
                </div>
 
                <div class="col">
diff --git a/src/templates/blog/modules/history-navigation.html b/src/templates/blog/modules/history-navigation.html
new file mode 100644 (file)
index 0000000..1ca9e0f
--- /dev/null
@@ -0,0 +1,13 @@
+<p class="small text-uppercase text-muted ml-3">{{ _("History") }}</p>
+
+<nav class="mb-5">
+    <ul class="nav flex-column">
+        {% for year in years %}
+            <li class="nav-item">
+                <a class="nav-link {% if request.path == "/years/{{ year }}" %}active{% end %}" href="/years/{{ year }}">
+                    {{ year }}
+                </a>
+            </li>
+        {% end %}
+    </ul>
+</nav>
diff --git a/src/templates/blog/modules/list.html b/src/templates/blog/modules/list.html
new file mode 100644 (file)
index 0000000..37e122f
--- /dev/null
@@ -0,0 +1,8 @@
+{% for post in posts %}
+       <strong class="mb-0">
+               <a href="/post/{{ post.slug }}">{{ post.title }}</a>
+       </strong>
+       <p class="text-muted small">
+               {{ locale.format_date(post.published_at, shorter=True, relative=False) }}
+       </p>
+{% end %}
diff --git a/src/templates/blog/year.html b/src/templates/blog/year.html
new file mode 100644 (file)
index 0000000..5d36007
--- /dev/null
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+
+{% block title %}{{ _("Posts in %s") % year }}{% end block %}
+
+{% block main %}
+       <div class="card">
+               <div class="card-body">
+                       <h5>{{ _("Posts in %s") % year }}</h5>
+
+                       {% module BlogList(posts) %}
+               </div>
+       </div>
+{% end block %}
index 48590ab57f28dc2c3d6b46903fc978958ec1f7f0..1c619adfbea7bae991901409d1cf987c3ddce0b6 100644 (file)
@@ -39,6 +39,8 @@ class Application(tornado.web.Application):
                                "format_month_name" : self.format_month_name,
                        },
                        "ui_modules" : {
+                               "BlogHistoryNavigation": blog.HistoryNavigationModule,
+                               "BlogList"             : blog.ListModule,
                                "BlogPost"             : blog.PostModule,
                                "BlogPosts"            : blog.PostsModule,
 
@@ -121,6 +123,7 @@ class Application(tornado.web.Application):
                        (r"/post/(.*)", blog.PostHandler),
                        (r"/search", blog.SearchHandler),
                        (r"/tags/([0-9a-z\-]+)", blog.TagHandler),
+                       (r"/years/([0-9]+)", blog.YearHandler),
 
                        # RSS Feed
                        (r"/feed.xml", blog.FeedHandler),
index 52540721a419e0decb5e1b5181689d57dafcefad..bb2994b1df11eebbec1f538ee197bf8ad938c460 100644 (file)
@@ -80,6 +80,26 @@ class TagHandler(base.BaseHandler):
                self.render("blog/tag.html", posts=posts, tag=tag)
 
 
+class YearHandler(base.BaseHandler):
+       def get(self, year):
+               posts = self.backend.blog.get_by_year(year)
+               if not posts:
+                       raise tornado.web.HTTPError(404, "There are no posts in %s" % year)
+
+               self.render("blog/year.html", posts=posts, year=year)
+
+
+class HistoryNavigationModule(ui_modules.UIModule):
+       def render(self):
+               return self.render_string("blog/modules/history-navigation.html",
+                       years=self.backend.blog.years)
+
+
+class ListModule(ui_modules.UIModule):
+       def render(self, posts):
+               return self.render_string("blog/modules/list.html", posts=posts)
+
+
 class PostModule(ui_modules.UIModule):
        def render(self, post):
                return self.render_string("blog/modules/post.html", post=post)
index 1295e72c27e2edacb70b7243bd803b36ec900214..b05440b5d166237d0a38a697befa58f5d42b51c8 100644 (file)
@@ -16,6 +16,10 @@ import unicodedata
 from .. import database
 
 class UIModule(tornado.web.UIModule):
+       @property
+       def backend(self):
+               return self.handler.backend
+
        @property
        def accounts(self):
                return self.handler.accounts