Modificare gli url in .htaccess con le funzioni di mod_rewrite

Attenzione: le modifiche al file .htaccess debbono essere fatte con molta prudenza. Prima di procedere eseguite sempre una copia di back-up del file e salvatela in un posto sicuro.

Il file .htaccess è un'estensione del file di configurazione del web server Apache; è stato ideato per permettere la delega di determinate operazioni di configurazioni ai responsabili del sito senza richiedere l'intervento dell'amministratore del server, e senza rendere accessibili le configurazioni più sensibili.

Noi ci occuperemo solo, ed in minima parte, delle possibilità offerte dal mod_rewrite, il componente di Apache destinato alla manipolazione degli URL. Nonostante l'assonanza ricordatevi che mod_rewrite non ha niente a che vedere con Joomla!, anche se il nostro cms lo usa abbondantemente per il SEO.

 

Come funziona?

Due sono le direttive che useremo:

  • RewriteCond stringaDiTest condizione [Opzioni]: per indicare quando riscrivere l'url
  • RewriteRule pattern sostituzione [Opzioni]: per indicare come riscrivere l'url

Osservando il file .htaccess avrete notato l'alternanza di queste due direttive che sono usate per l'implementazione SEO e per alcuni controlli di sicurezza. Notate che RewriteRule, la direttiva per come riscrivere l'url, può essere preceduto o meno da una o più RewriteCond per imporre delle condizioni su quando applicare la sostituzione.

Mod_rewrite carica l'intero insieme delle regole ed inizia a processarle. Per ogni RewriteRule confronta l'URL con il pattern (ovvero con lo schema di confronto), se non vi è corrispondenza passa alla regola successiva. Se la corrispondenza è trovata viene applicata la regola di sostituzione indicata se è verificata la condizione imposta nel gruppo di direttive RewriteCond che precede la RewriteRule, o se non vi è indicata alcuna condizione (ovvero non ci sono direttive RewriteCond).

Ho scritto che prima viene valutata la corrispondenza tra l'URL ed il pattern e poi viene valutata la condizione per decidere se applicare la sostituzione: può sembrare un poco strano, anche perchè avrete notato che le direttive rewitecond precedono sempre la RewriteRule, ma in effetti funziona proprio così.

Quando una regola viene applicata il ciclo ricomincia dall'inizio finché non venga effettuato senza che sia applicata alcuna sostituzione, o finché la sostituzione non richiede esplicitamente la fine del processo di sostituzione (ad esempio con un redirect); onde evitare loop infiniti esiste un numero massimo di iterazioni possibili.

La parte veramente difficile dell'uso delle regole/condizioni di riscrittura è il fatto che sia tutto basato su regular expressions, argomento a cui sono dedicati interi libri: senza la pretesa di voler insegnare niente vediamo ora alcuni esempi di riscrittura degli url che possono essere utili in Joomla!

 

www o non www

Questo primo esempio è indicato tra gli articoli richiesti, ed ho promesso a 'ste' di trattarlo: ogni promessa è debito.

[faccio riferimento all'articolo: http://community.joomla.org/featured-articles/did-you-know/476-to-www-or-not-to-www-.html]

Così come nella precedente versione di Joomla! (la 1.0), anche in quella attuale è possibile ignorare la compilazione della variabile di configurazione $live_site. Questo fa sì che il sito possa girare, sotto alcune configurazioni del web server, indifferentemente con (http://www.example.com) o senza (http://example.com) il www. iniziale; ciò potrebbe causare alcuni problemi, tra cui:

  • l'editor WYSIWYG potrebbe non funzionare ed impedire l'editing;
  • alcuni browser potrebbero richiedere due volte di effettuare il login a causa del fatto che cookie/sessioni appartengono a due URL differenti

Per reindirizzare tutto il traffico verso la 'versione www' del sito è proposta la seguente aggiunta al file .htaccess

RewriteCond %{HTTP_HOST} ^yoursite\.com [NC]

RewriteRule (.*) http://www.yoursite.com/$1 [R=301,L]

Come si legge?

Per prima cosa vediamo la RewriteRule; (.*) è il pattern, http://www.yoursite.com/$1 è la sostituzione.
Nel liguaggio delle regular expressions il carattere '.' indica un carattere qualsiasi (è un jolly) mentre l'asterisco indica che il carattere precedente può essere presente zero o più volte. '.*' vuol dire: prendi tutto l'URL, qualsiasi cosa sia.
le parentesi attorno definiscono un gruppo di caratteri che dovrà essere memorizzato per usi futuri, nello specifico il gruppo di caratteri verrà inserito nella stringa di sostituzione al posto del backreference $1 ($1 per il primo gruppo, $2 per i secondo e così via).

Quando questa porzione di .htaccess verrà processato sarà valutata la condizione espressa nella RewriteCond.
%{HTTP_HOST}, che contiene il nome host richiesto (è una variabile predefinita) viene confrontato con la stringa ^yoursite\.com. Il carattere ^, ad inizio riga, si legge inizia con, e precede il nome del sito; notate la scrittura '\.': ricordatevi che il punto ha un valore speciale e quindi è necessario scriverlo in questo modo per indicare proprio il '.'!
L'ultimo parametro(opzioni) '[NC]' indica che il confronto deve essere eseguito ignorando minuscole e maiuscole.

Facciamo un esempio

Un navigatore scrive l'indirizzo http://YourSite.com/index.php?option=com_virtuemart&Itemid=2&vmcchk=1&Itemid=2; Apache dividerà l'indirizzo nelle seguenti parti:

%{HTTP_HOST} : yoursite.com

URL : index.php?option=com_virtuemart&Itemid=2&vmcchk=1&Itemid=2

Notate due cose: il nome host non è preceduto dal protocollo, e, cosa molto più importante, l'URL non è mai preceduto da '/' ed è indicato sempre partendo dalla root (in realtà i percorsi relativi esistono per l'html, non per l'http!)

Il mod_rewrite:

  • confronta l'URL con il pattern, che indicando 'qualsiasi cosa' ovviamente soddisfa il confronto
  • verifica se il nome host inizia con yoursite\.com ignorando le differenze di maiuscole/minuscole
  • riscrive l'url aggiungendo il gruppo di caratteri salvati (tutto l'URL) in coda a http://www.yoursite.com/
  • effettua la redirezione a http://www.yoursite.com/index.php?option=com_virtuemart&Itemid=2&vmcchk=1&Itemid=2 tramite un redirect http con codice 301

L'ultimo parametro della RewiteRule, [R=301,L] indica con R=301 che una volta effettuata la sostituzione dell'URL questo debba essere reinviato al browser assieme al codice di stato http 301 (Moved Permanently, spostato in maniera definitiva) e che il loop di sostituzione deve essere interrotto, mentre la L (Last, ultima) indica che le RewriteRule successive non sono associate alla RewriteCond qui specificata.

Un'alternativa

Vediamo una alternativa a questa regola: io l'avrei scritta così:

RewriteCond %{HTTP_HOST} !^www\.
RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [R=301,L]

Vi premetto che il carattere '!' indica una negazione e pertanto si legge non (notate che non vi sono spazi tra ! e la condizione di test).
La RewriteRule svolge lo stesso compito visto prima, ma lo fa usando la variabile %{HTTP_HOST}, mentre la RewriteCond permette l'lapplicazione della regola solo se %{HTTP_HOST} NON comincia con 'www'. La differenza rispetto alla regola precedende? Questa non avete bisogno di modificarla inserendo il nome del vostro sito.

 

Simulare Joomla in Root

Il seguente codice permette di far sì che tutte le richieste che arrivino alla root del sito siano tradotte internamente per rispettare la struttura fisica delle cartelle del server. Supponete di aver installato Joomla! in www.miosito.it/cartella e di esservene pentiti.

La soluzione migliore è: spostate Joomla! http://www.joomla.it/articoli-della-community/4036-spostare-joomla-da-una-sottodirectory-alla-root-preservando-il-posizionamento.html

Ma se proprio non volete, ecco la modifica all' .htaccess

RewriteCond %{REQUEST_URI} !^/cartella
RewriteRule (.*) cartella/$1 [L]

Detto che %{REQUEST_URI} è l'URL interno preceduto dalla '/', dovreste saperla leggere:

Il mod_rewrite:

  • confronta l'URL con il pattern, che indicando 'qualsiasi cosa' ovviamente soddisfa il confronto
  • verifica se l'URI NON inizia con /cartella (Attenzione: i nomi host sono case insensitive, le path NO)
  • riscrive l'url aggiungendo il gruppo di caratteri salvati (tutto l'URL) in coda a cartella/ (ricordate che non c'è la / iniziale?)
  • ricomincia il ciclo di valutazione dell'URL

Ovviamente al 'giro' successivo la condizione !^/cartella non sarà più verificata e la regola non sarà applicata.

 

Rimuovere index.php dall'URL

Questa necessità si verifica quando il sito è stato indicizzato con attivata l'opzione 'Friendly URL' ma senza l'utilizzo del mod_rewrite. In questo caso se un visitatore digita www.dominio.it/index.php/nomepagina il redirect deve automaticamente portarlo a www.dominio.it/nomepagina (serve soprattutto per motori di ricerca!)

RewriteRule ^index.php/(.*)$ /$1 [R=301,L]

Questa è una riga sola! come vedete è sufficiente che l'URL inizi con 'index.php/' perché il sistema riscriva l'indirizzo rimuovendo la stringa 'index.php/'. Vi ricordate che significa '(.*)', vero? Il carattere $, alla fine del pattern, indica la fine della stringa e quindi il pattern si legge "verifica che inizi con index.php/ e poi prendi tutti i rimanenti caratteri sino a fine dell'url".

Il pattern deve essere sempre racchiuso tra ^ e $ ? Valgono le regole delle Espressioni Regolari (RegEx), con un po' approssimazione vi posso dire che quando si usa il quantificatore universale (*) in mezzo ad un pattern è buona norma specificare la fine della stringa per evitare ambiguità.

 

Rimuovere una cartella dall'URL

Questa è regola usata nel mio articolo quando si sposta fisicamente joomla da una sottodirectory (joomladir) alla root del sito. (serve soprattutto per motori di ricerca!)

RewriteRule ^joomladir/(.*)$ /$1 [R=301,L]

non ditemi che ve la devo spiegare!!

 

nella speranza che non vi sia venuto mal di testa vi saluto ;)

 

ciao,

marco

----

marco maria leoni web consulting

commentaCommenta questo articolo sul forum