Move feeds out of subpath. (#72)

Flatten feed location.

Now, if people decide to host this at my-domain/feed, the feeds won't be at my-domain/feed/feed

Reviewed-on: https://gitea.subcultureofone.org/greg/tkr/pulls/72
Co-authored-by: Greg Sarjeant <greg@subcultureofone.org>
Co-committed-by: Greg Sarjeant <greg@subcultureofone.org>
This commit is contained in:
Greg Sarjeant 2025-08-15 01:44:50 +00:00 committed by greg
parent dbd27b266d
commit d03c0a5331
9 changed files with 14 additions and 14 deletions

View File

@ -29,7 +29,7 @@ A lightweight, HTML-only status feed for self-hosted personal websites. Written
* HTML and CSS implementation. No Javascript. * HTML and CSS implementation. No Javascript.
* Accessible by default * Accessible by default
* RSS `/feed/rss` and Atom `/feed/atom` feeds * RSS `/rss` and Atom `/atom` feeds
* CSS uploads for custom theming * CSS uploads for custom theming
* Custom emoji to personalize moods (unicode only) * Custom emoji to personalize moods (unicode only)

View File

@ -104,7 +104,7 @@ class LogController extends Controller {
} }
private function parseLogLine(string $line): ?array { private function parseLogLine(string $line): ?array {
// Parse format: [2025-01-31 08:30:15] DEBUG: 192.168.1.100 [GET feed/rss] - message // Parse format: [2025-01-31 08:30:15] DEBUG: 192.168.1.100 [GET admin/settings] - message
$pattern = '/^\[([^\]]+)\] (\w+): ([^\s]+)(?:\s+\[([^\]]+)\])? - (.+)$/'; $pattern = '/^\[([^\]]+)\] (\w+): ([^\s]+)(?:\s+\[([^\]]+)\])? - (.+)$/';
if (preg_match($pattern, $line, $matches)) { if (preg_match($pattern, $line, $matches)) {

View File

@ -18,7 +18,7 @@ class AtomGenerator extends FeedGenerator {
Log::debug("Building Atom feed for " . $this->settings->siteTitle); Log::debug("Building Atom feed for " . $this->settings->siteTitle);
$feedTitle = Util::escape_xml($this->settings->siteTitle . " Atom Feed"); $feedTitle = Util::escape_xml($this->settings->siteTitle . " Atom Feed");
$siteUrl = Util::escape_xml(Util::buildUrl($this->settings->baseUrl, $this->settings->basePath)); $siteUrl = Util::escape_xml(Util::buildUrl($this->settings->baseUrl, $this->settings->basePath));
$feedUrl = Util::escape_xml(Util::buildUrl($this->settings->baseUrl, $this->settings->basePath, 'feed/atom')); $feedUrl = Util::escape_xml(Util::buildUrl($this->settings->baseUrl, $this->settings->basePath, 'atom'));
$updated = date(DATE_ATOM, strtotime($this->ticks[0]['timestamp'] ?? 'now')); $updated = date(DATE_ATOM, strtotime($this->ticks[0]['timestamp'] ?? 'now'));
ob_start(); ob_start();

View File

@ -23,7 +23,7 @@ class RssGenerator extends FeedGenerator {
<channel> <channel>
<title><?php echo Util::escape_xml($this->settings->siteTitle . ' RSS Feed') ?></title> <title><?php echo Util::escape_xml($this->settings->siteTitle . ' RSS Feed') ?></title>
<link><?php echo Util::escape_xml(Util::buildUrl($this->settings->baseUrl, $this->settings->basePath))?></link> <link><?php echo Util::escape_xml(Util::buildUrl($this->settings->baseUrl, $this->settings->basePath))?></link>
<atom:link href="<?php echo Util::escape_xml(Util::buildUrl($this->settings->baseUrl, $this->settings->basePath, 'feed/rss'))?>" <atom:link href="<?php echo Util::escape_xml(Util::buildUrl($this->settings->baseUrl, $this->settings->basePath, 'rss'))?>"
rel="self" rel="self"
type="application/rss+xml" /> type="application/rss+xml" />
<description><?php echo Util::escape_xml($this->settings->siteDescription) ?></description> <description><?php echo Util::escape_xml($this->settings->siteDescription) ?></description>

View File

@ -15,8 +15,8 @@ class Router {
['admin/emoji', 'EmojiController'], ['admin/emoji', 'EmojiController'],
['admin/emoji', 'EmojiController@handlePost', ['POST']], ['admin/emoji', 'EmojiController@handlePost', ['POST']],
['admin/logs', 'LogController'], ['admin/logs', 'LogController'],
['feed/rss', 'FeedController@rss'], ['rss', 'FeedController@rss'],
['feed/atom', 'FeedController@atom'], ['atom', 'FeedController@atom'],
['login', 'AuthController@showLogin'], ['login', 'AuthController@showLogin'],
['login', 'AuthController@handleLogin', ['POST']], ['login', 'AuthController@handleLogin', ['POST']],
['logout', 'AuthController@handleLogout', ['GET', 'POST']], ['logout', 'AuthController@handleLogout', ['GET', 'POST']],

View File

@ -19,11 +19,11 @@
<link rel="alternate" <link rel="alternate"
type="application/rss+xml" type="application/rss+xml"
title="<?php echo Util::escape_html($settings->siteTitle) ?> RSS Feed" title="<?php echo Util::escape_html($settings->siteTitle) ?> RSS Feed"
href="<?php echo Util::escape_html($settings->baseUrl . $settings->basePath)?>feed/rss/"> href="<?php echo Util::escape_html($settings->baseUrl . $settings->basePath)?>rss/">
<link rel="alternate" <link rel="alternate"
type="application/atom+xml" type="application/atom+xml"
title="<?php echo Util::escape_html($settings->siteTitle) ?> Atom Feed" title="<?php echo Util::escape_html($settings->siteTitle) ?> Atom Feed"
href="<?php echo Util::escape_html($settings->baseUrl . $settings->basePath)?>feed/atom/"> href="<?php echo Util::escape_html($settings->baseUrl . $settings->basePath)?>atom/">
</head> </head>
<body> <body>
<?php include TEMPLATES_DIR . '/partials/navbar.php'?> <?php include TEMPLATES_DIR . '/partials/navbar.php'?>

View File

@ -7,9 +7,9 @@
<summary aria-haspopup="true">feeds</summary> <summary aria-haspopup="true">feeds</summary>
<div class="dropdown-items"> <div class="dropdown-items">
<a <?php if($settings->strictAccessibility): ?>tabindex="0"<?php endif; ?> <a <?php if($settings->strictAccessibility): ?>tabindex="0"<?php endif; ?>
href="<?= Util::escape_html(Util::buildRelativeUrl($settings->basePath, 'feed/rss')) ?>">rss</a> href="<?= Util::escape_html(Util::buildRelativeUrl($settings->basePath, 'rss')) ?>">rss</a>
<a <?php if($settings->strictAccessibility): ?>tabindex="0"<?php endif; ?> <a <?php if($settings->strictAccessibility): ?>tabindex="0"<?php endif; ?>
href="<?= Util::escape_html(Util::buildRelativeUrl($settings->basePath, 'feed/atom')) ?>">atom</a> href="<?= Util::escape_html(Util::buildRelativeUrl($settings->basePath, 'atom')) ?>">atom</a>
</div> </div>
</details> </details>
<?php if (!Session::isLoggedIn()): ?> <?php if (!Session::isLoggedIn()): ?>

View File

@ -35,7 +35,7 @@ class AtomGeneratorTest extends TestCase
$this->assertStringContainsString('<title>Test Site Atom Feed</title>', $xml); $this->assertStringContainsString('<title>Test Site Atom Feed</title>', $xml);
$this->assertStringContainsString('<link rel="alternate" href="https://example.com/tkr/"/>', $xml); $this->assertStringContainsString('<link rel="alternate" href="https://example.com/tkr/"/>', $xml);
$this->assertStringContainsString('<link rel="self"', $xml); $this->assertStringContainsString('<link rel="self"', $xml);
$this->assertStringContainsString('href="https://example.com/tkr/feed/atom"', $xml); $this->assertStringContainsString('href="https://example.com/tkr/atom"', $xml);
$this->assertStringContainsString('<id>https://example.com/tkr/</id>', $xml); $this->assertStringContainsString('<id>https://example.com/tkr/</id>', $xml);
$this->assertStringContainsString('<author>', $xml); $this->assertStringContainsString('<author>', $xml);
$this->assertStringContainsString('<name>Test Site</name>', $xml); $this->assertStringContainsString('<name>Test Site</name>', $xml);
@ -69,7 +69,7 @@ class AtomGeneratorTest extends TestCase
$this->assertStringContainsString('<title>Test Site Atom Feed</title>', $xml); $this->assertStringContainsString('<title>Test Site Atom Feed</title>', $xml);
$this->assertStringContainsString('<link rel="alternate" href="https://example.com/tkr/"/>', $xml); $this->assertStringContainsString('<link rel="alternate" href="https://example.com/tkr/"/>', $xml);
$this->assertStringContainsString('<link rel="self"', $xml); $this->assertStringContainsString('<link rel="self"', $xml);
$this->assertStringContainsString('href="https://example.com/tkr/feed/atom"', $xml); $this->assertStringContainsString('href="https://example.com/tkr/atom"', $xml);
$this->assertStringContainsString('<id>https://example.com/tkr/</id>', $xml); $this->assertStringContainsString('<id>https://example.com/tkr/</id>', $xml);
$this->assertStringContainsString('<author>', $xml); $this->assertStringContainsString('<author>', $xml);
$this->assertStringContainsString('<name>Test Site</name>', $xml); $this->assertStringContainsString('<name>Test Site</name>', $xml);

View File

@ -34,7 +34,7 @@ class RssGeneratorTest extends TestCase
$this->assertStringContainsString('<rss version="2.0"', $xml); $this->assertStringContainsString('<rss version="2.0"', $xml);
$this->assertStringContainsString('<title>Test Site RSS Feed</title>', $xml); $this->assertStringContainsString('<title>Test Site RSS Feed</title>', $xml);
$this->assertStringContainsString('<link>https://example.com/tkr/</link>', $xml); $this->assertStringContainsString('<link>https://example.com/tkr/</link>', $xml);
$this->assertStringContainsString('<atom:link href="https://example.com/tkr/feed/rss"', $xml); $this->assertStringContainsString('<atom:link href="https://example.com/tkr/rss"', $xml);
$this->assertStringContainsString('<channel>', $xml); $this->assertStringContainsString('<channel>', $xml);
$this->assertStringContainsString('<item>', $xml); $this->assertStringContainsString('<item>', $xml);
$this->assertStringContainsString('</item>', $xml); $this->assertStringContainsString('</item>', $xml);
@ -66,7 +66,7 @@ class RssGeneratorTest extends TestCase
$this->assertStringContainsString('<rss version="2.0"', $xml); $this->assertStringContainsString('<rss version="2.0"', $xml);
$this->assertStringContainsString('<title>Test Site RSS Feed</title>', $xml); $this->assertStringContainsString('<title>Test Site RSS Feed</title>', $xml);
$this->assertStringContainsString('<link>https://example.com/tkr/</link>', $xml); $this->assertStringContainsString('<link>https://example.com/tkr/</link>', $xml);
$this->assertStringContainsString('<atom:link href="https://example.com/tkr/feed/rss"', $xml); $this->assertStringContainsString('<atom:link href="https://example.com/tkr/rss"', $xml);
$this->assertStringContainsString('<channel>', $xml); $this->assertStringContainsString('<channel>', $xml);
$this->assertStringContainsString('</channel>', $xml); $this->assertStringContainsString('</channel>', $xml);
$this->assertStringEndsWith('</rss>' . "\n", $xml); $this->assertStringEndsWith('</rss>' . "\n", $xml);