aboutsummaryrefslogtreecommitdiff
path: root/build/rss-hacks/index.html
blob: ee6fdcd81618340a0fd4a1bf1fa505e1004c4283 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta name="color-scheme" content="dark light">
	<link rel="icon" href="data:,">
	<title>RSS Hacks With XSLT</title>
	<link href="/atom.xml" type="application/atom+xml" rel="alternate" title="Atom feed for blog posts" />
	<link href="/rss.xml" type="application/rss+xml" rel="alternate" title="RSS feed for blog posts" />
<style>*{box-sizing:border-box;}body{font-family:sans-serif;line-height:1.33;margin:0 auto;max-width:650px;padding:1rem;}blockquote{background:rgba(0,0,0,0.1);border-left:4px solid;padding-left:5px;}img{max-width:100%;}pre{border:1px solid;overflow:auto;padding:5px;}table{text-align:left;width:100%;}.footnotes{font-size:90%;}</style>
</head>

<nav>
	<a href="#menu">Menu &darr;</a>
</nav>

<main>
<h1 id="rss-hacks-with-xslt">RSS Hacks With XSLT</h1>
<p>2022-05-23</p>
<p>In my spare time I&#8217;ve been further tinkering (hopefully for the better) with my humble Shinobi Website[^0] script. The most recent update in <code>patch-1</code> came with a solid amount of QoL improvements. If you&#8217;re interested, I wrote about it on the official Shinobi blog[^1].</p>
<p>The next feature I wanted to tackle was designing a custom layout for the XML files directly in the browser. I was greatly inspired to create something similar to Len Falken&#8217;s main directory listing[^2], since that blog was one of the original inspirations for Shinobi. I&#8217;m not able to copy what&#8217;s there though, since our feed builds are quite a bit different.</p>
<p>I then proceeded to fall down the XSLT rabbit hole.</p>
<h2 id="it-never-works-the-first-time-does-it">It Never Works the First Time, Does It?</h2>
<p>Since the shinobi script generates valid RSS code by default, I didn&#8217;t want to mess around <em>too</em> much via XSLT and risk breaking validation. I also wanted to keep the &#8220;plain text&#8221; look-and-feel for consistency with the rest of the site, even though the XSLT template would render into standard HTML. Minor CSS styling and placing the content directly inside <code>pre</code> tags solved these issues.</p>
<p>My first attempt was to use the available <code>sort</code> parameter (in XSL version 1.1+) targeting the <code>dc:date</code> type linked to the <code>pubDate</code> element:</p>
<pre><code>&#60;xsl:sort select="pubDate" data-type="dc:date" order="descending"&#47;&#62;
&#60;!-- each individual post&#39;s content here --&#62;
</code></pre>
<p>This did not work as intended. RSS 2.0 requires that the <code>pubDate</code> content is set to comply with the RFC-822 date-time[^3], which shinobi handles perfectly fine. The issue came from the XSL <code>sort</code> parameter not honoring this setting across all dates. My best guess is that it struggles to properly organize posts from their &#8220;month&#8221; parameter, so it sets the posts in order of date in what I refer to as &#8220;monthly sections&#8221;.</p>
<p>If anyone knows why this failed to consistently order the posts via <code>pubDate</code>, please let me know using the comment link below. I&#8217;m far from an XSLT expert and might have overlooked something painfully obvious!</p>
<h2 id="rss-hack-categories">RSS Hack: Categories</h2>
<p>After spending far too much time reading over documentation, official manual pages and Stack Overflow comments I gave up on the <code>dc:date</code> sort. I realized I could sort the posts much easier if they were converted into a format similar to ISO 8601. But <code>pubDate</code> is required to be in RFC-822, so I couldn&#8217;t alter that in the final XML file.</p>
<p>Then I remembered the <code>category</code> tag which shinobi does not utilize by default.</p>
<p>First I needed to convert the RFC-822 formatted date (found on the first line of all blog post text files) and render it inside a <code>category</code> tag. This was simple enough:</p>
<pre><code>$(date -j -f "%a, %d %b %Y" "$(head -n 1 $file)" +"%Y&#47;%m&#47;%d&#47;%u")
</code></pre>
<p>In a nutshell, this converts the RFC-822 date into the format &#8220;2022&#47;05&#47;24&#47;2&#8221;. Simple numbers that can be sorted much easier by XSL. Now all that was needed was setting to <code>sort</code> parameter properly:</p>
<pre><code>&#60;xsl:sort select="category" order="descending"&#47;&#62;
</code></pre>
<p>Everything worked perfectly and the RSS was still valid!</p>
<h3 id="patch-2-pending">Patch-2 Pending</h3>
<p>I&#8217;ve ported these changes over to this blog to perform some &#8220;in the wild&#8221; testing. You can see the custom feed list in your supported browser by visiting:</p>
<p><a href="https://pblog.bt.ht/feed.xml">https:&#47;&#47;pblog.bt.ht&#47;feed.xml</a></p>
<p>As for the shinobi project itself, I have not merged these updates into the main master branch (at the time of publishing this article). They can be found sitting on patch-2[^4]. My plan is to get this merged ASAP once a little more real-world testing is finished and I can include a better &#8220;setup&#47;install&#8221; section for newcomers.</p>
<h2 id="shinobi-updates">Shinobi Updates</h2>
<p>If you&#8217;re interested in more updates and details about the shinobi project itself, feel free to sub to that specific feed below. This post was more focused on hacking RSS parameters that happened to involve shinobi, but in the future all updates specific to the project will be posted there:</p>
<p><a href="https://shinobi.bt.ht/feed.xml">https:&#47;&#47;shinobi.bt.ht&#47;feed.xml</a></p>
<h2 id="refs">Refs</h2>
<ol>
<li><a href="https://shinobi.website/">https:&#47;&#47;shinobi.website&#47;</a></li>
<li><a href="https://shinobi.website/posts/patch-1.txt">https:&#47;&#47;shinobi.website&#47;posts&#47;patch-1.txt</a></li>
<li><a href="http://len.falken.directory/">http:&#47;&#47;len.falken.directory&#47;</a></li>
<li><a href="https://validator.w3.org/feed/docs/error/InvalidRFC2822Date.html">https:&#47;&#47;validator.w3.org&#47;feed&#47;docs&#47;error&#47;InvalidRFC2822Date.html</a></li>
<li><a href="https://git.sr.ht/~tdarb/shinobi-script/tree/patch-2">https:&#47;&#47;git.sr.ht&#47;~tdarb&#47;shinobi-script&#47;tree&#47;patch-2</a></li>
</ol>
<footer role="contentinfo">
    <h2>Menu Navigation</h2>
    <ul id="menu">
        <li><a href="/">Home</a></li>
        <li><a href="/projects">Projects</a></li>
        <li><a href="/uses">Uses</a></li>
        <li><a href="/wiki">Wiki</a></li>
        <li><a href="/resume">Resume</a></li>
        <li><a href="/colophon">Colophon</a></li>
        <li><a href="/now">Now</a></li>
        <li><a href="/donate">Donate</a></li>
        <li><a href="/atom.xml">RSS</a></li>
        <li><a href="#top">&uarr; Top of the page</a></li>
    </ul>
    <small>
        Built with <a href="https://git.sr.ht/~bt/barf">barf</a>. <br>
        Maintained with ♥ for the web. <br>
        Proud supporter of <a href="https://usefathom.com/ref/DKHJVX">Fathom</a> &amp; <a href="https://nextdns.io/?from=74d3p3h8">NextDNS</a>. <br>
        The content for this site is <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>.<br> The <a href="https://git.sr.ht/~bt/bt.ht">code for this site</a> is <a href="https://git.sr.ht/~bt/bt.ht/tree/master/item/LICENSE">MIT</a>.
    </small>
</footer>