CakePHP: RSS feeds

21.feb 2008 Envía un trackback

Una feature básica para cualquier web dospuntocero es la sindicación de contenidos. Resumiendo muy mucho podemos decir que se trata de un formato de redifusión de contenidos capaz de ser interpretado por clientes o lectores de feeds.

Dentro de un desarrollo con CakePHP (1.2 beta) crear el rss de un modelo es muy sencillo, se resume en cuatro pasos básicos.

1.- Habilitamos parseExtensions

Habilitamos esta opción para que el dispatcher se entere cuando alguien pida un .rss. Lo hacemos en el archivo app/config/routes.php:
Router::parseExtensions('rss');
 

2.- Usamos el componente requestHandler

El siguiente paso es mirar en el controlador si la url es o no un .rss para formatear los datos de una forma u otra, esto lo hacemos mediante el componente requestHandler que tendremos que activar previamente -en el controlador que nos interese o para toda la webapp en app/app_controller.php- de la siguiente forma:
var $components = array('RequestHandler');
 

3.- Controlador

Una vez habilitado requestHandler vamos al controlador correspondiente para condicionar la vista según sea o no un rss lo que se pide. En este caso dentro de la función index() del controlador, la condición sería así:
$isFeed = ife($this->RequestHandler->prefers('rss') == 'rss', true, false);
 
Particularmente esta última condición no funcionó en mi app, imagino que debido a los cambios que está sufriendo la versión 1.2-beta. Con un par de debugs y algo de paciencia he retocado el código tal que:
$isFeed = ife($this->RequestHandler->__renderType == 'rss', true, false);
 
Ahora dependiendo de si $isFeed es true ó false haremos una cosa u otra, pasteo la función entera para que se entienda mejor:
function index()
{
        $this->Post->recursive = 1;
       
        $isFeed = ife($this->RequestHandler->__renderType == 'rss', true, false);

        if($isFeed)
        {
                $settings=Configure::read('Settings');
                $feeds=Configure::read('Feeds');
                $this->layout = 'default';
                $this->set('channel', array (
                                'title' => $feeds['title'],
                                'description' => $feeds['description'],
                                'link' => $feeds['url'],
                                'managingEditor' => $settings['email'].' ('.$settings['author'].')',
                                'webMaster' => $settings['email'].' ('.$settings['author'].')',
                                'generator' => $settings['title'].' ('.$settings['version'].')'
                ));
                $this->set('posts', $this->Post->find('all', array('Post.status'=>1, 'order'=>'Post.created DESC', 'limit' => 15)));
        }
        else
        {
                $this->layout = Configure::read('Settings.theme');
                $this->set('posts', $this->paginate('Post', array('Post.status'=>1)));
        }
}
 
Como puede verse algunas variables dentro del array channel las tengo guardadas en config/config.php, pero eso ya es cuestión de organización, valdría perfectamente un array como este:
$this->set('channel', array (
                'title' => 'Mi aplicación web - feeds',
                'description' => 'Sindicación de contenidos de MiWeb2.0',
                'link' => 'http://miweb2.0.com',
                'managingEditor' => 'r0sk@userlinux.net (Yo Mismo)',
                'webMaster' => 'r0sk@userlinux.net (Yo Mismo)',
                'generator' => 'MiWeb2.0'
));
 

4.- Vista

Para la vista crearemos un directorio rss/ dentro de views. En este caso, como estamos intentando agregar sindicación al modelo de Posts la ruta completa sería views/posts/rss/index.ctp. Fijaos que en el controlador hemos puesto $this->layout = 'default';, CakePHP es lo suficientemente inteligente como para mirar dentro del directorio rss/. El código de la vista sería similar al siguiente:
echo $rss->items($posts, 'transformRSS');

function transformRSS($data)
{
        if($data['Tag']) { $category = Set::extract($data,'Tag.{n}.slug');$maincat = $category[0]; }
        if(!isset($maincat) OR !$maincat) $maincat="blog";
       
        return array(
                'title' => $data['Post']['title'],
                'link'  => '/posts/view/'.$data['Post']['slug'],
                'guid'  => '/posts/view/'.$data['Post']['slug'],
                'category' => $maincat,
                'description' => $data['Post']['content'].' '.$data['Post']['content_more'],
                'author' => $data['User']['email']. '('.$data['User']['name'].')',
                'pubDate' => $data['Post']['modified']
        );
}
 
Ojo, que yo he hecho una pequeña pirula (las dos condiciones antes del array) para rellenar category con los Tags, pero no haría falta. El código se entiende por si mismo.

5.- Accediendo al rss

Ahora que tenemos la programación a punto solo hemos de entrar a la url que nos dará acceso a la sindicación. En este caso como se trata del modelo Posts lo haremos desde http://webapp/posts/index.rss.

El último paso podría ser la validación del formato, es posible que se nos haya pasado algo por retocar para obtener este galardón. Suerte.

Referencias

cake feeds rss atom 1.2

Escribe tu comentario
 
 
Guardar datos
Escribe tu comentario:
captcha


Intenta que tu comentario sea interesante y con información relevante al tema de la entrada. BBCodes disponibles: [url=http://direccion]texto[/url], negrita: [b]texto[/b], itálica: [i]texto[/i], subrayada: [u]texto[/u]. Para mencionar o citar a alguien (quote): [cita]texto[/cita]