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

Implementation

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`
Done

The bake command has generated this code:


declare(strict_types=1);
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);

        $this->set(compact('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="http://www.w3.org/2005/Atom">' . "\n";
echo '<channel>' . "\n";
echo '<title>logikfabrik.com RSS</title>' . "\n";
echo '<description>your relevant knowhow</description>' . "\n";
echo '<atom:link href="https://www.logikfabrik.com/k/rss" rel="self" type="application/rss+xml" />' ."\n";
echo '<link>https://www.logikfabrik.com</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>https://www.logikfabrik.com/k/entries/view/' . $r['id'] . '</link>' . "\n";
  echo '<guid>https://www.logikfabrik.com/k/entries/view/' . $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 https://validator.w3.org/feed/

Tag: cakephp4

Previous Chapter: Creating a Sitemap for SEO

Next Chapter: Building Adminstrative Functionality