Crear Sitemap dinámico con CodeIgniter 4

Veamos cómo crear un sitemap dinámico con Codeigniter 4. Todas nuestras páginas y/o artículos actualizados en nuestro SiteMap.

Artículo que se añade al listado de tutoriales de CodeIgniter 4.

Problemas

Si no lo hacemos siguiendo estos pasos, tendremos problemas. Y muchos problemas. Debéis tener en cuenta que debemos retornar un fichero en formato XML y con Charset UTF-8. Si no seguís los pasos, tendréis desde errores del tipo:

  • No os detecta el tipo de documento xml. No se envía bien el header y no os reconoce el sitemap.
  • Errores de validación porque tenéis carácters no UTF-8.

Por ese motivo hay unos puntos muy concretos que son necesarios.

Controlador sitemap

El controlador es importantísimo. Llamamos a nuestro modelo para coger todos los artículos y mostramos la vista pasándole los artículos. Ahora bien, atentos a la llamada que hacemos al setHeader:

$this->response->setHeader('Content-Type', 'text/xml;charset=UTF-8');

Alerta: Esta llamada es importantísima. Con ella, hacemos que lo que retorna a la llamada sea un XML. Si no lo hacemos así, los navegadores, validadores, Google… no lo interpretará com XML y por lo tanto, dará error.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

use App\Models\SitemapModel;

class Sitemap extends CI_Controller {

  private $sitemapModel;
  
  /**
  * Constructor.
  */
  public function __construct()
  {
    $this->sitemapModel = new SitemapModel();
  }

  /**
  * Index Page for this controller.
  */
  public function index()
  {
    // IMPORTANTÍSIMO
    // Es lo que hace que lo que mostramos sea en formato XML y no otro que nos de error
    $this->response->setHeader('Content-Type', 'text/xml;charset=UTF-8');

    $data = [
	'articles' => $this->sitemapModel->getArticles()
    ];

    echo view('sitemap', $data);
  }
}

Model sitemap

Es el modelo. Simplemente devuelve todos los artículos que tenemos en la base de datos. Es el que utilizamos en el controlador anterior.

<?php namespace App\Models;

use CodeIgniter\Model;

class SitemapModel extends Model
{
  protected $db;
  protected $request;
  protected $numreg;

  public function __construct()
  {
    $this->numreg = 0;

    $this->request = \Config\Services::request();
    $this->db = \Config\Database::connect();
  }

  /**
  * Get Articles
  */

  public function getArticles()
  {
    $query = $this->db->query("SELECT * FROM articles ORDER BY date_created");
    $results = $query->getResultArray();

    return $results;
  }
}

Vista sitemap

En la vista formamos el XML resultado. En este caso el formato es de SiteMap como podéis ver.

<?php 
echo'<?xml version="1.0" encoding="UTF-8" ?>' ?>
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc><?php echo base_url();?></loc>
        <priority>1.0</priority>
        <changefreq>daily</changefreq>
    </url>

    <!-- Sitemap -->
    <?php foreach($articles as $article) { ?>
    <url>
        <loc><?php echo base_url()."article/".$article->id ?></loc>
        <priority>0.5</priority>
        <changefreq>daily</changefreq>
    </url>
    <?php } ?>

</urlset>

Alerta: A la hora de formar nuestro SiteMap, deberá contener caracteres UTF-8. Si utilizamos ñ, á, é, í, ó, ú o parecidos, nos daran errores de validació. Por lo que tendremos que subsituirlos por el equivalente en carácter de escape (os dejo enlace en la parte inferior para que lo veáis. Un ejemplo con el ? en algunos enlaces:

https://miweb.com/pages?id=123

Véis el interrogante a la hora de pasar el parámetro? pues nos dará un error de validación. Hay que pasarlo, substituyéndolo por:

https://miweb.com/pages&amp;id=123

Hemos cambiado ? por &amp; y de este modo, no nos dará error y Google nos lo validará sin problemas.

Routes Sitemap

Añadiendo la siguiente linea a nuestro fichero Routes.php de la carpeta /app/Config haremos que podamos consultar de forma más cómoda y clara nuestro sitemap

$route['sitemap\.xml'] = "Sitemap/index";

Con esto, podemos llamar a nuestro sitemap de la forma:

// gracias a linea en Routes
https://miweb.com/sitemap.xml

// Si no, deberíamos hacerlo así:
// https://miweb.com/sitemap/index

Espero que con este artículo podáis crear con CodeIgniter 4 un sitemap dinámico sin problemas. O almenos, os de luz si tenéis algún problema al respecto.


Más información