for row in res:
yield row.year
+ @property
+ def authors(self):
+ res = self.db.query("""
+ SELECT
+ author_uid,
+ MAX(published_at) AS published_at
+ FROM
+ blog
+ WHERE
+ author_uid IS NOT NULL
+ AND
+ published_at IS NOT NULL
+ AND
+ published_at <= NOW()
+ GROUP BY
+ author_uid
+ ORDER BY
+ published_at DESC
+ """,
+ )
+
+ return [self.backend.accounts.get_by_uid(row.author_uid) for row in res]
+
async def announce(self):
posts = self._get_posts("SELECT * FROM blog \
WHERE (published_at IS NOT NULL AND published_at <= NOW()) \
<section>
<h3>{{ _("Posts") }}</h3>
- {% module BlogList(posts) %}
+ {% module BlogList(posts, show_author=True) %}
</section>
</div>
{% end block %}
<meta name="description" content="{{ _("The IPFire Blog has the latest news from the IPFire Project about Development, Current Affairs, and many more interesting things.") }}" />
{% end %}
-{% block main %}
- {% module BlogPosts(posts) %}
+{% block container %}
+ <div class="header">
+ <div class="container">
+ <h1>{{ _("IPFire Blog") }}</h1>
+ </div>
+ </div>
+
+ <div class="container">
+ <section>
+ {% module BlogList(posts, relative=True) %}
+ </section>
+
+ {% module BlogHistoryNavigation() %}
+ </div>
{% end block %}
-<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/%s" % year %}active{% end %}" href="/years/{{ year }}">
- {{ year }}
- </a>
- </li>
- {% end %}
- </ul>
-</nav>
+<h5>{{ _("Read More") }}</h5>
+
+<h6>{{ _("Authors") }}</h6>
+
+<div class="row row-cols-1 row-cols-md-2 row-cols-lg-4">
+ {% for account in authors %}
+ <div class="col mb-4">
+ <div class="row align-items-center">
+ <div class="col-2 col-md-3">
+ <img class="img-fluid rounded-circle"
+ src="{{ account.avatar_url(size=64) }}">
+ </div>
+
+ <div class="col">
+ <h6 class="mb-0">
+ <a href="/blog/authors/{{ account.uid }}">
+ {{ account.name or account.nickname }}
+ </a>
+ </h6>
+ </div>
+ </div>
+ </div>
+ {% end %}
+</div>
+
+<h6>{{ _("Years") }}</h6>
+
+<ul class="nav nav-pills nav-fill">
+ {% for year in years %}
+ <li class="nav-item">
+ <a class="nav-link" href="/blog/years/{{ year }}">{{ year }}</a>
+ </li>
+ {% end %}
+</ul>
{% for post in posts %}
- <strong class="mb-0">
- <a {% if "lightningwirelabs.com" in post.tags %}class="text-lwl"{% end %} href="/post/{{ post.slug }}">{{ post.title }}</a>
- </strong>
+ <h6 class="mb-0">
+ <a {% if "lightningwirelabs.com" in post.tags %}class="text-lwl"{% end %} href="/blog/{{ post.slug }}">{{ post.title }}</a>
+ </h6>
+
<p class="text-muted small">
- {{ locale.format_date(post.published_at, shorter=True, relative=False) }}
+ {{ locale.format_date(post.published_at, shorter=True, relative=relative) }}
{% if "lightningwirelabs.com" in post.tags %}
<span class="text-lwl">{{ _("by Lightning Wire Labs") }}</span>
+ {% elif show_author and post.author %}
+ <a href="/blog/authors/{{ post.author.uid }}">{{ _("by %s") % post.author }}</a>
{% end %}
</p>
{% end %}
(r"/blog/feed.xml", blog.FeedHandler),
(r"/blog/search", blog.SearchHandler),
(r"/blog/tags/([0-9a-z\-\.]+)", blog.TagHandler),
+ (r"/blog/years/([0-9]{4})", blog.YearHandler),
(r"/blog/([0-9a-z\-\._]+)", blog.PostHandler),
(r"/blog/([0-9a-z\-\._]+)/delete", blog.DeleteHandler),
(r"/blog/([0-9a-z\-\._]+)/edit", blog.EditHandler),
class IndexHandler(auth.CacheMixin, base.BaseHandler):
def get(self):
- posts = self.backend.blog.get_newest(limit=3)
+ posts = self.backend.blog.get_newest(limit=10)
# Allow this to be cached for 5 minutes
if not self.current_user:
class HistoryNavigationModule(ui_modules.UIModule):
def render(self):
return self.render_string("blog/modules/history-navigation.html",
- years=self.backend.blog.years)
+ authors=self.backend.blog.authors, years=self.backend.blog.years)
class ListModule(ui_modules.UIModule):
- def render(self, posts):
- return self.render_string("blog/modules/list.html", posts=posts)
+ def render(self, posts, relative=False, show_author=True):
+ return self.render_string("blog/modules/list.html",
+ posts=posts, relative=relative, show_author=show_author)
class PostModule(ui_modules.UIModule):