guide/03-collections.html
212 lines · 46880 bytes
1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="utf-8">
5<meta name="viewport" content="width=device-width, initial-scale=1">
6<title>Collections · orgo</title>
7<meta name="description" content="Generated pages — blog indexes, tag pages, pagination and RSS feeds.">
8<link rel="icon" href="../favicon.svg" type="image/svg+xml">
9<link rel="stylesheet" href="../theme.css">
10<link rel="stylesheet" href="../syntax.css">
11<link rel="stylesheet" href="../style.css">
12</head>
13<body>
14<header class="site">
15<a class="site-title" href="../index.html">orgo</a>
16<nav>
17<a href="../install.html">Install</a>
18<a href="../quickstart.html">Quick start</a>
19<a href="index.html">Guide</a>
20</nav>
21</header>
22<main>
23<h1>Collections</h1>
24<p class="lede">The one kind of output that is not a translation of some input.</p>
25<nav class="toc" aria-label="On this page">
26<h2>On this page</h2>
27<ul>
28<li><a href="#a-blog-index">A blog index</a>
29<ul>
30<li><a href="#sorting">Sorting</a></li>
31<li><a href="#grouping-a-listing-by-year">Grouping a listing by year</a></li>
32<li><a href="#full-content-feeds">Full-content feeds</a></li>
33<li><a href="#nav-true">nav = true</a></li>
34</ul></li>
35<li><a href="#tag-pages">Tag pages</a>
36<ul>
37<li><a href="#grouping-by-anything">Grouping by anything</a></li>
38<li><a href="#two-tags-that-would-collide-are-an-error">Two tags that would collide are an error</a></li>
39</ul></li>
40<li><a href="#pagination">Pagination</a></li>
41<li><a href="#an-rss-feed">An RSS feed</a></li>
42<li><a href="#every-setting">Every setting</a></li>
43<li><a href="#incremental-behaviour">Incremental behaviour</a></li>
44</ul>
45</nav>
46<p>A blog index exists because a set of posts exists, not because someone wrote <code class="verbatim">index.org</code>. A <code class="verbatim">[[collections]]</code> block declares one: a source directory in, an output file out, through a template.</p>
47<p>Keeping it declarative means an RSS feed is the same mechanism with an XML template rather than a second feature.</p>
48<h2 id="a-blog-index">A blog index</h2>
49<pre><code class="language-toml highlight"><span class="source toml"><span class="punctuation definition table array toml">[[</span><span class="entity name section toml">collections</span><span class="punctuation definition table array toml">]]</span>
50<span class="variable other key toml">source</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>blog<span class="punctuation definition string end toml">"</span></span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> directory to list; empty means every page
51</span><span class="variable other key toml">output</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>blog/index.html<span class="punctuation definition string end toml">"</span></span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> where to write it
52</span><span class="variable other key toml">template</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>list.html<span class="punctuation definition string end toml">"</span></span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> template file name
53</span><span class="variable other key toml">title</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>Blog<span class="punctuation definition string end toml">"</span></span>
54<span class="variable other key toml">sort</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>date<span class="punctuation definition string end toml">"</span></span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> date | title | path
55</span><span class="variable other key toml">order</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>desc<span class="punctuation definition string end toml">"</span></span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> desc | asc
56</span><span class="variable other key toml">nav</span> <span class="keyword operator assignment toml">=</span> <span class="constant language toml">true</span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> put this page in the site nav</span></span></code></pre>
57<p>The template receives the collection's entries as <code class="verbatim">pages</code>, already sorted, plus the usual <code class="verbatim">site</code>, <code class="verbatim">nav</code> and <code class="verbatim">root</code>:</p>
58<pre><code class="language-html highlight"><span class="text html basic">{% extends "base.html" %}
59{% block content %}
60<span class="meta tag block any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag block any html">ul</span><span class="punctuation definition tag end html">></span></span>
61 {% for post in pages %}
62 <span class="meta tag inline any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline any html">li</span><span class="punctuation definition tag end html">></span></span>
63 <span class="meta tag other html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag other html">time</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">datetime</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ post.date_iso }}<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>{{ post.date_iso }}<span class="meta tag other html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag other html">time</span><span class="punctuation definition tag end html">></span></span>
64 <span class="meta tag inline a html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline a html">a</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">href</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ root }}{{ post.url }}<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>{{ post.title }}<span class="meta tag inline a html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline a html">a</span><span class="punctuation definition tag end html">></span></span>
65 <span class="meta tag block any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag block any html">p</span><span class="punctuation definition tag end html">></span></span>{{ post.excerpt | truncate(180) }}<span class="meta tag block any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag block any html">p</span><span class="punctuation definition tag end html">></span></span>
66 <span class="meta tag inline any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline any html">li</span><span class="punctuation definition tag end html">></span></span>
67 {% endfor %}
68<span class="meta tag block any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag block any html">ul</span><span class="punctuation definition tag end html">></span></span>
69{% endblock %}</span></code></pre>
70<h3 id="sorting">Sorting</h3>
71<p><code class="verbatim">sort</code> is <code class="verbatim">date</code> (default), <code class="verbatim">title</code> or <code class="verbatim">path</code>; <code class="verbatim">order</code> is <code class="verbatim">desc</code> (default) or <code class="verbatim">asc</code>.</p>
72<p>Date sorting uses <code class="verbatim">page.date_iso</code>, the <code class="verbatim">YYYY-MM-DD</code> extracted from <code class="verbatim">#+DATE:</code> whatever org syntax it was written in — <code class="verbatim">[2025-09-05 Fri 10:21:00]</code>, <code class="verbatim"><2024-05-01 Wed></code> or a bare <code class="verbatim">2024-05-01</code> all work.</p>
73<p><strong>Pages with no parseable date sort last in either direction</strong>, so an undated draft never leads a dated archive.</p>
74<h3 id="grouping-a-listing-by-year">Grouping a listing by year</h3>
75<p>An archive usually wants year headings, and that is a <strong>template</strong> decision rather than a config one — the entries are already in the right order, they just need breaking up. <code class="verbatim">page.year</code> exists for exactly this, because minijinja's <code class="verbatim">groupby</code> takes an attribute name and cannot slice a date itself:</p>
76<pre><code class="language-html highlight"><span class="text html basic"><span class="meta tag block any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag block any html">ul</span> <span class="meta attribute-with-value class html"><span class="entity other attribute-name class html">class</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value class html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span></span></span><span class="meta attribute-with-value class html"><span class="string quoted double html"><span class="meta class-name html">post-list</span><span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>
77{% for year, posts in pages | groupby("year") | reverse %}
78 <span class="meta tag inline any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline any html">li</span> <span class="meta attribute-with-value class html"><span class="entity other attribute-name class html">class</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value class html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span></span></span><span class="meta attribute-with-value class html"><span class="string quoted double html"><span class="meta class-name html">post-list-year</span><span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>{{ year if year else "undated" }}<span class="meta tag inline any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline any html">li</span><span class="punctuation definition tag end html">></span></span>
79 {% for entry in posts %}
80 <span class="meta tag inline any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline any html">li</span><span class="punctuation definition tag end html">></span></span><span class="meta tag other html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag other html">time</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">datetime</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ entry.date_iso }}<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>{{ entry.date_iso }}<span class="meta tag other html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag other html">time</span><span class="punctuation definition tag end html">></span></span>
81 <span class="meta tag inline a html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline a html">a</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">href</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ root }}{{ entry.url }}<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>{{ entry.title }}<span class="meta tag inline a html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline a html">a</span><span class="punctuation definition tag end html">></span></span><span class="meta tag inline any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline any html">li</span><span class="punctuation definition tag end html">></span></span>
82 {% endfor %}
83{% endfor %}
84<span class="meta tag block any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag block any html">ul</span><span class="punctuation definition tag end html">></span></span></span></code></pre>
85<p><code class="verbatim">groupby</code> sorts its groups ascending, so <code class="verbatim">| reverse</code> puts the newest year first — matching the <code class="verbatim">order = "desc"</code> the entries themselves already use, and leaving undated pages in a group of their own at the end.</p>
86<p>Name that group in the template rather than with <code class="verbatim">groupby</code>'s <code class="verbatim">default=</code> argument, which covers an attribute that is <strong>missing</strong> and not one that is null — an undated page has a <code class="verbatim">year</code>, and it is <code class="verbatim">none</code>.</p>
87<h3 id="full-content-feeds">Full-content feeds</h3>
88<p>A feed usually carries whole posts, and a subscriber handed excerpts instead has lost something. <code class="verbatim">include_content</code> gives the template each entry's rendered HTML as <code class="verbatim">entry.content</code>:</p>
89<pre><code class="language-toml highlight"><span class="source toml"><span class="punctuation definition table array toml">[[</span><span class="entity name section toml">collections</span><span class="punctuation definition table array toml">]]</span>
90<span class="variable other key toml">source</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>blog<span class="punctuation definition string end toml">"</span></span>
91<span class="variable other key toml">output</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>feed.xml<span class="punctuation definition string end toml">"</span></span>
92<span class="variable other key toml">template</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>feed.xml<span class="punctuation definition string end toml">"</span></span>
93<span class="variable other key toml">include_content</span> <span class="keyword operator assignment toml">=</span> <span class="constant language toml">true</span></span></code></pre>
94<pre><code class="language-html highlight"><span class="text html basic"><span class="meta tag other html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag other html">description</span><span class="punctuation definition tag end html">></span></span><span class="meta tag sgml html"><span class="punctuation definition tag html"><!</span><span class="constant other inline-data html">[CDATA[{{ post.content | safe }}]]</span><span class="punctuation definition tag html">></span></span><span class="meta tag other html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag other html">description</span><span class="punctuation definition tag end html">></span></span></span></code></pre>
95<p>Off by default, because it costs a render of every listed page each time the listing is rebuilt. That cost is only paid when the listing is <strong>not</strong> cached, and the listing's cache key covers its entries' content — so a body edit reaches the feed, and an unchanged site pays nothing.</p>
96<p>Everywhere else <code class="verbatim">entry.content</code> is <code class="verbatim">none</code>, since carrying every page's body in every listing context would be most of a site's memory for nothing.</p>
97<h3 id="nav-true">nav = true</h3>
98<p>The listing page joins the site navigation. This is how a section landing page — <code class="verbatim">/blog/</code>, <code class="verbatim">/notes/</code> — gets into a nav built from top-level pages, and it points at the right thing: the section, not any one post in it.</p>
99<h2 id="tag-pages">Tag pages</h2>
100<p>Add <code class="verbatim">group_by</code> and the collection emits one page <em>per group</em> instead of one page total, plus an optional index of the groups:</p>
101<pre><code class="language-toml highlight"><span class="source toml"><span class="punctuation definition table array toml">[[</span><span class="entity name section toml">collections</span><span class="punctuation definition table array toml">]]</span>
102<span class="variable other key toml">source</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>blog<span class="punctuation definition string end toml">"</span></span>
103<span class="variable other key toml">group_by</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>tags<span class="punctuation definition string end toml">"</span></span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> "tags", or any #+KEYWORD: name
104</span><span class="variable other key toml">output</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>tags/{tag}.html<span class="punctuation definition string end toml">"</span></span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> {tag} becomes each group's slug
105</span><span class="variable other key toml">template</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>tag.html<span class="punctuation definition string end toml">"</span></span>
106<span class="variable other key toml">title</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>Tagged: {tag}<span class="punctuation definition string end toml">"</span></span>
107<span class="variable other key toml">index_output</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>tags/index.html<span class="punctuation definition string end toml">"</span></span>
108<span class="variable other key toml">index_template</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>tags.html<span class="punctuation definition string end toml">"</span></span>
109<span class="variable other key toml">index_title</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>Tags<span class="punctuation definition string end toml">"</span></span>
110<span class="variable other key toml">nav</span> <span class="keyword operator assignment toml">=</span> <span class="constant language toml">true</span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> adds the *index*, not every tag</span></span></code></pre>
111<p>A group page receives its own posts as <code class="verbatim">pages</code> and itself as <code class="verbatim">group</code>:</p>
112<pre><code class="language-html highlight"><span class="text html basic"><span class="meta tag block any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag block any html">h1</span><span class="punctuation definition tag end html">></span></span>{{ group.name }} ({{ group.count }})<span class="meta tag block any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag block any html">h1</span><span class="punctuation definition tag end html">></span></span>
113{% for post in pages %}<span class="meta tag inline a html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline a html">a</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">href</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ root }}{{ post.url }}<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>{{ post.title }}<span class="meta tag inline a html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline a html">a</span><span class="punctuation definition tag end html">></span></span>{% endfor %}</span></code></pre>
114<p>The index receives <code class="verbatim">groups</code>, sorted by name:</p>
115<pre><code class="language-html highlight"><span class="text html basic"><span class="meta tag block any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag block any html">ul</span><span class="punctuation definition tag end html">></span></span>{% for tag in groups %}
116 <span class="meta tag inline any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline any html">li</span><span class="punctuation definition tag end html">></span></span><span class="meta tag inline a html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline a html">a</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">href</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ root }}{{ tag.url }}<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>{{ tag.name }}<span class="meta tag inline a html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline a html">a</span><span class="punctuation definition tag end html">></span></span> ({{ tag.count }})<span class="meta tag inline any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline any html">li</span><span class="punctuation definition tag end html">></span></span>
117{% endfor %}<span class="meta tag block any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag block any html">ul</span><span class="punctuation definition tag end html">></span></span></span></code></pre>
118<h3 id="grouping-by-anything">Grouping by anything</h3>
119<p><code class="verbatim">group_by = "tags"</code> is multi-valued: a post appears under every tag it carries. Any other value names a single-valued <code class="verbatim">#+KEYWORD:</code>, so <code class="verbatim">group_by = "category"</code> buckets pages by <code class="verbatim">#+CATEGORY:</code> with no extra machinery.</p>
120<h3 id="two-tags-that-would-collide-are-an-error">Two tags that would collide are an error</h3>
121<p><code class="verbatim">web_dev</code> and <code class="verbatim">web@dev</code> both slugify to <code class="verbatim">web-dev</code>, so one page would silently overwrite the other. That is a build error naming both values.</p>
122<h2 id="pagination">Pagination</h2>
123<pre><code class="language-toml highlight"><span class="source toml"><span class="punctuation definition table array toml">[[</span><span class="entity name section toml">collections</span><span class="punctuation definition table array toml">]]</span>
124<span class="variable other key toml">source</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>blog<span class="punctuation definition string end toml">"</span></span>
125<span class="variable other key toml">output</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>blog/index.html<span class="punctuation definition string end toml">"</span></span>
126<span class="variable other key toml">paginate</span> <span class="keyword operator assignment toml">=</span> <span class="constant numeric toml">10</span>
127<span class="variable other key toml">paginate_output</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>blog/page/{n}.html<span class="punctuation definition string end toml">"</span></span> <span class="comment line number-sign toml"><span class="punctuation definition comment toml">#</span> {n} is the 1-based page number</span></span></code></pre>
128<p><strong>Page 1 stays at <code class="verbatim">output</code></strong>, so a section's canonical URL never moves as its page count changes. Only pages 2..N are named by <code class="verbatim">paginate_output</code>.</p>
129<p>The template gets a <code class="verbatim">paginator</code>:</p>
130<pre><code class="language-html highlight"><span class="text html basic">{% if paginator and paginator.total > 1 %}
131<span class="meta tag block any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag block any html">nav</span><span class="punctuation definition tag end html">></span></span>
132 {% if paginator.prev_url %}<span class="meta tag inline a html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline a html">a</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">href</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ paginator.prev_url }}<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>Newer<span class="meta tag inline a html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline a html">a</span><span class="punctuation definition tag end html">></span></span>{% endif %}
133 {% for pg in paginator.pages %}
134 <span class="meta tag inline a html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline a html">a</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">href</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ pg.url }}<span class="punctuation definition string end html">"</span></span></span>{% <span class="entity other attribute-name html">if</span> <span class="entity other attribute-name html">pg.current</span> %} <span class="meta attribute-with-value html"><span class="entity other attribute-name html">aria-current</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>page<span class="punctuation definition string end html">"</span></span></span>{% <span class="entity other attribute-name html">endif</span> %}<span class="punctuation definition tag end html">></span></span>{{ pg.number }}<span class="meta tag inline a html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline a html">a</span><span class="punctuation definition tag end html">></span></span>
135 {% endfor %}
136 {% if paginator.next_url %}<span class="meta tag inline a html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline a html">a</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">href</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ paginator.next_url }}<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>Older<span class="meta tag inline a html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline a html">a</span><span class="punctuation definition tag end html">></span></span>{% endif %}
137<span class="meta tag block any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag block any html">nav</span><span class="punctuation definition tag end html">></span></span>
138{% endif %}</span></code></pre>
139<table>
140<thead>
141<tr><th>Field</th><th>Meaning</th></tr>
142</thead>
143<tbody>
144<tr><td><code class="verbatim">current</code>, <code class="verbatim">total</code></td><td>This page's number, and how many there are.</td></tr>
145<tr><td><code class="verbatim">per_page</code>, <code class="verbatim">total_entries</code></td><td>As configured, and across the whole listing.</td></tr>
146<tr><td><code class="verbatim">prev_url</code>, <code class="verbatim">next_url</code></td><td><code class="verbatim">none</code> at the ends.</td></tr>
147<tr><td><code class="verbatim">first_url</code>, <code class="verbatim">last_url</code></td><td>Always present.</td></tr>
148<tr><td><code class="verbatim">pages</code></td><td><code class="verbatim">[{number, url, current}]</code> for a numbered strip.</td></tr>
149</tbody>
150</table>
151<p>Every URL is relative to the page carrying it, so links work from page 1 (<code class="verbatim">page/2.html</code>) and from page 5 (<code class="verbatim">../index.html</code>, <code class="verbatim">6.html</code>) without the template knowing where it sits. An unpaginated collection has no <code class="verbatim">paginator</code> at all, so <code class="verbatim">{% if paginator %}</code> is a reliable test in a shared template.</p>
152<p>Grouping and pagination compose: each group paginates independently, which is why <code class="verbatim">paginate_output</code> needs <code class="verbatim">{tag}</code> as well as <code class="verbatim">{n}</code> on a grouped collection.</p>
153<h2 id="an-rss-feed">An RSS feed</h2>
154<p>A feed is a listing page with an XML template. Templates load by full filename and any extension, so:</p>
155<pre><code class="language-toml highlight"><span class="source toml"><span class="punctuation definition table array toml">[[</span><span class="entity name section toml">collections</span><span class="punctuation definition table array toml">]]</span>
156<span class="variable other key toml">source</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>blog<span class="punctuation definition string end toml">"</span></span>
157<span class="variable other key toml">output</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>feed.xml<span class="punctuation definition string end toml">"</span></span>
158<span class="variable other key toml">template</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>feed.xml<span class="punctuation definition string end toml">"</span></span>
159<span class="variable other key toml">title</span> <span class="keyword operator assignment toml">=</span> <span class="string quoted double toml"><span class="punctuation definition string begin toml">"</span>Feed<span class="punctuation definition string end toml">"</span></span></span></code></pre>
160<pre><code class="language-html highlight"><span class="text html basic"><span class="meta tag preprocessor xml html"><span class="punctuation definition tag begin html"><?</span><span class="entity name tag xml html">xml</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">version</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>1.0<span class="punctuation definition string end html">"</span></span></span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">encoding</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>utf-8<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">?></span></span>
161<span class="meta tag other html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag other html">rss</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">version</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>2.0<span class="punctuation definition string end html">"</span></span></span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">xmlns:atom</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>http://www.w3.org/2005/Atom<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>
162<span class="meta tag other html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag other html">channel</span><span class="punctuation definition tag end html">></span></span>
163 <span class="meta tag inline any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline any html">title</span><span class="punctuation definition tag end html">></span></span>{{ site.title }}<span class="meta tag inline any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline any html">title</span><span class="punctuation definition tag end html">></span></span>
164 <span class="meta tag inline any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline any html">link</span><span class="punctuation definition tag end html">></span></span>{{ "index.html" | absolute }}<span class="meta tag inline any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline any html">link</span><span class="punctuation definition tag end html">></span></span>
165 <span class="meta tag other html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag other html">atom:link</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">href</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>{{ page.url | absolute }}<span class="punctuation definition string end html">"</span></span></span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">rel</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>self<span class="punctuation definition string end html">"</span></span></span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">type</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>application/rss+xml<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">/></span></span>
166 {% for post in pages %}
167 <span class="meta tag other html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag other html">item</span><span class="punctuation definition tag end html">></span></span>
168 <span class="meta tag inline any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline any html">title</span><span class="punctuation definition tag end html">></span></span>{{ post.title }}<span class="meta tag inline any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline any html">title</span><span class="punctuation definition tag end html">></span></span>
169 <span class="meta tag inline any html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag inline any html">link</span><span class="punctuation definition tag end html">></span></span>{{ post.url | absolute }}<span class="meta tag inline any html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag inline any html">link</span><span class="punctuation definition tag end html">></span></span>
170 <span class="meta tag other html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag other html">guid</span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">isPermaLink</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">"</span>true<span class="punctuation definition string end html">"</span></span></span><span class="punctuation definition tag end html">></span></span>{{ post.url | absolute }}<span class="meta tag other html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag other html">guid</span><span class="punctuation definition tag end html">></span></span>
171 <span class="meta tag other html"><span class="punctuation definition tag begin html"><</span><span class="entity name tag other html">pubDate</span><span class="punctuation definition tag end html">></span></span>{{ post.date_iso | rfc822 }}<span class="meta tag other html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag other html">pubDate</span><span class="punctuation definition tag end html">></span></span>
172 <span class="meta tag other html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag other html">item</span><span class="punctuation definition tag end html">></span></span>
173 {% endfor %}
174<span class="meta tag other html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag other html">channel</span><span class="punctuation definition tag end html">></span></span>
175<span class="meta tag other html"><span class="punctuation definition tag begin html"></</span><span class="entity name tag other html">rss</span><span class="punctuation definition tag end html">></span></span></span></code></pre>
176<p>This needs <code class="verbatim">site.base_url</code>, because a feed with relative links is invalid everywhere it is read. <code class="verbatim">orgo init</code> writes this template and leaves the collection commented out until there is a base URL to make absolute links from.</p>
177<h2 id="every-setting">Every setting</h2>
178<table>
179<thead>
180<tr><th>Key</th><th>Default</th><th>Meaning</th></tr>
181</thead>
182<tbody>
183<tr><td><code class="verbatim">source</code></td><td>=""</td><td>Directory to list. Empty means every page.</td></tr>
184<tr><td><code class="verbatim">output</code></td><td><code class="verbatim">"index.html"</code></td><td>Where to write. Needs <code class="verbatim">{tag}</code> when grouped.</td></tr>
185<tr><td><code class="verbatim">template</code></td><td><code class="verbatim">"list.html"</code></td><td>Template file name.</td></tr>
186<tr><td><code class="verbatim">title</code></td><td><code class="verbatim">"Index"</code></td><td><code class="verbatim">{{ page.title }}</code>. <code class="verbatim">{tag}</code> is substituted when grouped.</td></tr>
187<tr><td><code class="verbatim">group_by</code></td><td>=""</td><td><code class="verbatim">"tags"</code>, or a <code class="verbatim">#+KEYWORD:</code> name. Empty means one page.</td></tr>
188<tr><td><code class="verbatim">index_output</code></td><td>=""</td><td>Where to write the group index. Empty means none.</td></tr>
189<tr><td><code class="verbatim">index_template</code></td><td><code class="verbatim">"tags.html"</code></td><td>Template for the group index.</td></tr>
190<tr><td><code class="verbatim">index_title</code></td><td><code class="verbatim">"Tags"</code></td><td>Title for the group index.</td></tr>
191<tr><td><code class="verbatim">sort</code></td><td><code class="verbatim">"date"</code></td><td><code class="verbatim">date</code>, <code class="verbatim">title</code> or <code class="verbatim">path</code>.</td></tr>
192<tr><td><code class="verbatim">order</code></td><td><code class="verbatim">"desc"</code></td><td><code class="verbatim">desc</code> or <code class="verbatim">asc</code>.</td></tr>
193<tr><td><code class="verbatim">paginate</code></td><td><code class="verbatim">0</code></td><td>Entries per page. <code class="verbatim">0</code> means no pagination.</td></tr>
194<tr><td><code class="verbatim">paginate_output</code></td><td>=""</td><td>Where pages 2..N go. Needs <code class="verbatim">{n}</code>.</td></tr>
195<tr><td><code class="verbatim">nav</code></td><td><code class="verbatim">false</code></td><td>Add this page — or its index, when grouped — to the nav.</td></tr>
196</tbody>
197</table>
198<h2 id="incremental-behaviour">Incremental behaviour</h2>
199<p>A listing page is cached on the entries it lists, so:</p>
200<ul>
201<li>Adding a post re-renders that post, its section index, its tag pages and the tag index whose counts changed. Nothing else.</li>
202<li>Editing a post's <strong>body</strong> changes no listing metadata, so the index is not touched at all.</li>
203<li>Retitling a post does re-render the listings that display the title.</li>
204</ul>
205<p>A tag page depends on its own posts and not on the other groups, which is why <code class="verbatim">groups</code> is given to the index and not to every group page: a page that can see every group would depend on every group, and one new post would re-render every tag page.</p>
206<p>When a collection shrinks below a page boundary, the pages that no longer exist are deleted rather than left serving stale content.</p>
207</main>
208<footer class="site">
209Built with orgo — these docs are an orgo site.
210</footer>
211</body>
212</html>