Si tenemos un blog, es fundamental disponer de un canal RSS o Atom para que, por una parte, los usuarios pueden suscribirse a nuestra web y, por otra parte, los agregadores de noticias tengan acceso a nuestro contenido, lo que nos traerá más visitas. Vamos a ver como generar este típo de canal con NodeJS, Express, Mongoose y MongoDB
En este artículo se supone que el lector está familiarizado con NodeJS+Express. Por lo tanto vamos a ir directos a los archivos que necesitamos para publicar nuestro feed. En este artículo se presenta el código para generar el feed de este blog: http://www.iteracion42.com/feed/.
Primero que nada vamos a ver como almacenamos los posts de nuestro blog. En el archivo posts.js tendremos el esquema del documento MongoDB, que sería el siguiente:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var PostSchema = new Schema({
_id: Number,
title: String,
body: String,
published_at: Date,
canonical: String,
author: String
});
module.exports = mongoose.model('Post', PostSchema);
Dentro del direcotrio routes, creamos el archivo feed.js:
var express = require('express');
var router = express.Router();
var Post = require('../models/post');
/* GET home page. */
router.get('/', function(req, res, next) {
Post.find({ }).sort({ published_at: -1} ).exec(function (error, db_posts) {
if(error) { console.log(error) }
db_posts.forEach( function (post, index) {
db_posts[index].body = post.body.split('<hr>')[0];
db_posts[index].body = post.body.replace('<p>','').replace('</p>','');
});
res.setHeader('content-type', 'application/rss+xml');
res.render('feed', {
pretty: true,
title: 'Iteración 42',
description: 'Un poco de programación y un algo sobre sistemas',
posts: db_posts
});
});
});
module.exports = router;
Aquí hay que tener en cuenta 2 cosas. La primera es la línea "res.setHeader('content-type', 'application/rss+xml');". Un archivo RSS no es plain/text y, aunque muchos lectores ignoran este error, no es correcto publicarlo con el header incorrecto. Otro punto a tener en cuenta es: "pretty: true,". Con esto obligamos a Express a renderizar el html con saltos de línea. Al estándar RSS no le gusta el código en una sola línea. Con algunos agregadores de noticias se puede tener problemas.
A continuación el código para la plantilla Jade de nuesto Feed RSS:
doctype xml
rss(version='2.0', xmlns:atom='http://www.w3.org/2005/Atom')
channel
title #{title}
link http://www.iteracion42.com
description #{description}
language es-ES
copyright Copyright 2016, Iteración 42
generator Iteración 42
if posts.length
lastBuildDate= new Date(posts[0].published_at).toUTCString()
|
| <atom:link href="http://www.iteracion42.com/feed/" rel="self" type="application/rss+xml"/>
each post in posts
item
title= post.title
link http://www.iteracion42.com/viewpost/#{post.id}/#{post.canonical}
guid http://www.iteracion42.com/viewpost/#{post.id}/#{post.canonical}
description #{post.body}
pubDate= new Date(post.published_at).toUTCString()
La línea más extraña puede ser donde declaramos el atom:link que, pese a no ser necesaria para cumplir el estándar RSS 2.0, el comprobador de RSS lo marcaba como error. De esta forma me aseguro que este feed será compatible con el 100% de agregadores de noticias. En los items, tenemos por ducplicado link e guid. Otra vez, es para asegurar la compatibilidad con todos los agregadores de noticias.
Para comprobar el feed se han utilizado los comprobadores: https://validator.w3.org/feed/ y http://www.feedvalidator.org/.