]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
RSS/ATOM feeds: process through Slim controller
authorArthurHoaro <arthur@hoa.ro>
Mon, 18 May 2020 15:17:36 +0000 (17:17 +0200)
committerArthurHoaro <arthur@hoa.ro>
Thu, 23 Jul 2020 19:19:21 +0000 (21:19 +0200)
16 files changed:
application/container/ContainerBuilder.php
application/container/ShaarliContainer.php
application/feed/FeedBuilder.php
application/front/controllers/FeedController.php [new file with mode: 0644]
application/front/controllers/ShaarliController.php
doc/md/RSS-feeds.md
index.php
plugins/pubsubhubbub/pubsubhubbub.php
tests/feed/CachedPageTest.php
tests/front/controller/FeedControllerTest.php [new file with mode: 0644]
tpl/default/includes.html
tpl/default/opensearch.html
tpl/default/page.header.html
tpl/vintage/includes.html
tpl/vintage/opensearch.html
tpl/vintage/page.header.html

index 199f3f67303c2d0e93a5727ea2af275c7a876e6f..84406979296e3a94d5a87af5645d38eb4ad96198 100644 (file)
@@ -7,6 +7,7 @@ namespace Shaarli\Container;
 use Shaarli\Bookmark\BookmarkFileService;
 use Shaarli\Bookmark\BookmarkServiceInterface;
 use Shaarli\Config\ConfigManager;
+use Shaarli\Feed\FeedBuilder;
 use Shaarli\Formatter\FormatterFactory;
 use Shaarli\History;
 use Shaarli\Plugin\PluginManager;
@@ -100,6 +101,15 @@ class ContainerBuilder
             );
         };
 
+        $container['feedBuilder'] = function (ShaarliContainer $container): FeedBuilder {
+            return new FeedBuilder(
+                $container->bookmarkService,
+                $container->formatterFactory->getFormatter(),
+                $container->environment,
+                $container->loginManager->isLoggedIn()
+            );
+        };
+
         return $container;
     }
 }
index 3995f669ca3815a01c3765a6fc94f988cbfd1744..deb071970a41a6872a0c87ca9ccffc6bccb04bd0 100644 (file)
@@ -6,6 +6,7 @@ namespace Shaarli\Container;
 
 use Shaarli\Bookmark\BookmarkServiceInterface;
 use Shaarli\Config\ConfigManager;
+use Shaarli\Feed\FeedBuilder;
 use Shaarli\Formatter\FormatterFactory;
 use Shaarli\History;
 use Shaarli\Plugin\PluginManager;
@@ -29,6 +30,7 @@ use Slim\Container;
  * @property PluginManager            $pluginManager
  * @property FormatterFactory         $formatterFactory
  * @property PageCacheManager         $pageCacheManager
+ * @property FeedBuilder              $feedBuilder
  */
 class ShaarliContainer extends Container
 {
index bcf27c2c77826a22bed51adc38f27d538a086ad7..c97ae1ea0e67ef83682379d8d3885b00ed3d79f6 100644 (file)
@@ -78,7 +78,7 @@ class FeedBuilder
      * @param array                    $serverInfo $_SERVER.
      * @param boolean                  $isLoggedIn True if the user is currently logged in, false otherwise.
      */
-    public function __construct($linkDB, $formatter, array $serverInfo, $isLoggedIn)
+    public function __construct($linkDB, $formatter, $serverInfo, $isLoggedIn)
     {
         $this->linkDB = $linkDB;
         $this->formatter = $formatter;
diff --git a/application/front/controllers/FeedController.php b/application/front/controllers/FeedController.php
new file mode 100644 (file)
index 0000000..78d826d
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Shaarli\Front\Controller;
+
+use Shaarli\Feed\FeedBuilder;
+use Slim\Http\Request;
+use Slim\Http\Response;
+
+/**
+ * Class FeedController
+ *
+ * Slim controller handling ATOM and RSS feed.
+ *
+ * @package Front\Controller
+ */
+class FeedController extends ShaarliController
+{
+    public function atom(Request $request, Response $response): Response
+    {
+        return $this->processRequest(FeedBuilder::$FEED_ATOM, $request, $response);
+    }
+
+    public function rss(Request $request, Response $response): Response
+    {
+        return $this->processRequest(FeedBuilder::$FEED_RSS, $request, $response);
+    }
+
+    protected function processRequest(string $feedType, Request $request, Response $response): Response
+    {
+        $response = $response->withHeader('Content-Type', 'application/'. $feedType .'+xml; charset=utf-8');
+
+        $pageUrl = page_url($this->container->environment);
+        $cache = $this->container->pageCacheManager->getCachePage($pageUrl);
+
+        $cached = $cache->cachedVersion();
+        if (!empty($cached)) {
+            return $response->write($cached);
+        }
+
+        // Generate data.
+        $this->container->feedBuilder->setLocale(strtolower(setlocale(LC_COLLATE, 0)));
+        $this->container->feedBuilder->setHideDates($this->container->conf->get('privacy.hide_timestamps', false));
+        $this->container->feedBuilder->setUsePermalinks(
+            null !== $request->getParam('permalinks') || !$this->container->conf->get('feed.rss_permalinks')
+        );
+
+        $data = $this->container->feedBuilder->buildData($feedType, $request->getParams());
+
+        $this->executeHooks($data, $feedType);
+        $this->assignAllView($data);
+
+        $content = $this->render('feed.'. $feedType);
+
+        $cache->cache($content);
+
+        return $response->write($content);
+    }
+
+    /**
+     * @param mixed[] $data Template data
+     *
+     * @return mixed[] Template data after active plugins hook execution.
+     */
+    protected function executeHooks(array $data, string $feedType): array
+    {
+        $this->container->pluginManager->executeHooks(
+            'render_feed',
+            $data,
+            [
+                'loggedin' => $this->container->loginManager->isLoggedIn(),
+                'target' => $feedType,
+            ]
+        );
+
+        return $data;
+    }
+}
index 2b8285887fa421d130d99347fe8e878b84244dff..0c5d363e0ea594f295cc855f01d6fff795a18acb 100644 (file)
@@ -30,6 +30,20 @@ abstract class ShaarliController
         return $this;
     }
 
+    /**
+     * Assign variables to RainTPL template through the PageBuilder.
+     *
+     * @param mixed $data Values to assign to the template and their keys
+     */
+    protected function assignAllView(array $data): self
+    {
+        foreach ($data as $key => $value) {
+            $this->assignView($key, $value);
+        }
+
+        return $this;
+    }
+
     protected function render(string $template): string
     {
         $this->assignView('linkcount', $this->container->bookmarkService->count(BookmarkFilter::$ALL));
index 71f4d7eeff39d7fd88825f4283493f415d6637c6..cdfb8c7857db7562a6b6634ec60cd54eb2d9e7b7 100644 (file)
@@ -1,14 +1,14 @@
 ### Feeds options
 
-Feeds are available in ATOM with `?do=atom` and RSS with `do=RSS`.
+Feeds are available in ATOM with `/feed-atom` and RSS with `/feed-rss`.
 
 Options:
 
 - You can use `permalinks` in the feed URL to get permalink to Shaares instead of direct link to shaared URL.
-    - E.G. `https://my.shaarli.domain/?do=atom&permalinks`.
+    - E.G. `https://my.shaarli.domain/feed-atom?permalinks`.
 - You can use `nb` parameter in the feed URL to specify the number of Shaares you want in a feed (default if not specified: `50`). The keyword `all` is available if you want everything.
-    - `https://my.shaarli.domain/?do=atom&permalinks&nb=42`
-    - `https://my.shaarli.domain/?do=atom&permalinks&nb=all`
+    - `https://my.shaarli.domain/feed-atom?permalinks&nb=42`
+    - `https://my.shaarli.domain/feed-atom?permalinks&nb=all`
 
 ### RSS Feeds or Picture Wall for a specific search/tag
 
index 980e77044d9aabcaadfb9ad9c7fe56e560597118..c3e0a5bf9c6a131bbcc2f631b7ecc8b235d76877 100644 (file)
--- a/index.php
+++ b/index.php
@@ -432,45 +432,8 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM
     // ATOM and RSS feed.
     if ($targetPage == Router::$PAGE_FEED_ATOM || $targetPage == Router::$PAGE_FEED_RSS) {
         $feedType = $targetPage == Router::$PAGE_FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM;
-        header('Content-Type: application/'. $feedType .'+xml; charset=utf-8');
-
-        // Cache system
-        $query = $_SERVER['QUERY_STRING'];
-        $cache = new CachedPage(
-            $conf->get('resource.page_cache'),
-            page_url($_SERVER),
-            startsWith($query, 'do='. $targetPage) && !$loginManager->isLoggedIn()
-        );
-        $cached = $cache->cachedVersion();
-        if (!empty($cached)) {
-            echo $cached;
-            exit;
-        }
 
-        $factory = new FormatterFactory($conf, $loginManager->isLoggedIn());
-        // Generate data.
-        $feedGenerator = new FeedBuilder(
-            $bookmarkService,
-            $factory->getFormatter(),
-            $_SERVER,
-            $loginManager->isLoggedIn()
-        );
-        $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0)));
-        $feedGenerator->setHideDates($conf->get('privacy.hide_timestamps') && !$loginManager->isLoggedIn());
-        $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$conf->get('feed.rss_permalinks'));
-        $data = $feedGenerator->buildData($feedType, $_GET);
-
-        // Process plugin hook.
-        $pluginManager->executeHooks('render_feed', $data, array(
-            'loggedin' => $loginManager->isLoggedIn(),
-            'target' => $targetPage,
-        ));
-
-        // Render the template.
-        $PAGE->assignAll($data);
-        $PAGE->renderPage('feed.'. $feedType);
-        $cache->cache(ob_get_contents());
-        ob_end_flush();
+        header('Location: ./feed-'. $feedType .'?'. http_build_query($_GET));
         exit;
     }
 
@@ -1610,6 +1573,8 @@ $app->group('', function () {
     $this->get('/tag-list', '\Shaarli\Front\Controller\TagCloudController:list')->setName('taglist');
     $this->get('/daily', '\Shaarli\Front\Controller\DailyController:index')->setName('daily');
     $this->get('/daily-rss', '\Shaarli\Front\Controller\DailyController:rss')->setName('dailyrss');
+    $this->get('/feed-atom', '\Shaarli\Front\Controller\FeedController:atom')->setName('feedatom');
+    $this->get('/feed-rss', '\Shaarli\Front\Controller\FeedController:rss')->setName('feedrss');
 
     $this->get('/add-tag/{newTag}', '\Shaarli\Front\Controller\TagController:addTag')->setName('add-tag');
 })->add('\Shaarli\Front\ShaarliMiddleware');
index 2878c0505be296b486ab2b9ee4547a2851c7986b..41634dda50ba7f2d6877dd68c142de0f7191dda7 100644 (file)
@@ -60,8 +60,8 @@ function hook_pubsubhubbub_render_feed($data, $conf)
 function hook_pubsubhubbub_save_link($data, $conf)
 {
     $feeds = array(
-        index_url($_SERVER) .'?do=atom',
-        index_url($_SERVER) .'?do=rss',
+        index_url($_SERVER) .'feed-atom',
+        index_url($_SERVER) .'feed-rss',
     );
 
     $httpPost = function_exists('curl_version') ? false : 'nocurl_http_post';
index 363028a2dae3ba4779a197ec58a031f76a45382d..57f3b09be8ebcbc552b9a8e0fed455f9e90b878c 100644 (file)
@@ -11,7 +11,7 @@ class CachedPageTest extends \PHPUnit\Framework\TestCase
 {
     // test cache directory
     protected static $testCacheDir = 'sandbox/pagecache';
-    protected static $url = 'http://shaar.li/?do=atom';
+    protected static $url = 'http://shaar.li/feed-atom';
     protected static $filename;
 
     /**
@@ -42,8 +42,8 @@ class CachedPageTest extends \PHPUnit\Framework\TestCase
     {
         new CachedPage(self::$testCacheDir, '', true);
         new CachedPage(self::$testCacheDir, '', false);
-        new CachedPage(self::$testCacheDir, 'http://shaar.li/?do=rss', true);
-        new CachedPage(self::$testCacheDir, 'http://shaar.li/?do=atom', false);
+        new CachedPage(self::$testCacheDir, 'http://shaar.li/feed-rss', true);
+        new CachedPage(self::$testCacheDir, 'http://shaar.li/feed-atom', false);
         $this->addToAssertionCount(1);
     }
 
diff --git a/tests/front/controller/FeedControllerTest.php b/tests/front/controller/FeedControllerTest.php
new file mode 100644 (file)
index 0000000..d4cc553
--- /dev/null
@@ -0,0 +1,219 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Shaarli\Front\Controller;
+
+use PHPUnit\Framework\TestCase;
+use Shaarli\Bookmark\BookmarkServiceInterface;
+use Shaarli\Config\ConfigManager;
+use Shaarli\Container\ShaarliContainer;
+use Shaarli\Feed\FeedBuilder;
+use Shaarli\Formatter\FormatterFactory;
+use Shaarli\Plugin\PluginManager;
+use Shaarli\Render\PageBuilder;
+use Shaarli\Render\PageCacheManager;
+use Shaarli\Security\LoginManager;
+use Slim\Http\Request;
+use Slim\Http\Response;
+
+class FeedControllerTest extends TestCase
+{
+    /** @var ShaarliContainer */
+    protected $container;
+
+    /** @var FeedController */
+    protected $controller;
+
+    public function setUp(): void
+    {
+        $this->container = $this->createMock(ShaarliContainer::class);
+        $this->controller = new FeedController($this->container);
+    }
+
+    /**
+     * Feed Controller - RSS default behaviour
+     */
+    public function testDefaultRssController(): void
+    {
+        $this->createValidContainerMockSet();
+
+        $request = $this->createMock(Request::class);
+        $response = new Response();
+
+        $this->container->feedBuilder->expects(static::once())->method('setLocale');
+        $this->container->feedBuilder->expects(static::once())->method('setHideDates')->with(false);
+        $this->container->feedBuilder->expects(static::once())->method('setUsePermalinks')->with(true);
+
+        // Save RainTPL assigned variables
+        $assignedVariables = [];
+        $this->assignTemplateVars($assignedVariables);
+
+        $this->container->feedBuilder->method('buildData')->willReturn(['content' => 'data']);
+
+        // Make sure that PluginManager hook is triggered
+        $this->container->pluginManager
+            ->expects(static::at(0))
+            ->method('executeHooks')
+            ->willReturnCallback(function (string $hook, array $data, array $param): void {
+                static::assertSame('render_feed', $hook);
+                static::assertSame('data', $data['content']);
+
+                static::assertArrayHasKey('loggedin', $param);
+                static::assertSame('rss', $param['target']);
+            })
+        ;
+
+        $result = $this->controller->rss($request, $response);
+
+        static::assertSame(200, $result->getStatusCode());
+        static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]);
+        static::assertSame('feed.rss', (string) $result->getBody());
+        static::assertSame('data', $assignedVariables['content']);
+    }
+
+    /**
+     * Feed Controller - ATOM default behaviour
+     */
+    public function testDefaultAtomController(): void
+    {
+        $this->createValidContainerMockSet();
+
+        $request = $this->createMock(Request::class);
+        $response = new Response();
+
+        $this->container->feedBuilder->expects(static::once())->method('setLocale');
+        $this->container->feedBuilder->expects(static::once())->method('setHideDates')->with(false);
+        $this->container->feedBuilder->expects(static::once())->method('setUsePermalinks')->with(true);
+
+        // Save RainTPL assigned variables
+        $assignedVariables = [];
+        $this->assignTemplateVars($assignedVariables);
+
+        $this->container->feedBuilder->method('buildData')->willReturn(['content' => 'data']);
+
+        // Make sure that PluginManager hook is triggered
+        $this->container->pluginManager
+            ->expects(static::at(0))
+            ->method('executeHooks')
+            ->willReturnCallback(function (string $hook, array $data, array $param): void {
+                static::assertSame('render_feed', $hook);
+                static::assertSame('data', $data['content']);
+
+                static::assertArrayHasKey('loggedin', $param);
+                static::assertSame('atom', $param['target']);
+            })
+        ;
+
+        $result = $this->controller->atom($request, $response);
+
+        static::assertSame(200, $result->getStatusCode());
+        static::assertStringContainsString('application/atom', $result->getHeader('Content-Type')[0]);
+        static::assertSame('feed.atom', (string) $result->getBody());
+        static::assertSame('data', $assignedVariables['content']);
+    }
+
+    /**
+     * Feed Controller - ATOM with parameters
+     */
+    public function testAtomControllerWithParameters(): void
+    {
+        $this->createValidContainerMockSet();
+
+        $request = $this->createMock(Request::class);
+        $request->method('getParams')->willReturn(['parameter' => 'value']);
+        $response = new Response();
+
+        // Save RainTPL assigned variables
+        $assignedVariables = [];
+        $this->assignTemplateVars($assignedVariables);
+
+        $this->container->feedBuilder
+            ->method('buildData')
+            ->with('atom', ['parameter' => 'value'])
+            ->willReturn(['content' => 'data'])
+        ;
+
+        // Make sure that PluginManager hook is triggered
+        $this->container->pluginManager
+            ->expects(static::at(0))
+            ->method('executeHooks')
+            ->willReturnCallback(function (string $hook, array $data, array $param): void {
+                static::assertSame('render_feed', $hook);
+                static::assertSame('data', $data['content']);
+
+                static::assertArrayHasKey('loggedin', $param);
+                static::assertSame('atom', $param['target']);
+            })
+        ;
+
+        $result = $this->controller->atom($request, $response);
+
+        static::assertSame(200, $result->getStatusCode());
+        static::assertStringContainsString('application/atom', $result->getHeader('Content-Type')[0]);
+        static::assertSame('feed.atom', (string) $result->getBody());
+        static::assertSame('data', $assignedVariables['content']);
+    }
+
+    protected function createValidContainerMockSet(): void
+    {
+        $loginManager = $this->createMock(LoginManager::class);
+        $this->container->loginManager = $loginManager;
+
+        // Config
+        $conf = $this->createMock(ConfigManager::class);
+        $this->container->conf = $conf;
+        $this->container->conf->method('get')->willReturnCallback(function (string $parameter, $default) {
+            return $default;
+        });
+
+        // PageBuilder
+        $pageBuilder = $this->createMock(PageBuilder::class);
+        $pageBuilder
+            ->method('render')
+            ->willReturnCallback(function (string $template): string {
+                return $template;
+            })
+        ;
+        $this->container->pageBuilder = $pageBuilder;
+
+        $bookmarkService = $this->createMock(BookmarkServiceInterface::class);
+        $this->container->bookmarkService = $bookmarkService;
+
+        // Plugin Manager
+        $pluginManager = $this->createMock(PluginManager::class);
+        $this->container->pluginManager = $pluginManager;
+
+        // Formatter
+        $formatterFactory = $this->createMock(FormatterFactory::class);
+        $this->container->formatterFactory = $formatterFactory;
+
+        // CacheManager
+        $pageCacheManager = $this->createMock(PageCacheManager::class);
+        $this->container->pageCacheManager = $pageCacheManager;
+
+        // FeedBuilder
+        $feedBuilder = $this->createMock(FeedBuilder::class);
+        $this->container->feedBuilder = $feedBuilder;
+
+        // $_SERVER
+        $this->container->environment = [
+            'SERVER_NAME' => 'shaarli',
+            'SERVER_PORT' => '80',
+            'REQUEST_URI' => '/daily-rss',
+        ];
+    }
+
+    protected function assignTemplateVars(array &$variables): void
+    {
+        $this->container->pageBuilder
+            ->expects(static::atLeastOnce())
+            ->method('assign')
+            ->willReturnCallback(function ($key, $value) use (&$variables) {
+                $variables[$key] = $value;
+
+                return $this;
+            })
+        ;
+    }
+}
index 3e7d63208bf5b77689ed38d7eea821c02f996248..cdbfeea1962fa49bd052663167692f5ed8487884 100644 (file)
@@ -3,8 +3,8 @@
 <meta name="format-detection" content="telephone=no" />
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <meta name="referrer" content="same-origin">
-<link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}#" title="ATOM Feed" />
-<link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" />
+<link rel="alternate" type="application/atom+xml" href="{$feedurl}feed-atom?{$searchcrits}#" title="ATOM Feed" />
+<link rel="alternate" type="application/rss+xml" href="{$feedurl}feed-rss?{$searchcrits}#" title="RSS Feed" />
 <link href="img/favicon.png" rel="shortcut icon" type="image/png" />
 <link href="img/apple-touch-icon.png" rel="apple-touch-icon" sizes="180x180" />
 <link type="text/css" rel="stylesheet" href="css/shaarli.min.css?v={$version_hash}" />
index 3fcc30b74fdc2bc150687dcabc12f89b62222c54..5774d38dfc491f3453f6cd649da578d420b6172b 100644 (file)
@@ -3,8 +3,8 @@
     <ShortName>Shaarli search - {$pagetitle}</ShortName>
     <Description>Shaarli search - {$pagetitle}</Description>
     <Url type="text/html" template="{$serverurl}?searchterm={searchTerms}" />
-    <Url type="application/atom+xml" template="{$serverurl}?do=atom&amp;searchterm={searchTerms}"/>
-    <Url type="application/rss+xml" template="{$serverurl}?do=rss&amp;searchterm={searchTerms}"/>
+    <Url type="application/atom+xml" template="{$serverurl}feed-atom?searchterm={searchTerms}"/>
+    <Url type="application/rss+xml" template="{$serverurl}feed-rss?searchterm={searchTerms}"/>
     <InputEncoding>UTF-8</InputEncoding>
     <Developer>Shaarli Community - https://github.com/shaarli/Shaarli/</Developer>
     <Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAHRklE
index 6b686580c44652a7904fb5657724c36066a9512a..2d015b264253b966399bbe35b896d29d5c6fc95d 100644 (file)
@@ -52,7 +52,7 @@
           </li>
         {/loop}
         <li class="pure-menu-item pure-u-lg-0 shaarli-menu-mobile" id="shaarli-menu-mobile-rss">
-            <a href="./?do={$feed_type}{$searchcrits}" class="pure-menu-link">{'RSS Feed'|t}</a>
+            <a href="./feed-{$feed_type}?{$searchcrits}" class="pure-menu-link">{'RSS Feed'|t}</a>
         </li>
         {if="$is_logged_in"}
           <li class="pure-menu-item pure-u-lg-0 shaarli-menu-mobile" id="shaarli-menu-mobile-logout">
@@ -74,7 +74,7 @@
             </a>
           </li>
           <li class="pure-menu-item" id="shaarli-menu-desktop-rss">
-            <a href="./?do={$feed_type}{$searchcrits}" class="pure-menu-link" title="{'RSS Feed'|t}" aria-label="{'RSS Feed'|t}">
+            <a href="./feed-{$feed_type}?{$searchcrits}" class="pure-menu-link" title="{'RSS Feed'|t}" aria-label="{'RSS Feed'|t}">
               <i class="fa fa-rss" aria-hidden="true"></i>
             </a>
           </li>
index d77ce497b65cd04b44429e7553ac2e53ad3aa25a..cf56ca6103811d3b84ae44fbcce1281a56a82028 100644 (file)
@@ -3,8 +3,8 @@
 <meta name="format-detection" content="telephone=no" />
 <meta name="viewport" content="width=device-width,initial-scale=1.0" />
 <meta name="referrer" content="same-origin">
-<link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" />
-<link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}#" title="ATOM Feed" />
+<link rel="alternate" type="application/rss+xml" href="{$feedurl}feed-rss?{$searchcrits}#" title="RSS Feed" />
+<link rel="alternate" type="application/atom+xml" href="{$feedurl}feed-atom?{$searchcrits}#" title="ATOM Feed" />
 <link href="img/favicon.ico" rel="shortcut icon" type="image/x-icon" />
 <link type="text/css" rel="stylesheet" href="css/shaarli.min.css" />
 {if="$formatter==='markdown'"}
index 3fcc30b74fdc2bc150687dcabc12f89b62222c54..5774d38dfc491f3453f6cd649da578d420b6172b 100644 (file)
@@ -3,8 +3,8 @@
     <ShortName>Shaarli search - {$pagetitle}</ShortName>
     <Description>Shaarli search - {$pagetitle}</Description>
     <Url type="text/html" template="{$serverurl}?searchterm={searchTerms}" />
-    <Url type="application/atom+xml" template="{$serverurl}?do=atom&amp;searchterm={searchTerms}"/>
-    <Url type="application/rss+xml" template="{$serverurl}?do=rss&amp;searchterm={searchTerms}"/>
+    <Url type="application/atom+xml" template="{$serverurl}feed-atom?searchterm={searchTerms}"/>
+    <Url type="application/rss+xml" template="{$serverurl}feed-rss?searchterm={searchTerms}"/>
     <InputEncoding>UTF-8</InputEncoding>
     <Developer>Shaarli Community - https://github.com/shaarli/Shaarli/</Developer>
     <Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAHRklE
index d945155592902d4e50f0f2ed414aaf1ce83cc8c8..0a8392b64a3537a1d7703dfee7174698cf977ea9 100644 (file)
@@ -27,9 +27,9 @@
     {else}
     <li><a href="./login">Login</a></li>
     {/if}
-    <li><a href="{$feedurl}?do=rss{$searchcrits}" class="nomobile">RSS Feed</a></li>
+    <li><a href="{$feedurl}/feed-rss?{$searchcrits}" class="nomobile">RSS Feed</a></li>
     {if="$showatom"}
-    <li><a href="{$feedurl}?do=atom{$searchcrits}" class="nomobile">ATOM Feed</a></li>
+    <li><a href="{$feedurl}/feed-atom?{$searchcrits}" class="nomobile">ATOM Feed</a></li>
     {/if}
     <li><a href="./tag-cloud">Tag cloud</a></li>
     <li><a href="./picture-wall{function="ltrim($searchcrits, '&')"}">Picture wall</a></li>