]> zackmdavis.net Git - An_Algorithmic_Lucidity.git/commitdiff
more theme matching (feat. Claude Code)
authorZack M. Davis <code@zackmdavis.net>
Tue, 14 Jul 2026 17:10:35 +0000 (10:10 -0700)
committerZack M. Davis <code@zackmdavis.net>
Tue, 14 Jul 2026 17:10:59 +0000 (10:10 -0700)
16 files changed:
pelicanconf.py
theme/static/css/pygments.css [new file with mode: 0644]
theme/static/css/style.css
theme/templates/archives.html [new file with mode: 0644]
theme/templates/article.html
theme/templates/author.html [new file with mode: 0644]
theme/templates/authors.html [new file with mode: 0644]
theme/templates/base.html
theme/templates/categories.html [new file with mode: 0644]
theme/templates/category.html [new file with mode: 0644]
theme/templates/includes/post_card.html [new file with mode: 0644]
theme/templates/index.html
theme/templates/page.html [new file with mode: 0644]
theme/templates/period_archives.html [new file with mode: 0644]
theme/templates/tag.html [new file with mode: 0644]
theme/templates/tags.html [new file with mode: 0644]

index d5e5f7797dd5e86cd0a1efac9d49beba5f1fc55c..b7d90a485b341322bc857a9e2b9e9573d345bfad 100644 (file)
@@ -3,6 +3,7 @@
 
 AUTHOR = 'Zack M. Davis'
 SITENAME = 'An Algorithmic Lucidity'
+SITESUBTITLE = 'a blog'
 SITEURL = ''
 
 PATH = 'content'
@@ -20,7 +21,28 @@ AUTHOR_FEED_ATOM = None
 AUTHOR_FEED_RSS = None
 
 # Blogroll
-LINKS = ()
+LINKS = (
+    ('Beach City Bugle', 'http://www.beachcitybugle.com/'),
+    ('Claude Opus 4.5', 'https://claudeopus45.substack.com/'),
+    ('Compass Rose', 'http://benjaminrosshoffman.com/'),
+    ('Daniel Lemire', 'http://lemire.me/blog/'),
+    ('David R. MacIver', 'http://www.drmaciver.com/blog/'),
+    ('Equestria Daily', 'http://www.equestriadaily.com/'),
+    ('From Automorphy to Electricity', 'http://automorphy.blogspot.com/'),
+    ('Gallabytes', 'http://gallabytes.com/archive.html'),
+    ('Jeff Kaufman', 'http://www.jefftk.com/index'),
+    ('Julia Evans', 'http://jvns.ca/'),
+    ('Meteuphoric', 'http://meteuphoric.wordpress.com/'),
+    ('Otium', 'http://srconstantin.wordpress.com/'),
+    ('Reflective Disequilibrium', 'http://reflectivedisequilibrium.blogspot.com/'),
+    ('Ribbonfarm', 'http://www.ribbonfarm.com/'),
+    ('Seeking Whence', 'http://grognor.blogspot.com/'),
+    ('Slate Star Codex', 'http://slatestarcodex.com/'),
+    ('Stuart Spence Stuff', 'http://stuartspencestuff.blogspot.com/'),
+    ('The Rationalist Conspiracy', 'http://rationalconspiracy.com/'),
+    ("The Story's Story", 'http://jseliger.wordpress.com/'),
+    ('The Unit of Caring', 'http://theunitofcaring.tumblr.com/'),
+)
 
 # Social widget
 SOCIAL = ()
diff --git a/theme/static/css/pygments.css b/theme/static/css/pygments.css
new file mode 100644 (file)
index 0000000..27836fa
--- /dev/null
@@ -0,0 +1,75 @@
+pre { line-height: 125%; }
+td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.highlight .hll { background-color: #ffffcc }
+.highlight { background: #f8f8f8; }
+.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #F00 } /* Error */
+.highlight .k { color: #008000; font-weight: bold } /* Keyword */
+.highlight .o { color: #666 } /* Operator */
+.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
+.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #9C6500 } /* Comment.Preproc */
+.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
+.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
+.highlight .gr { color: #E40000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #008400 } /* Generic.Inserted */
+.highlight .go { color: #717171 } /* Generic.Output */
+.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #04D } /* Generic.Traceback */
+.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #008000 } /* Keyword.Pseudo */
+.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #B00040 } /* Keyword.Type */
+.highlight .m { color: #666 } /* Literal.Number */
+.highlight .s { color: #BA2121 } /* Literal.String */
+.highlight .na { color: #687822 } /* Name.Attribute */
+.highlight .nb { color: #008000 } /* Name.Builtin */
+.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */
+.highlight .no { color: #800 } /* Name.Constant */
+.highlight .nd { color: #A2F } /* Name.Decorator */
+.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #00F } /* Name.Function */
+.highlight .nl { color: #767600 } /* Name.Label */
+.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #19177C } /* Name.Variable */
+.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #BBB } /* Text.Whitespace */
+.highlight .mb { color: #666 } /* Literal.Number.Bin */
+.highlight .mf { color: #666 } /* Literal.Number.Float */
+.highlight .mh { color: #666 } /* Literal.Number.Hex */
+.highlight .mi { color: #666 } /* Literal.Number.Integer */
+.highlight .mo { color: #666 } /* Literal.Number.Oct */
+.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
+.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
+.highlight .sc { color: #BA2121 } /* Literal.String.Char */
+.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
+.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
+.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
+.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
+.highlight .sx { color: #008000 } /* Literal.String.Other */
+.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
+.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
+.highlight .ss { color: #19177C } /* Literal.String.Symbol */
+.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
+.highlight .fm { color: #00F } /* Name.Function.Magic */
+.highlight .vc { color: #19177C } /* Name.Variable.Class */
+.highlight .vg { color: #19177C } /* Name.Variable.Global */
+.highlight .vi { color: #19177C } /* Name.Variable.Instance */
+.highlight .vm { color: #19177C } /* Name.Variable.Magic */
+.highlight .il { color: #666 } /* Literal.Number.Integer.Long */
index 3416038c295d6edca71143d708c506fe4d9b7705..f6c93ada2cf56f66ddeb2abe907932ff604bb444 100644 (file)
@@ -14,19 +14,19 @@ body {
 }
 
 a {
-    color: #663399;
+    color: #58388c;
     text-decoration: none;
 }
 
 a:hover {
-    color: #884dbb;
+    color: #906ccf;
 }
 
 /* Header */
 header {
     background: #5e5e5e;
     padding: 15px 0;
-    border-bottom: 18px solid #a070d0;
+    border-bottom: 18px solid #a777ab;
 }
 
 header h1 {
@@ -37,13 +37,20 @@ header h1 {
 }
 
 header h1 a {
-    color: #fff;
+    color: #c5e7fc;
 }
 
 header h1 a:hover {
     color: #fff;
 }
 
+.site-description {
+    color: #ffdbff;
+    font-style: italic;
+    margin-top: 3px;
+    font-size: 14px;
+}
+
 /* Container */
 .container {
     max-width: 960px;
@@ -111,6 +118,81 @@ header h1 a:hover {
     font-weight: bold;
 }
 
+.post-content h1,
+.post-content h2,
+.post-content h3,
+.post-content h4,
+.post-content h5,
+.post-content h6 {
+    font-family: "Bitstream Charter", "Charter", Georgia, serif;
+    font-weight: bold;
+    line-height: 1.3;
+    margin: 1.2em 0 0.5em;
+}
+
+.post-content h1 { font-size: 24px; }
+.post-content h2 { font-size: 20px; }
+.post-content h3 { font-size: 17px; }
+.post-content h4 { font-size: 15px; }
+.post-content h5,
+.post-content h6 { font-size: 14px; }
+
+.post-content ul,
+.post-content ol {
+    margin: 0 0 1em 1.5em;
+}
+
+.post-content li {
+    margin-bottom: 0.3em;
+}
+
+.post-content blockquote {
+    margin: 0 0 1em 0;
+    padding: 2px 1.2em;
+    border-left: 4px solid #ddd;
+    color: #555;
+}
+
+.post-content blockquote p:last-child {
+    margin-bottom: 0;
+}
+
+.post-content hr {
+    margin: 2em 0;
+    border: none;
+    border-top: 1px solid #ddd;
+}
+
+.post-content img {
+    max-width: 100%;
+    height: auto;
+}
+
+.post-content table {
+    border-collapse: collapse;
+    margin-bottom: 1em;
+    width: 100%;
+}
+
+.post-content th,
+.post-content td {
+    border: 1px solid #ddd;
+    padding: 6px 10px;
+    text-align: left;
+}
+
+.post-content pre {
+    overflow-x: auto;
+    padding: 10px;
+    margin-bottom: 1em;
+    background: #f7f7f7;
+}
+
+.post-content code {
+    font-family: Consolas, Monaco, monospace;
+    font-size: 13px;
+}
+
 /* Sidebar */
 .sidebar {
     width: 220px;
@@ -155,7 +237,42 @@ header h1 a:hover {
 }
 
 .widget a {
-    color: #663399;
+    color: #58388c;
+    font-size: 12px;
+}
+
+.tagcloud {
+    line-height: 2.2;
+}
+
+.tagcloud a {
+    display: inline-block;
+    margin-right: 8px;
+}
+
+.archive-title {
+    font-family: "Bitstream Charter", "Charter", Georgia, serif;
+    font-size: 22px;
+    margin-bottom: 15px;
+}
+
+.archive-year {
+    font-size: 18px;
+    margin: 20px 0 8px;
+    border-bottom: 1px solid #ddd;
+}
+
+.archive-list {
+    list-style: none;
+    margin-bottom: 10px;
+}
+
+.archive-list li {
+    padding: 3px 0;
+}
+
+.archive-list time {
+    color: #999;
     font-size: 12px;
 }
 
diff --git a/theme/templates/archives.html b/theme/templates/archives.html
new file mode 100644 (file)
index 0000000..23a8583
--- /dev/null
@@ -0,0 +1,18 @@
+{% extends "base.html" %}
+
+{% block title %}{{ SITENAME }} - Archives{% endblock %}
+
+{% block content %}
+    <h2 class="archive-title">Archives</h2>
+    {% for year, year_articles in dates|groupby('date.year')|reverse %}
+        <h3 class="archive-year">{{ year }}</h3>
+        <ul class="archive-list">
+            {% for article in year_articles|reverse %}
+                <li>
+                    <time datetime="{{ article.date.isoformat() }}">{{ article.date.strftime('%-d %b') }}</time>
+                    &mdash; <a href="{{ SITEURL }}/{{ article.url }}">{{ article.title }}</a>
+                </li>
+            {% endfor %}
+        </ul>
+    {% endfor %}
+{% endblock %}
index f23efd81f19f6a4648be0fac2d880242688d35a3..e9cab1f597ad4cb25ac691b6491a49cba9fcd1ef 100644 (file)
@@ -1,24 +1,8 @@
 {% extends "base.html" %}
+{% import "includes/post_card.html" as post_card %}
 
 {% block title %}{{ article.title }} - {{ SITENAME }}{% endblock %}
 
 {% block content %}
-    <article class="post">
-        <h2 class="post-title">{{ article.title }}</h2>
-        <div class="post-meta">
-            <time datetime="{{ article.date.isoformat() }}">{{ article.date.strftime('%-d %B %Y') }}</time>
-            {% if article.category %}
-                | Category: <a href="{{ SITEURL }}/{{ article.category.url }}">{{ article.category }}</a>
-            {% endif %}
-            {% if article.tags %}
-                | Tags:
-                {% for tag in article.tags %}
-                    <a href="{{ SITEURL }}/{{ tag.url }}">{{ tag }}</a>{% if not loop.last %}, {% endif %}
-                {% endfor %}
-            {% endif %}
-        </div>
-        <div class="post-content">
-            {{ article.content }}
-        </div>
-    </article>
+    {{ post_card.render_post(article) }}
 {% endblock %}
diff --git a/theme/templates/author.html b/theme/templates/author.html
new file mode 100644 (file)
index 0000000..c9a964d
--- /dev/null
@@ -0,0 +1,7 @@
+{% extends "index.html" %}
+
+{% block title %}{{ SITENAME }} - {{ author }}{% endblock %}
+
+{% block content_title %}
+    <h2 class="archive-title">Author: {{ author }}</h2>
+{% endblock %}
diff --git a/theme/templates/authors.html b/theme/templates/authors.html
new file mode 100644 (file)
index 0000000..7491620
--- /dev/null
@@ -0,0 +1,12 @@
+{% extends "base.html" %}
+
+{% block title %}{{ SITENAME }} - Authors{% endblock %}
+
+{% block content %}
+    <h2 class="archive-title">Authors</h2>
+    <ul class="archive-list">
+        {% for author, articles in authors|sort %}
+            <li><a href="{{ SITEURL }}/{{ author.url }}">{{ author }}</a> ({{ articles|count }})</li>
+        {% endfor %}
+    </ul>
+{% endblock %}
index d0203efdef0b29b5523424f4adc16292bbfe1fc9..3bf152cd03f6ce92a17ad7effc241cff04f75245 100644 (file)
@@ -5,11 +5,20 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>{% block title %}{{ SITENAME }}{% endblock %}</title>
     <link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/css/style.css">
+    <link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/css/pygments.css">
+    {% if FEED_ALL_ATOM %}
+    <link rel="alternate" type="application/atom+xml" title="{{ SITENAME }} Full Atom Feed" href="{{ SITEURL }}/{{ FEED_ALL_ATOM }}">
+    {% endif %}
+    <script>
+    MathJax = { tex: { inlineMath: [['\\(', '\\)']], displayMath: [['$$', '$$']] } };
+    </script>
+    <script defer src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
 </head>
 <body>
     <header>
         <div class="container">
             <h1><a href="{{ SITEURL }}/">{{ SITENAME }}</a></h1>
+            {% if SITESUBTITLE %}<p class="site-description">{{ SITESUBTITLE }}</p>{% endif %}
         </div>
     </header>
 
             <div class="widget">
                 <h3>Archives</h3>
                 <ul>
-                {% for year, articles in dates|groupby('date.year')|reverse %}
+                {% for year, year_articles in dates|groupby('date.year')|reverse %}
                     <li><strong>{{ year }}</strong>
                         <ul>
-                        {% for month_num, month_articles in articles|groupby('date.month')|reverse %}
+                        {% for month_num, month_articles in year_articles|groupby('date.month')|reverse %}
                             <li>
-                                <a href="{{ SITEURL }}/{{ month_articles[0].date.strftime('%Y/%m') }}/">
+                                <a href="{{ SITEURL }}/{{ month_articles[0].date.strftime('%Y/%b') }}/">
                                     {{ month_articles[0].date.strftime('%B %Y') }}
                                 </a>
                                 ({{ month_articles|length }})
                 {% endfor %}
                 </ul>
             </div>
+
+            <div class="widget">
+                <h3>Categories</h3>
+                <ul>
+                {% for category, articles in categories %}
+                    <li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a> ({{ articles|count }})</li>
+                {% endfor %}
+                </ul>
+            </div>
+
+            <div class="widget">
+                <h3>Tags</h3>
+                {% set counts = tags|map('last')|map('length')|list %}
+                {% set max_count = counts|max %}
+                {% set min_count = counts|min %}
+                <div class="tagcloud">
+                {% for tag, articles in tags|sort %}
+                    {% set c = articles|count %}
+                    {% set size = 10 + ((c - min_count) / ((max_count - min_count) or 1)) * 10 %}
+                    <a href="{{ SITEURL }}/{{ tag.url }}" style="font-size: {{ size|round(1) }}px;" title="{{ c }} posts">{{ tag }}</a>
+                {% endfor %}
+                </div>
+            </div>
+
+            {% if LINKS %}
+            <div class="widget">
+                <h3>Blogroll</h3>
+                <ul>
+                {% for name, link in LINKS %}
+                    <li><a href="{{ link }}">{{ name }}</a></li>
+                {% endfor %}
+                </ul>
+            </div>
+            {% endif %}
         </aside>
     </div>
 
diff --git a/theme/templates/categories.html b/theme/templates/categories.html
new file mode 100644 (file)
index 0000000..c837533
--- /dev/null
@@ -0,0 +1,12 @@
+{% extends "base.html" %}
+
+{% block title %}{{ SITENAME }} - Categories{% endblock %}
+
+{% block content %}
+    <h2 class="archive-title">Categories</h2>
+    <ul class="archive-list">
+        {% for category, articles in categories %}
+            <li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a> ({{ articles|count }})</li>
+        {% endfor %}
+    </ul>
+{% endblock %}
diff --git a/theme/templates/category.html b/theme/templates/category.html
new file mode 100644 (file)
index 0000000..b8db656
--- /dev/null
@@ -0,0 +1,7 @@
+{% extends "index.html" %}
+
+{% block title %}{{ SITENAME }} - {{ category }} category{% endblock %}
+
+{% block content_title %}
+    <h2 class="archive-title">Category: {{ category }}</h2>
+{% endblock %}
diff --git a/theme/templates/includes/post_card.html b/theme/templates/includes/post_card.html
new file mode 100644 (file)
index 0000000..b2a391a
--- /dev/null
@@ -0,0 +1,22 @@
+{% macro render_post(article, full=True) %}
+<article class="post">
+    <h2 class="post-title">
+        <a href="{{ SITEURL }}/{{ article.url }}">{{ article.title }}</a>
+    </h2>
+    <div class="post-meta">
+        <time datetime="{{ article.date.isoformat() }}">{{ article.date.strftime('%-d %B %Y') }}</time>
+        {% if article.category %}
+            | <a href="{{ SITEURL }}/{{ article.category.url }}">{{ article.category }}</a>
+        {% endif %}
+        {% if article.tags %}
+            | Tags:
+            {% for tag in article.tags %}
+                <a href="{{ SITEURL }}/{{ tag.url }}">{{ tag }}</a>{% if not loop.last %}, {% endif %}
+            {% endfor %}
+        {% endif %}
+    </div>
+    <div class="post-content">
+        {{ article.content if full else article.summary }}
+    </div>
+</article>
+{% endmacro %}
index c869d4d7703eae11cc18a1fda4914eb1d2709df5..09949febe5541bf3c58738ec38c4cdae0ee0aef7 100644 (file)
@@ -1,24 +1,19 @@
 {% extends "base.html" %}
+{% import "includes/post_card.html" as post_card %}
 
 {% block content %}
+    {% block content_title %}{% endblock %}
+
     {% for article in articles_page.object_list %}
-        <article class="post">
-            <h2 class="post-title">
-                <a href="{{ SITEURL }}/{{ article.url }}">{{ article.title }}</a>
-            </h2>
-            <div class="post-meta">
-                <time datetime="{{ article.date.isoformat() }}">{{ article.date.strftime('%-d %B %Y') }}</time>
-            </div>
-            <div class="post-content">
-                {{ article.content }}
-            </div>
-        </article>
+        {{ post_card.render_post(article) }}
     {% endfor %}
 
     {% if articles_page.has_previous() or articles_page.has_next() %}
     <nav class="pagination">
         {% if articles_page.has_previous() %}
             <a href="{{ SITEURL }}/{{ articles_previous_page.url }}">&larr; Newer</a>
+        {% else %}
+            <span></span>
         {% endif %}
         {% if articles_page.has_next() %}
             <a href="{{ SITEURL }}/{{ articles_next_page.url }}">Older &rarr;</a>
diff --git a/theme/templates/page.html b/theme/templates/page.html
new file mode 100644 (file)
index 0000000..b187c57
--- /dev/null
@@ -0,0 +1,12 @@
+{% extends "base.html" %}
+
+{% block title %}{{ page.title }} - {{ SITENAME }}{% endblock %}
+
+{% block content %}
+    <article class="post">
+        <h2 class="post-title">{{ page.title }}</h2>
+        <div class="post-content">
+            {{ page.content }}
+        </div>
+    </article>
+{% endblock %}
diff --git a/theme/templates/period_archives.html b/theme/templates/period_archives.html
new file mode 100644 (file)
index 0000000..efa79a5
--- /dev/null
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+{% import "includes/post_card.html" as post_card %}
+
+{% block title %}{{ SITENAME }} - {{ period|reverse|join(' ') }} archives{% endblock %}
+
+{% block content %}
+    <h2 class="archive-title">{{ period|reverse|join(' ') }}</h2>
+    {% for article in dates %}
+        {{ post_card.render_post(article) }}
+    {% endfor %}
+{% endblock %}
diff --git a/theme/templates/tag.html b/theme/templates/tag.html
new file mode 100644 (file)
index 0000000..79b3f00
--- /dev/null
@@ -0,0 +1,7 @@
+{% extends "index.html" %}
+
+{% block title %}{{ SITENAME }} - {{ tag }} tag{% endblock %}
+
+{% block content_title %}
+    <h2 class="archive-title">Tag: {{ tag }}</h2>
+{% endblock %}
diff --git a/theme/templates/tags.html b/theme/templates/tags.html
new file mode 100644 (file)
index 0000000..c27d5a7
--- /dev/null
@@ -0,0 +1,12 @@
+{% extends "base.html" %}
+
+{% block title %}{{ SITENAME }} - Tags{% endblock %}
+
+{% block content %}
+    <h2 class="archive-title">Tags</h2>
+    <ul class="archive-list">
+        {% for tag, articles in tags|sort %}
+            <li><a href="{{ SITEURL }}/{{ tag.url }}">{{ tag }}</a> ({{ articles|count }})</li>
+        {% endfor %}
+    </ul>
+{% endblock %}