Gestione CSS avanzata: Parte 2

cssNel precedente articolo abbiamo discusso i nostri obiettivi e abbiamo dato un’occhiata a quello che dovrebbe essere il risultato finale.
Iniziamo oggi a sviluppare lo script.

Struttura delle directory

Vediamo innanzitutto l’organizzazione dei file del nostro progetto

/cache/
/libs/cleancss.php
/libs/smarty/[...]
/templates/
/templates/css/
/templates/css/reset.ccss
/templates/css/main.ccss
/.htaccess
/bootstrap.inc.php
/css.php
  • Il file css.php sarà lo script sul quale lavoreremo. Lo vedremo in dettaglio a breve.
  • La cartella templates conterrà per l’appunto i template di Smarty e noi per tenere tutto meglio organizzato creiamo una cartella /templates/css per i fogli di stile.
  • Nella cartella libs posizioniamo tutte le librerie esterne che ci potranno service. Tra queste ci saranno sicuramente Smarty e CleanCSS.
  • bootstrap.inc.php rappresenta il file che inizializza l’ambiente di sviluppo, ad esempio creando l’oggetto di Smarty e impostando l’include_path.
<?php
$basedir = dirname(__FILE__);
set_include_path("$basedir/libs" . PATH_SEPARATOR . get_include_path());

require_once('smarty/libs/Smarty.class.php');

$s = new Smarty;

$s->auto_literal = true;
$s->_dir_perms = 0777;
$s->_file_perms = 0666;
$s->template_dir = implode(DIRECTORY_SEPARATOR, array($basedir, 'templates'));
$s->config_dir = $s->template_dir;
$s->compile_dir  = implode(DIRECTORY_SEPARATOR, array($basedir, 'cache', 'templates_c'));
$s->error_reporting = E_ALL & ~E_NOTICE;

if (!file_exists($s->compile_dir)) {
    mkdir($s->compile_dir);
    chmod($s->compile_dir, 0777);
}
  • E infine la cartella cache che conterrà tutti i file temporanei o le versioni precompilate dei nostri css.

URL

Come abbiamo visto lo script ci deve permettere di aggregare più CSS in un’unica richiesta, passando i nomi attraverso una variabile in GET.
L’url di una tipica richiesta sarà del tipo /css.php?f=reset+main ma tramite mod_rewrite possiamo gestirli con indirizzi del tipo /reset+main.css.

Iniziamo quindi a definire questa regola nel file .htaccess

RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule (.*)\.css$ css.php?f=$1 [L]

e il gioco è fatto! Possiamo ora utilizzare indifferentemente un tipo di indirizzo o l’altro.

Lo script PHP

Ora vediamo il file css.php:

<?php
require_once('bootstrap.inc.php'); // <- smarty  inizializzato qui ($s = new Smarty;)
require_once('cleancss.php');

// validazione della richiesta
if (empty($_GET['f'])) {
    header('HTTP/1.1 400 Bad Request');
    exit;
}

// questo script manda in output del css
header('Content-Type: text/css');

// Il + nella richiesta equivale a uno spazio, divido l'elenco dei file richiesti
$files = explode(' ',$_GET['f']);

$csscontent = "";
foreach ($files as $file) {
    $template = "css/$file.ccss";
    // Se il file non esiste tra i CCSS (CleanCSS), allora lo cerco come CSS normale
    if (!$s->templateExists($template)) {
        $template = "css/$file.css";
        $csscontent .= "/* $file.css */\\n";
        $csscontent .= trim($s->fetch($template))."\\n";
    } else {
        $csscontent .= "/* $file.ccss */\\n";
        $csscontent .= CleanCSS::convertString($s->fetch($template))."\\n";
    }
}

echo $csscontent;

Per ora è tutto molto semplice: Dopo aver validato la richiesta, controlliamo l’esistenza dei template richiesti, prima con l’estensione .ccss e se non esiste, lo cerchiamo con l’estensione .css.

Se il file aveva l’estensione .ccss, la conversione avverrà nel seguente modo in 2 passi successivi. Prima verrà richiesto il template a smarty ($s->fetch($template)), dopodiché il risultato verrà passato alla libreria CleanCSS per convertirne il formato in CSS semplice.

Per oggi ci fermiamo qui. Abbiamo pronto uno scheletro funzionante dello script ma mancano ancora gran parte delle funzioni avanzate. Per ora abbiamo sviluppato un sistema per l’inclusione di più CSS in una singola richiesta e la conversione dal formato CleanCSS.

Il codice sorgente dell’applicazione sviluppata fino ad ora è disponibile per il download. Assicuratevi di dare i permessi di scrittura alla cartella cache.

Nella prossimo articolo implementeremo l’aggiunta automatica delle varianti non-standard dei browser e della minificazione del codice, per poi concludere con un’ottima gestione della cache.