Newsgroup: it.comp.www.php
Titolo: cms e routing

Buondï¿œ a tutti!
C'ï¿œ qualcuno nel ng che si ï¿œ cimentato nella progettazione di un cms, 
con url amichevoli? Avete previsto la possibilitï¿œ di gestire sia pagine 
da database, sia pagine applicative (intendo script php)? In tal caso, 
che scelte avete fatto per il routing delle richieste?

 che scelte avete fatto per il routing delle richieste?
io ho implementato solo i permalink, ma credo che alla fine non cambi 
molto a livello di tecnologia, si tratta sempre di prevedere un 
identificativo univoco per la pagina, diverso dal classico id=XX&pag=YY, 
in questo caso occorre prevedere invece hce la generazione automatica 
del permalink la possibilità di inserimento del link da parte 
dell'utente, ma ritengo che nel caso lo implementassi farei un campo 
gemello del permalink nel database.

 che scelte avete fatto per il routing delle richieste?
Io ho fatto una configurazione tale per cui un url del tipo foo/bar/
baz/pinco/palla/tizio viene elaborato nel modo:
1. Controllo se esiste (e se è nei moduli attivi, per evitare
injection) il controller foo
1.a Se si, controllo se contiene il metodo bar, e in tal caso gli
passo il resto dell'url come argomento (array('baz', 'pinco', 'palla',
'tizio'))
1.a.b In alcune parti, gli argomenti vengono passati sempre tramite
array ma di tipo associativo (array('baz' => 'pinco, 'palla' =>
'tizio'))
2. Se non esiste il controller o non ha il metodo, potrebbe essere un
alias, quindi controllo la configurazione (a database per esempio) se
ci sono azioni da fare per quell'url
3. se non trovo niente nella configurazione, restituisco un bel 404.
Nel punto 2 devo implementare (quando ho tempo) un sistema tipo
wildcards.

 3. se non trovo niente nella configurazione, restituisco un bel 404.
Ciao DaNieL, grazie per la risposta :).
Nella mia implementazione l'url si porta appresso le informazioni circa 
il percorso del controller nella mappa del sito: ci� significa che 
foo/bar/baz potrebbe essere cos� rappresentato nella mappa:
foo
  |
  |- bar
      |
      |- baz
Il mio algoritmo di routing quindi procede in senso opposto al tuo, 
partendo dalla fine e andando a ritroso, poich� l'url potrebbe essere 
valido per i seguenti casi:
(1) controller:baz metodo:main (metodo cercato implicitamente se non 
specificato)
(2) controller:bar metodo:baz
(3) controller:bar metodo:main argomenti:baz
(4) controller:foo metodo:bar argomenti:baz
(5) controller:foo metodo:main argomenti:bar,baz
Tutto questo funziona, ma finora ho lavorato solo con controller 
"fisici", senza cio� avere i contenuti di una pagina su database 
(praticamente la tipica funzionalit� di un cms). A conti fatti finora ho 
realizzato pi� un framework che un cms.
Ora che voglio implementare sopra al mio framework le funzionalit� di un 
cms, non ho le idee chiare su come capire dall'url quando � richiesta 
una pagina da cms oppure un controller.
Ci� che vorrei evitare � di portarmi appresso un id numerico di pagina 
(qualcosa del tipo 
www.esempio.it/12/tag-della-mia-pagina.html
).
Pensavo a qualcosa del tipo: prima cerco con il metodo sopra illustrato 
se esiste un controller; se non esiste, cerco su db se esiste una pagina 
con id uguale alla richiesta; se non esiste, 404. Prevedo per� problemi 
nella costruzione dei menu di pagine, per esempio quando un controller 
sar� figlio di un'altra pagina. Insomma, voler rappresentare nell'url la 
gerarchia tra pagine e controller si sta rivelando un casotto :(
Avete qualche idea chiarificatrice?

 che scelte avete fatto per il routing delle richieste?
codeigniter ha un buon sistema di routing interno, che diventa ottimo se 
si sa armeggiare in application/config/route.php

 gerarchia tra pagine e controller si sta rivelando un casotto :(
.. che è praticamente quello che faccio io.
Se non viene trovato nessun controller/metodo per l'url, considero
l'url come un alias, cioè l'utente mi ha specificato che la pagina che
mostra l'oggetto X, invece che raggiungerla tramite url /oggetto/
mostra/x la vuole all'url /titolo-oggetto-x.
Diciamo che la mia implementazione è più che altro nata per gli url
seo-friendly, e permette di 'rimappare' qualsiasi url interno
(controller/metodo/argomenti) in un url più semplice.
Il casino però, è fare il controllo se l'alias che si và a creare è
'libero' o meno, esempio:
url normale: /oggetto/modifica/x -> classe oggetto, metodo modifica,
argomento x (identificatore dell'oggetto, non necessariamente l'id)
url normale: /oggetto/stampa/x -> classe oggetto, metodo stampa (che
richiama una view particolare), argomanto X
Metti che ho un utente particolarmente masochista che mi imposta come
alias di /oggetto/modifica/x il valore /oggetto/stampa/x.
Così come l'ho strutturato io il controller prende il soppravvento,
quindi digitando /oggetto/stampa/x viene fatto una specie di redirect
a /oggetto/modifica/x, ma in futuro mi piacerebbe implementare un
controllo che avverta l'utente che l'url è utilizzato dal sistema (e
qui viene fuori l'esigenza delle wildcard).
Unica cosa che ti consiglio di fare, è 'registrare' i controller e
relativi metodi autorizzati a essere invocati tramite url onde evitare
injection e exploit vari.

 Avete qualche idea chiarificatrice?
Dimenticavo: per quel che riguarda la gerarchia delle pagine (e
breadcrumbs), se non sono una cosa impossibile da fare potresti
gestirla tramite array e, nei vari controller, invocare tipo la
funzione add_breadcrumb() dove registri passo passo la pagina in cui
sei.
Io a spiegarmi sono un cane; dai un'occhio al sistema che usa Drupal
per le breadcrumb

http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_set_breadcrumb/6
http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_get_breadcrumb/6


Per la gerarchia delle pagine e la relativa rappresentazione come 
breadcrumb, ho un file contenente un array siffatto:
$sitemap = array(
 
	'home' => array(
		'text' => 'Home',
		'title' => 'Pagina principale'
	),
 
	'news' => array(
		'text' => 'News',
		'title' => 'tutte le novità da Medimec',
	),
	'catalogo' => array(
		'text' => 'Catalogo prodotti',
		'title' => 'Consulta il nostro catalogo',
 
		'sons'	=> array(
 
			'prodotto-1' => array(
				'text' => 'Prodotto 1',
				'title' => '',
			),
		),
	),
);
 
quindi il breadcrumb lo genero a partire da questa struttura.


Si, immaginavo una cosa simile; aggiungi il valore del peso ai vari
elementi (in modo, all'occorrenza, di poterli riordinare) e ti fai una
funzione per aggiungere/rimuovere gli elementi a piacimento.
Logicamente se hai una struttura molto complessa diventa un massacro e
bisognerebbe puntare su qualcosa di più statico/standard ma con minori
possibilità di personalizzazione.
Ad esempio, quando crei gli alias ti salvi anche il percorso 'reale' e
quando li utilizzi parti da quello a creare le breadcrumb.

 [cut]
Quello che non mi è chiaro è: tu rappresenti nell'url la gerarchia tra 
le pagine? Esempio:
www.es.it/chi-siamo/la-nostra-storia/prima-del-duemila
dove chi-siamo, la-nostra-storia, prima-del-duemila sono 3 pagine da cms
perchè da quanto ho capito dal tuo intervento, hai la singola 
tassonomia: <controller>/<metodo>/<id>
Se mi limitassi a quello sarei a posto.. il mio problema è proprio 
gestire a "profondità illimitata" l'url.
Giusto per chiarire: il mio problema non è che senza portarmi appresso 
tutta la gerarchia non posso generare il breadcrumb eh.. non è per 
questo che intendo avere l'url così fatto.

 pagina X -> mostro pagina X (invocando direttamente il controller)
url: chi-siamo/la-nostra-storia -> lookup database -> pagina Y ->
mostro pagina Y (invocando direttamente il controller)
disabilito l'url rewrite, gli url saranno tipo
?node=X -> controller=node, metodo (non settato, quindi il default
'visualizza') con arg X
?node=Y -> controller=node, metodo (non settato, quindi il default
'visualizza') con arg Y
Per la gerarchia non ho mai avuto grandissime esigenze, ora non
ricordo come l'avevo implementata ma il sistema degli array non mi
sembra male, tenendo traccia a db della parentela.
Attualmente mi capita sempre meno spesso di fare cose custom, per la
parte pubblica utilizzo sempre drupal; per le applicazioni invece non
ho mai avuto esigenze di questo tipo, il semplice metodo controller/
metodo unito a un minimo di alias ha sempre coperto le mie esigenze.