
Hoy vamos a ver una aplicación experimental de eso que llaman “linked data”, una tendencia que podría considerarse web semántica, aunque sin ontologías ni estándares, sino basada en RSS, servicios web y API específicas para cada servicio: se trata de obtener enlaces en Delicious relacionados con los contenidos del blog.
Lo que hace este sencillo algoritmo es comparar las “nubes” de tags: obtiene los últimos enlaces de una cuenta de Delicious, comprueba que contengan las tags más recurrentes en el blog, y, cuanto más concurrentes sean las tags en el blog, más puntuación de afinidad se le da al enlace.
El ejemplo en acción lo puedes ver ahí a la derecha. Las tags más recurrentes del blog (web semántica, web social, evolución de internet…) están presentes en los enlaces.
El algoritmo puede ser útil para saber cómo evolucionan los intereses de redacción y navegación del blogger o aportar contenido añadido al blog. Estoy preparando más artículos con más criterios para evaluar la "cercanía temática" de los artículos, basándose en las etiquetas.
El código de abajo funciona sobre el gestor de contenidos de este sitio. Si a alguien le interesa hacer un plug-in para WordPress que soporte esta funcionalidad lo podemos intentar. Habría que adaptar la obtención de los datos (adaptando las sentencias SQL a la BD de WordPress o sustituyéndolas por llamadas a la API) y el modo de mostrarlos (sin Smarty).
Función para ordenar los enlaces
//Ordena una matriz por el valor de una de sus claves (primer nivel)
//TODO parece que no funciona bien
function array_sort_clave(&$data, $campo) {
//Crea una función personalizada para el campo
$codigo_funcion = “return strcmp($a['$campo'], $b['$campo']);”;
usort($data, create_function(‘$a,$b’, $codigo_funcion));
return $data;
}
Clase Enlace (la utilizo para los enlaces de Delicious y para el blogroll)
class Enlace {
public $titulo;
public $url;
public $icono;
public $rel;
public $tags = array();
public function __construct($titulo, $url, $icono, $rel=null, $tags=null) {
$this->titulo = $titulo;
$this->url = $url;
$this->icono = $icono;
$this->rel = $rel;
$this->tags = $tags;
}
}
La "chicha"
//Obtiene una nube de tags correspondiente a todos los post
static public function getTagcloudSimple() {
$tagcloud = array();
$cTags = BDConsulta("SELECT tag FROM tags WHERE post IN (SELECT id FROM posts ORDER BY creado DESC)");
while ($tag = recorrer_resultados($cTags)) {
$tagcloud[$tag['tag']]++;
}
return $tagcloud;
}
//Obtiene enlaces de Delicious, en orden de afinidad con el blog
//La afinidad con el blog se calcula a partir de las tags de los posts del blog. A cada enlace se le asigna un índice de afinidad
//El índice de afinidad se calcula sumando las veces que cada tag del enlace aparece en el blog
static public function getDelicious() {
$enlaces = self::getEnlacesDelicious();
$enlaces_con_puntos = array();
$tags_blog = self::getTagcloudSimple();
foreach ($enlaces as $enlace) {
$puntos = 0;
foreach ($enlace->tags as $tag_del_enlace) {
$puntos += $tags_blog[$tag_del_enlace];
}
$enlaces_con_puntos[] = array('datos'=>$enlace, 'puntos'=>$puntos);
}
array_sort_clave($enlaces_con_puntos, "puntos");
$enlaces_final = array();
$cnt = count($enlaces_con_puntos);
//Ordena inversamente la matriz, aunque ordena sólamente las claves
for ($i=0; $i<$cnt; $i++) {
$enlaces_final[$cnt-1-$i] = $enlaces_con_puntos[$i];
}
//Ordena el array según las nuevas claves. Vaya lío...
ksort($enlaces_final);
return $enlaces_final;
}
//Se procesa el RSS de los enlaces y se crea un array de objetos Enlace con él
static public function getEnlacesDelicious($limite=30) {
if (!is_int($limite)) trigger_error("El parámetro debe ser un entero", E_USER_ERROR);
//$xml = simplexml_load_file(RUTA_L . "delicious.xml");
$xml = simplexml_load_file("http://feeds.delicious.com/v2/rss/isra00?count=$limite");
$enlaces = array();
foreach ($xml->channel->item as $item) {
$tags_item = array();
//No vale pasar $item->category directamente al constructor de Enlace, mejor pasarlo a array de cadenas
foreach ($item->category as $s) {
$tags_item[] = utf8_decode((string) $s);
}
$enlaces[] = new Enlace(utf8_decode($item->title), utf8_decode($item->link), null, null, $tags_item);
}
return $enlaces;
}
Mostramos los enlaces en una plantilla Smarty
<h3>Enlaces Delicious</h3>
<div id="blogroll" class="sb_seccion pq">
<p>Mostrando enlaces relacionados con el blog. <a href="http://delicious.com/isra00/">Ver todos los enlaces</a>.</p>
<ul>
{foreach from=$delicious item=enlace name=i}{if $smarty.foreach.i.index < 10}
<li>
<a href="{$enlace.datos->url}">{$enlace.datos->titulo}</a>
{foreach from=$enlace.datos->tags item=tag}
<a class="insignificante" href="http://delicious.com/isra00/{$tag}">[{$tag}]</a>
{/foreach}
</li>
{/if}{/foreach}
</ul>
</div>