Artículo archivado de 2013. Se conserva como referencia; la tecnología está desfasada.

Cache.manifest autogenerado en PHP

4 min de lectura

Si no quieres leer la entrada entera, puedes conseguir el código (y proponer cambios, por supuesto) en GitHub: https://github.com/tx2z/autogenerated-cache.manifest-php

Algo muy interesante de HTML5 es la posibilidad de crear aplicaciones o páginas web que funcionan sin conexión mediante el archivo cache.manifest. El usuario puede leer estas páginas cuando no tiene conexión a Internet, algo habitual hoy en día con la mala cobertura móvil de algunos lugares. También es buena idea con buenas conexiones, porque el usuario no tiene que descargar todos los datos y la página carga más rápido.

Así que sí, muy interesante, pero si has intentado crear un cache.manifest por tu cuenta, sabrás que lleva tiempo y esfuerzo, porque hay que actualizarlo cada vez que añades o cambias un archivo de tu web o aplicación.

Por eso busqué una forma fácil, o mejor, automática, de generar este archivo y descubrí que es muy sencillo con PHP (seguro que también lo es con otros lenguajes de servidor).

Echa un vistazo al código para ver lo fácil que es:

 1<?php
 2// Add the correct Content-Type for the cache manifest
 3header('Content-Type: text/cache-manifest');
 4
 5// Write the first line
 6echo "CACHE MANIFEST\n";
 7
 8// Initialize the $hashes string
 9$hashes = "";
10
11function create_manifest($folder) {
12  $dir = new RecursiveDirectoryIterator($folder);
13	// Iterate through all the files/folders in the current directory
14	foreach (new RecursiveIteratorIterator($dir) as $file) {
15		$info = pathinfo($file);
16
17		// If the object is a file
18		// and it's not called manifest.php (this file),
19		// and it's not a dotfile, add it to the list
20		if ($file -&gt; IsFile() && $file != "./manifest.php" && substr($file -&gt; getFilename(), 0, 1) != ".") {
21			// Replace spaces with %20 or it will break
22			echo str_replace(' ', '%20', $file) . "\n";
23
24			// Add this file's hash to the $hashes string
25			$hashes .= md5_file($file);
26		}
27	}
28}
29
30create_manifest(".");
31
32// Write the $hashes string 
33echo "# Hash: " . md5($hashes) . "\n";
34?>

Creo que no necesita mucha explicación, pero aun así:

– Primero se declara que el archivo es un cache.manifest y se escribe «CACHE MANIFEST» en la primera línea:

1<?php
2// Add the correct Content-Type for the cache manifest
3header('Content-Type: text/cache-manifest'); 
4
5// Write the first line
6echo "CACHE MANIFEST\n";
7?>

– Casi todo se hace en la función «create_manifest», que recorre todos los archivos y carpetas de la carpeta definida en la variable $folder.

Dentro de la función se crea un array, $dir, que contiene todos los archivos y carpetas, gracias a la clase «RecursiveDirectoryIterator». Se recorre ese array con «foreach» y se obtiene la ruta de cada archivo con «pathinfo».

Después, si el objeto es un archivo (no una carpeta), no se llama manifest.php (porque si cacheas tu archivo de manifiesto lo vas a pasar mal) y no es un «dotfile», se imprime en la página sustituyendo los espacios por %20 (en teoría no hace falta, porque habrás creado tus URL y tus archivos como es debido 🙂 ).

Por último, se añade el hash md5 del archivo a la variable $hashes (lo explico más adelante).

 1<?php
 2function create_manifest($folder) {
 3  $dir = new RecursiveDirectoryIterator($folder);
 4  // Iterate through all the files/folders in the current directory
 5	foreach (new RecursiveIteratorIterator($dir) as $file) {
 6		$info = pathinfo($file);
 7
 8		// If the object is a file
 9		// and it's not called manifest.php (this file),
10		// and it's not a dotfile, add it to the list
11		if ($file -&gt; IsFile() && $file != "./manifest.php" && substr($file -&gt; getFilename(), 0, 1) != ".") {
12			// Replace spaces with %20 or it will break
13			echo str_replace(' ', '%20', $file) . "\n";
14
15			// Add this file's hash to the $hashes string
16			$hashes .= md5_file($file);
17		}
18	}
19}
20?>

– Falta llamar a la función en la carpeta cuyos archivos queremos añadir al archivo cache.manifest. Podemos poner un punto (.) si queremos incluirlo todo.

1<?php
2create_manifest(".");
3?>

– Por último, si cambiamos el contenido de un archivo sin cambiar su nombre (por ejemplo, al actualizar una imagen), el navegador no sabe que el archivo ha cambiado y va a usar la versión cacheada. Pero si el cache.manifest ha cambiado, volverá a descargar todos los archivos.

Al imprimir la variable $hashes (que es distinta cada vez que cambia un archivo) nos aseguramos de que el navegador descargue todos los archivos si cambiamos cualquier cosa.

1<?php
2// Write the $hashes string
3echo "# Hash: " . md5($hashes) . "\n";
4?>

Y eso es todo. Solo falta añadirlo a nuestra página web después de la declaración del doctype:

1<!DOCTYPE html>
2<html manifest="manifest.php">

Ya tengo un archivo cache.manifest autogenerado que no hace falta actualizar cada vez 🙂

Funciona, por ejemplo, en la versión para tablet de la Revista Exégesis: http://www.revista-exegesis.com/publicaciones/2059/