Blog


Generar Sitemap con Symfony2

GENERAR SITEMAP CON SYMFONY2

26 / 06 / 2014 Symfony

Los Sitemaps ayudan al posicionamiento en buscadores facilitando, por ejemplo, un fichero XML con todas las páginas que se pueden rastrear de un sitio web. En dicho fichero XML se pueden enumerar, además de las URL de todas las páginas, metadatos adicionales como la última actualización, importancia, etc. En este artículo vamos a ver una forma sencilla de generar ese sitemap.xml con Symfony.

Lo primero que haremos será crear la ruta para el sitemap:


# src/Vabadus/MiBundle/Resources/config/routing.yml

web_sitemap:
    pattern:  /sitemap.{_format}
    defaults: { _controller: MiBundle:Sitemap:sitemap, _format: xml }

A continuación creamos la acción correspondiente:


<?php
// src/Vabadus/MiBundle/Controller/SitemapController.php

namespace Vabadus\MiBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class SitemapsController extends Controller
{
    public function sitemapAction() 
    {
        $em = $this->getDoctrine()->getManager();
        
        $urls = array();
        $hostname = $this->getRequest()->getSchemeAndHttpHost();

        // incluye url página inicial
        $urls[] = array(
            'loc' => $this->get('router')->generate('web_homepage'), 
            'changefreq' => 'weekly', 
            'priority' => '1.0'
        );

        // incluye urls multiidioma
        foreach($languages as $lang) {
            $urls[] = array(
                'loc' => $this->get('router')->generate('web_quienes_somos', array(
                    '_locale' => $lang
                )), 
                'changefreq' => 'monthly', 
                'priority' => '0.3'
            );

            $urls[] = array(
                'loc' => $this->get('router')->generate('web_contacto', array(
                    '_locale' => $lang
                )), 
                'changefreq' => 'monthly', 
                'priority' => '0.3'
            );

            // ...
        }
        
        // incluye urls desde base de datos
        $categorias = $em->getRepository('MiBundle:Categoria')->findAll();
        foreach ($categorias as $item) {
            $urls[] = array(
                'loc' => $this->get('router')->generate('web_categoria', array(
                    'slug' => $item->getSlug()
                )), 
                'priority' => '0.5'
            );
        }

        $productos = $em->getRepository('MiBundle:Producto')->findAll();
        foreach ($productos as $item) {
            $urls[] = array(
                'loc' => $this->get('router')->generate('web_producto_detalle', array(
                    'slug' => $item->getSlug()
                )), 
                'priority' => '0.5'
            );
        }

        return $this->render('MiBundle:Sitemap:sitemap.xml.twig', array(
            'urls'     => $urls, 
            'hostname' => $hostname
        ));
    }
}

Y por último, creamos la plantilla:


<?xml version="1.0" encoding="UTF-8"?>
<urlset
      xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
            http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">

{% for url in urls %}
    <url>
        {# comprueba que hostname no esté ya incluido en url #}
        <loc>
            {% if url.loc|replace({hostname:''}) == url.loc %}
                {{ hostname }}{{ url.loc }}
            {% else %}
                {{ url.loc }}
            {% endif %}
        </loc>
        {% if url.lastmod is defined %}
            <lastmod>{{ url.lastmod }}</lastmod>
        {% endif %}
        {% if url.changefreq is defined %}
            <changefreq>{{ url.changefreq }}</changefreq>
        {% endif %}
        {% if url.priority is defined %}
            <priority>{{ url.priority }}</priority>
        {% endif %}
    </url>
{% endfor %}
</urlset>


ARTÍCULOS RELACIONADOS