Next Chapter: Building Adminstrative Functionality

CakePHP 4: Building a RSS Feed

2019-05-18 18:10:11+00

User Story RSS Feed

I as a end user want to get the latest knowledge entries as a link in my newsfeed reader in order to be up-to-date with the latest topics.

Acceptance Criteria

  • public entries are listed in a rss feed.
  • the latest 40 public entries ordered by modified date listed
  • External Feed validators proof that the feed is valid


There are various steps necessary in order to implement a rss feed. These steps include:

  1. Define a layout
  2. Define a controller
  3. Define a view
  4. Define the routing

Define a Layout for the RSS Feed

Open a new file in ../templates/layout/rss.php.

In the rss.php file there will be the following content

<?php echo $this->fetch('content');

Define a Controller

To kickstart the development we use bake to create a skeleton of the controller.

bin/cake bake controller rss --actions index --no-actions
Baking controller class for Rss...

Wrote `.../lfcakephp4/src/Controller/RssController.php`
Bake is detecting possible fixtures...

Baking test case for App\Controller\RssController ...
Wrote `.../lfcakephp4/tests/TestCase/Controller/RssControllerTest.php`

The bake command has generated this code:

namespace App\Controller;

 * Rss Controller
 * @method \App\Model\Entity\Rs[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
class RssController extends AppController
     * Index method
     * @return \Cake\Http\Response|null
    public function index()
        $rss = $this->paginate($this->Rss);


We will extend the index function as follows.

   public function index()
        // define the sql to get the data
        $q = "select id, modified, etyp, etitle,etag2, eurl, etext";
        $q.= " from entry";
        $q.= " order by modified desc limit 40";

        // connect to the database and get the data
        $conn = ConnectionManager::get('default');
        $rset = $conn->execute($q)->fetchAll('assoc');

        // return the data to the view
        $this->response = $this->response->withType('xml');
        $this->set('rset', $rset);

In the header of the controller file we need to include various libraries.

namespace App\Controller;

use Cake\Datasource\ConnectionManager;
use Cake\Utility\Text;
use Cake\Http\Response;

Defining the view

The view file ../template/Rss/index.php should look as follows.

// set layout in templates/layout/
$this->layout = 'rss';
use Cake\Utility\Text;

echo '<rss version="2.0" xmlns:atom="">' . "\n";
echo '<channel>' . "\n";
echo '<title> RSS</title>' . "\n";
echo '<description>your relevant knowhow</description>' . "\n";
echo '<atom:link href="" rel="self" type="application/rss+xml" />' ."\n";
echo '<link></link>' . "\n";
echo '<lastBuildDate>' . gmdate('D, d M Y H:i:s +0000'). '</lastBuildDate>' . "\n";
echo '<ttl>1800</ttl>'."\n";

foreach ($rset as $r) {
  $body = htmlspecialchars($this->Text->truncate(strip_tags($r['etext']), 140, 
         [ 'ending' => '...','exact'  => true, 'html'   => true,]),ENT_QUOTES);
  echo "\n". '<item>';
  echo '<title>' . htmlspecialchars ($r['etitle'],ENT_QUOTES) . '</title>' . "\n";
  echo '<description>' . $body . '</description>' . "\n";
  echo '<link>' . $r['id'] . '</link>' . "\n";
  echo '<guid>' . $r['id'] . '</guid>' . "\n";
  echo '<pubDate>'.  date('D, d M Y H:i:s +0000',strtotime($r['modified'])) . '</pubDate>' . "\n";
  echo '</item>';

echo "\n" . '</channel>' ."\n";
echo '</rss>';

Adjusting the Routes

In the routes file there is the connection between URL and controller/actions defined. The following entry will support our RSS feed:

    $routes->connect('/rss/*',  ['controller' => 'Rss',  'action' => 'index']);

Quality Testing the RSS Feed

To assess if the results are valid we use an rss checker such as

Tag: cakephp4

Previous Chapter: Creating a Sitemap for SEO

Next Chapter: Building Adminstrative Functionality