Visualizzazione risultati 1 fino 6 di 6

Discussione: [PHP] Template System personale per il sito

  1. #1
    L'avatar di heracleum
    heracleum non è connesso Utente storico
    Data registrazione
    21-01-2004
    Messaggi
    3,333

    Predefinito [PHP] Template System personale per il sito

    Ho in cantiere di sostituire la generazione del layout base del mio sito con un Template System "fatto in casa", insomma tale da NON potersi definire CMS (Content Management System).
    Soprattutto per portare comodamente il tutto da HTML penoso (invalidissimo w3c) ad un bel XHTML1.0 Transitional valido.

    E tra l'altro non è stato per nulla difficile, in una sola serata (ieri) ne ho realizzato uno che fa proprio al caso mio. Informandomi con google qua e là, ho realizzato un semplicissimo Template Engine che consta di una sola Classe PHP.
    Togliendo fronzoli e utilità personali, il codice base della classe è:
    class file: docgen.php
    Codice PHP:
    <?php
    class DocGen{

    var
    $content;

    function
    DocGen($template = "default.html") {
    if (
    file_exists($template))
    $this->content = join("", file($template));
    else
    die(
    "Template $template non trovato.");
    }

    function
    parse($file) {
    ob_start();
    include(
    $file);
    $buffer = ob_get_contents();
    ob_end_clean();
    return
    $buffer;
    }

    function
    put($tags = array()) {
    if (
    sizeof($tags) > 0){
    foreach (
    $tags as $tag => $data) {
    $data = (file_exists($data)) ? $this->parse($data) : $data;
    $this->content = str_replace('<!--'. $tag .'-->', $data, $this->content);
    }
    }
    }

    function
    flush() {
    echo
    $this->content;
    }
    }
    ?>
    Poi il file php vero e proprio che viene chiamato, usa la classe così:
    diciamo index.php:
    Codice PHP:
    <?php
    $root
    = '/membri/utente/';
    require_once(
    $root.'percorso/docgen.php');

    $docgen = new DocGen();

    $docgen->put(array(
    'doc_title' => 'Il Titolo Pagina',
    'doc_descr' => 'Descrizione della pagina nei meta',
    'doc_menu' => $root.'percorso/menu.php',
    'doc_footer' => $root.'percorso/footer.php'
    ));

    //-------start dynamic body content---------
    ob_start();

    //...TUTTO il codice xhtml/php del
    //corpo principale di questa pagina...

    $pagecont = ob_get_contents();
    ob_end_clean();
    //-------end dynamic body content---------

    $docgen->put(array('doc_body' => $pagecont));

    $docgen->flush();

    ?>
    OK?
    Dovrebbe essere piuttosto chiaro
    Per chiarire l'ultimo particolare, in vero layout della pagina sta nel file html che usiamo come template, che molto stilizzato potrebbe somigliare a:
    template file: default.html
    Codice HTML:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html dir="ltr" lang="it">
    <head>
      <title> <!--doc_title--> </title>
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
      <meta name="description" content="<!--doc_descr-->" />
    </head>
      <body>
        <div id="menu">  <!--doc_menu-->  </div>
        <div id="main">  <!--doc_body-->  </div>
        <div id="footer">  <!--doc_footer-->  </div>
      </body>
    </html>
    Ok penso ci sia tutto il necessario per capire.
    Dunque differisce da un CMS classico perché non è un unico script centrale a sapere qual è la Site Map (alberatura delle pagine) e ad associare un Item di navigazione al contenuto della pagina relativa...
    bensì sono vari script php che mettiamo fisicamente in reali sottocartelle del nostro spazio web, e ciascuno script (come nell'esempio di index.php) sfrutta la classe DocGen per assegnargli i vari componenti dai valori stringa diretti e semplici (titolo, descrizione..) ai blocchi complessi, quindi file php o html (es. footer.php e menu.php) che saranno inclusi nella pagina.

    Quindi:
    - Flessibilità assoluta, funziona che è una bellezza! almeno per me comodisssimo;
    - e utile per chi ha già pagine php sparse per varie directory e vuole riorganizzare e centralizzare uno o più layout diversi in tutto il sito senza perdere PR e gli URL.

    Finora condivido con voi lo script e spero sia di utilità...
    Ma veniamo al punto dolente :
    e questa è infatti la richiesta di scambio idee del post:


    - finché non è pronto TUTTO il "buffer" (il contenuto della pagina caricato man mano) e dunque finché non si invoca la funzione $docgen->flush() al browser ovviamente non arriva NULLA, quindi se la pagina è molto lunga (per es. ha molti commenti o è una lista lunga, etc..) il visitatore sta lì ad aspettare a pagina vuota!

    Questo è dovuto all'ampio uso delle funzioni ob_ cioè Output Buffering (ob_start() etc..).

    Al di là di gestire un messaggio di caricamento di qualsivoglia natura...
    Come risolvereste voi la questione di inviare "qualcosa" al browser?

    io una soluzione sotto sotto la sto covando... ma mi piacerebbe condividere con voi idee varie, senza snaturare troppo il sistema di templating.

    (la fonte più utile per l'ispirazione è stata http://codewalkers.com )
    Avvertimento: richiedere in privato questioni tecniche produrrà inevitabilmente una supercazzola prematurata come risposta. (5 served)

  2. #2
    L'avatar di mythologia
    mythologia non è connesso Moderatore
    Data registrazione
    05-01-2004
    Messaggi
    2,614

    Predefinito

    Io uso un sistema 'simile', fatto da me per il mio forum in cantiere...
    Io avendo trovato lo stesso problema ho risolto facendo, in pratica, uno split del file di template attraverso una solita stringa (<!--split--> in questo caso):
    Es.
    Codice PHP:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <
    html dir="ltr" lang="it">
    <
    head>
    <
    title>
    <!--
    doc_title-->
    </
    title>
    <
    meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <
    meta name="description" content="<!--doc_descr-->" />
    </
    head> <body> <div id="menu"> <!--doc_menu-->
    </
    div>
    <
    div id="main">
    <!--
    split-->
    <!--
    doc_body-->
    </
    div> <div id="footer">
    <!--
    doc_footer-->
    </
    div>
    </
    body>
    </
    html>
    Questo è un esempio (il file postato da te, heracleum,era un po' troppo piccolo)...
    Poi aggiungi lo split anche nella funzione in modo tale che ti printi tutto come fosse una cosa a parte.
    Credo che tu abbia capito in linee generali cosa intendo...
    ciò si può fare in quell'unica classe... infatti io uso proprio una classe e devo dirti che il tutto funziona a meraviglia
    Ultima modifica di mythologia : 04-01-2006 alle ore 10.23.28

  3. #3
    Guest

    Predefinito

    Secondo me il problema non si pone, Heracleum.
    Una pagina viene generata in qualche centesimo di secondo, anche con server carico questa non dovrebbe superare il secondo.
    Se si superano questi valori c'è qualcosa che non và o a livello di script o a livello server.

    Prendi ad esempio il mio forum (non posto il link solo per evitare spam), la pagina viene generata in media a 0.03 ed al massimo in 0.6 con server a pieno carico, usando lo stesso tuo sistema (sintassi delle variabili a parte).
    Ti assicuro che l'apparente lentezza di caricamento è sempre dovuta a problemi di banda/connessione.

    Ultima cosa: consiglio di aggiungere un metodo per gestire gli errori, se avviene un errore fatale con la cattura dell'output attiva questo non viene visualizzato perchè lo script si interrompe prima del flush.
    Ultima modifica di Inverno : 04-01-2006 alle ore 13.58.39

  4. #4
    L'avatar di mythologia
    mythologia non è connesso Moderatore
    Data registrazione
    05-01-2004
    Messaggi
    2,614

    Predefinito

    Giusto, anche io faccio come Inverno :D

  5. #5
    L'avatar di heracleum
    heracleum non è connesso Utente storico
    Data registrazione
    21-01-2004
    Messaggi
    3,333

    Predefinito

    Citazione Originalmente inviato da Inverno
    Ultima cosa: consiglio di aggiungere un metodo per gestire gli errori, se avviene un errore fatale con la cattura dell'output attiva questo non viene visualizzato perchè lo script si interrompe prima del flush.
    Ottima dritta
    in effetti il messaggio di errore va a finire nell'output buffer ma interrompendo lo script non si arriva al flush.. vero, ancora non avevo neanche affrontato la gestione degli errori ed hai fatto benissimo a segnalare la cosa.


    Nel frattempo mi sono venute ulteriori idee..
    Come inserire anche un sistema di content Caching.. per evitare di rieseguire spesso il grosso degli script inutilmente, in base a scadenze (anche differenti in base all'esigenza)..
    Ma questo è un tema più orientato al "content" più che al template.

    Myhologia:
    Sì, cioè dici appena alla classe docgen viene invocata una funzione apposita per "splittare", intanto questa manda al client il pezzo di buffer prima del tag split e lo toglie ovviamente dal suo buffer.

    Direi, anche senza usare un tag apposito per lo split, no?
    Alla classe gli si aggiunge una function di split tipo
    flush_before($tagname)
    in cui tutta la substring da 0 fino all'occorrenza del nome tag indicato viene restituita al client.

    Quindi per es prima che lo script si metta a processare il proprio body potrebbe fare:
    flush_before('doc_body');

    Dopo di che il valore della variabile $content della classe DocGen inizierà per:
    "<!--doc_body-->
    </div> <div id="footer"> ...etc.."
    Avvertimento: richiedere in privato questioni tecniche produrrà inevitabilmente una supercazzola prematurata come risposta. (5 served)

  6. #6
    L'avatar di mythologia
    mythologia non è connesso Moderatore
    Data registrazione
    05-01-2004
    Messaggi
    2,614

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •