site: feeds everywhere + programmatic surface
Feeds: JSON Feed 1.1 at /feed.json, per-category and per-tag RSS at /categories/<name>/rss.xml and /tags/<name>/rss.xml alongside the main /rss.xml — all from a shared src/lib/feed.ts item source. Category/tag pages advertise their scoped feed via autodiscovery; new /feeds/ directory page (footer-linked) lists every feed with counts; RSS feeds gain an atom:link self reference and a feed.xsl stylesheet so they render readably in browsers. Programmatic readers: build-generated /llms.txt (site map with every review/bundle/post), SearchAction on the WebSite JSON-LD wired to /search/?q=, and a "For robots" section on /feeds/ documenting search.json, llms.txt, the sitemap, and JSON-LD coverage. Claude-Session: https://claude.ai/code/session_01WZaczDJjL3xZ3u5spsN5AL
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Browser-facing rendering for the site's RSS feeds. Feed readers ignore
|
||||
this entirely; it only makes /rss.xml (and the per-category/per-tag
|
||||
feeds) human-friendly when opened in a browser.
|
||||
-->
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
|
||||
<xsl:template match="/rss/channel">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title><xsl:value-of select="title"/> — feed</title>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<style>
|
||||
body {
|
||||
max-width: 42rem;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 1.25rem;
|
||||
background: #f4f0ec;
|
||||
color: #1a1a1a;
|
||||
font-family: ui-serif, Georgia, 'Iowan Old Style', serif;
|
||||
font-size: 18px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
a { color: #b34700; text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
.notice {
|
||||
padding: 0.75rem 1rem;
|
||||
background: #ebe6df;
|
||||
border-radius: 6px;
|
||||
font-family: ui-sans-serif, system-ui, sans-serif;
|
||||
font-size: 0.85rem;
|
||||
color: #6b6b6b;
|
||||
}
|
||||
.notice code {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
h1 { font-family: ui-sans-serif, system-ui, sans-serif; letter-spacing: -0.015em; margin: 1.5rem 0 0.25rem; }
|
||||
.tagline { margin: 0 0 2rem; font-style: italic; color: #6b6b6b; }
|
||||
.item { margin: 0 0 1.5rem; }
|
||||
.item h2 { margin: 0; font-size: 1.1rem; font-family: ui-sans-serif, system-ui, sans-serif; letter-spacing: -0.015em; }
|
||||
.item p { margin: 0.2rem 0 0; }
|
||||
.item .date {
|
||||
font-family: ui-sans-serif, system-ui, sans-serif;
|
||||
font-size: 0.72rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: #6b6b6b;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p class="notice">
|
||||
This is an <strong>RSS feed</strong>. Copy this page's address into
|
||||
your feed reader to subscribe. All feeds are listed at
|
||||
<a href="/feeds/">/feeds/</a>.
|
||||
</p>
|
||||
<h1><xsl:value-of select="title"/></h1>
|
||||
<p class="tagline"><xsl:value-of select="description"/></p>
|
||||
<xsl:for-each select="item">
|
||||
<div class="item">
|
||||
<h2>
|
||||
<a>
|
||||
<xsl:attribute name="href"><xsl:value-of select="link"/></xsl:attribute>
|
||||
<xsl:value-of select="title"/>
|
||||
</a>
|
||||
</h2>
|
||||
<p class="date"><xsl:value-of select="pubDate"/></p>
|
||||
<p><xsl:value-of select="description"/></p>
|
||||
</div>
|
||||
</xsl:for-each>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
Reference in New Issue
Block a user