Inici > Programació, Web > Leer hilos RSS en CakePHP utilizando jQuery

Leer hilos RSS en CakePHP utilizando jQuery

divendres, 20 de novembre de 2009 Imprimir

Con este pequeño tutorial aprenderéis a leer hilos RSS en CakePHP y mostrarlos “con clase” utilizando el framework de JavaScript jQuery.

Si no tenéis ni idea de Cake pero utilizáis un poco el tarro seguro que podréis aprovechar este mismo ejemplo para leer hilos RSS mediante PHP y jQuery (una pista: empezad por eliminar todo lo que tenga que ver con la caché).

Para este tutorial sólo necesitáis jQuery (yo utilizo la v. 1.3.2) y CakePHP (en mi caso la v. 1.2.4.8284 [1.2.5 stable]).


Vamos a utilizar nuestro fichero pages_controller.php para gestionar los hilos. Si no lo tenéis creado, creadlo. Recordad que debéis hacerlo en la carpeta /app/controllers/ y que el contenido de este fichero debe ser, para empezar, idéntico que el fichero /cake/libs/controller/pages_controller.php; algo así:

<?php // /app/controllers/pages_controller.php
class PagesController extends AppController {
	var $name = 'Pages';
	var $uses = array();
	var $components = array('RequestHandler');
	var $cacheDuration = '+3 hours';

	function display()
	{
		$path = func_get_args();

		$count = count($path);
		if (!$count) {
			$this->redirect('/');
		}
		$page = $subpage = $title = null;

		if (!empty($path[0])) {
			$page = $path[0];
		}
		if (!empty($path[1])) {
			$subpage = $path[1];
		}
		if (!empty($path[$count - 1])) {
			$title = Inflector::humanize($path[$count - 1]);
		}
		$this->set(compact('page', 'subpage', 'title'));
		$this->render(join('/', $path));
	}
}

Para ahorrar tiempo he añadido ya —en azul— un par de cosas que vamos a necesitar.

En la línea 5 he añadido el “RequestHandler” ya que vamos a trabajar con Ajax y necesitaremos uno de sus métodos.

En la línea 6 he inicializado la variable $cacheDuration donde almacenamos el tiempo de actualización de la caché (3 horas en el caso del ejemplo). Si lo preferís podéis iniciarla más adelante como una variable normal dentro de un método en lugar de crearla como variable de clase.

Sabiendo esto, pasemos a la creación del resto de métodos del controlador PagesController:

// continuación de /app/controllers/pages_controller.php
function beforeFilter()
{
	// Desactivamos debug para todo el controlador
	Configure::write('debug',0);
	// En caso de utilizar el componente Auth, damos permiso a las secciones necesarias
	//$this->Auth->allowedActions = array('rss');
	parent::beforeFilter();
}

function rss($name = null, $limit = 8, $cache = true)
{
	// Desactivamos auto render de las vistas
	$this->autoRender = false;
	$options = compact('limit','cache');
	// Si la solicitud es Ajax
	if($this->RequestHandler->isAjax()){
		// Cargamos layout ajax.ctp
		$this->layout = 'ajax';
		// Url según nombre recibido por parámetro
		switch($name){
			case 'psico':
				$url = 'http://psicoactividad.underave.net/feed';
				break;
			case 'zeta':
				$url = 'http://planzeta.underave.net/feed';
				break;
			case 'raco':
				$url = 'http://www.racotecnic.com/feed';
				break;
			case 'underave':
			default:
				$url = 'http://blog.underave.net/feed';
		}
		// Obtenemos los hilos
		if((isset($options['cache']) && $options['cache'] == false) || ($feeds = Cache::read("$name.feed")) == false){
			$feeds = $this->_getFeeds($url);
			// Si el parámetro cache es true guardamos en caché
			if($options['cache'] == true){
				Cache::set(array('duration' => $this->cacheDuration));
				Cache::write("$name.feed",$feeds);
			}
		}
		// Limitamos los resultados
		if(isset($options['limit']) && count($feeds) > $options['limit'])
			$feeds = array_slice($feeds, 0, $options['limit']);
		// Guardamos la variable $data
		$this->set('data', $feeds);
		// Cargamos fichero json.ctp
		$this->render('/ajax/json');
	}else $this->redirect('/');
}
        
private function _getFeeds($url)
{
	// Configuramos la conexión curl
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
	curl_setopt($ch, CURLOPT_URL, $url);
	// Ejecutamos la conexión
	$feed = curl_exec($ch);
	curl_close($ch);
	// En caso de error detenemos ejecución
	if(!$feed)  return false;
	// Creamos objeto SimpleXmlElement
	$xml = new SimpleXmlElement($feed);
	// Leemos el hilo RSS y lo guardamos en la variable $out
	foreach($xml->channel->item as $item){
		$out[] = array(
			'title' 		=> (string)$item->title,
			'description' 	=> (string)$item->description,
			'pubDate' 		=> strtotime($item->pubDate),
			'link' 			=> (string)$item->link
		);
	}
	// Devolvemos el hilo
	return $out;
  }

Como siempre digo, el código habla por si solo y para el resto están los comentarios 😉 Sólo cabría mencionar un par de cosas:

El layout ajax.ctp (línea 19) no hace falta que lo creéis ya que CakePHP ya lo incluye en su núcleo.

El fichero json.ctp (línea 49) sólo contiene el echo de un json_encode:

<?php // /app/views/ajax/json.ctp
echo json_encode($data) ?>

El fichero json.ctp lo he creado en la carpeta ajax porque todo lo relacionado con ajax lo meto en la carpeta /app/views/ajax/ para tenerlo todo en el mismo sitio. A demás, son ficheros tan genéricos que los utilizo desde casi todas las secciones así que ya me va bien tenerlos en una carpeta por separado.

Si lo preferís, en lugar de crear la vista json, podéis optar por hacer un echo de un json_encode en el controlador directamente, aunque eso rompe un poco con el patrón MVC.

Para que el método rss funcione es importante que creemos una ruta hacia /rss:

// /app/config/routes.php
Router::connect('/rss/:feed',
	array('controller'=>'pages','action'=>'rss'),
	array(
		'feed'=>'[a-z]+',
		'pass'=>array('feed')
	)
);

Dicho esto, pasemos rápidamente a la vista que mostrará los hilos RSS (en mi caso la he llamado blogs.ctp):

// /app/views/pages/blogs.ctp
<?php $javascript->link('page_specific/blogs',false) ?>
<p><?php echo $html->link('Leer hilos RSS en CakePHP utilizando jQuery','http://www.racotecnic.com/2009/11/leer-hilos-rss-en-cakephp-utilizando-jquery') ?></p>
<?php echo $html->link($html->image('http://www.underave.net/barna23/img/blogs/raco.png', array('alt'=>'Racó Tècnic', 'class'=>'titol_blog')),'http://www.racotecnic.com',array('target'=>'_blank'),false,false) ?>
<ul class="blogs" id="raco">
	<li><?php __("Cargando") ?>...</li>
</ul>
<?php echo $html->link($html->image('http://www.underave.net/barna23/img/blogs/unde.png', array('alt'=>'Underave\'s Blog: Be underground', 'class'=>'titol_blog')),'http://blog.underave.net',null,false,false) ?>
<ul class="blogs" id="underave">
	<li><?php __("Cargando") ?>...</li>
</ul>
<?php echo $html->link($html->image('http://www.underave.net/barna23/img/blogs/zeta.png', array('alt'=>'Plan [Zeta]', 'class'=>'titol_blog')),'http://planzeta.underave.net',array('target'=>'_blank'),false,false) ?>
<ul class="blogs" id="zeta">
	<li><?php __("Cargando") ?>...</li>
</ul>
<?php echo $html->link($html->image('http://www.underave.net/barna23/img/blogs/psico.png', array('alt'=>'Psico Actividad', 'class'=>'titol_blog')),'http://psicoactividad.underave.net',array('target'=>'_blank'),false,false) ?>
<ul class="blogs" id="psico">
	<li><?php __("Cargando") ?>...</li>
</ul>

En la línea 2 he añadido el fichero javascript que se encargará de cargar los hilos RSS (y será el siguiente paso del tutorial).

En las líneas 5, 6 y 7 (y luego se repite para cada blog) he añadido una lista de elementos con una ID cada uno. Esta ID debe coincidir con las opciones que hayáis puesto en el switch del método rss (en pages_controller.php).

Sólo nos queda hacer el fichero JavaScript encargado de cargar los hilos:

// /app/webroot/js/page_specific/blogs.js
$(function(){
	// ID de cada blog (debe coincidir con las ID de la vista y las del controlador)
	var blogs = ['underave','zeta','psico','raco'];
	$.each(blogs, function(i, blog){
		// Obtenemos JSON para cada blog
		$.getJSON(webroot+'rss/'+blog,function(data){
			// Ocultamos el texto "Cargando..."
			$('#'+blog).fadeOut('normal',function(){
				// Eliminamos el texto "Cargando..."
				$(this).html('');
				// Añadimos un ítem a la lista por cada enlace recibido
				$.each(data, function(i, item){
					$('<li><a href="'+item.link+'" target="_top">'+item.title.substr(0,1).toUpperCase() + item.title.substr(1,item.title.length).toLowerCase()+'</a></li>').appendTo("#"+blog);
				});
				// Lo mostramos todo
				$(this).fadeIn('normal');
			});
		});
	});
});

El trozo de item.title.subtr(0,1).toUpperCase() + item.title….. es una pijada mía para que salga sólo la primera letra en mayúscula y el resto en minúscula. Si lo queréis sacar simplemente poned “item.title” y ya estará 😉

Pues ya está, ya lo tenemos 😀 Si todo ha ido bien deberíais verlo parecido a alguno de los ejemplos.

Categories: Programació, Web Etiquetes:, , , , ,
  1. Migue
    dissabte, 4 de setembre de 2010 a les 06:10 | #1

    consulta me prodrias ayudar con este, lo estoi dejando como una nueva app como otra aplicacion del cake en una app tengo wordpress y en otra quiero dejar este rss, descargo tu archivo y la coloco altiro como nueva app y no me funciona ???? hay que hacerle algo mas o no? … estoi recien aprendiendo esto de cake y ando buscando justo un lector de rss

Comentaris tancats.