Domanda

Mi chiedo: qual è il modo più efficace per analizzare qualcosa del tipo:

{{HEADER}}

Hello my name is {{NAME}}

{{#CONTENT}}
    This is the content ...

    {{#PERSONS}}

        <p>My name is {{NAME}}.</p>

    {{/PERSONS}}

{{/CONTENT}}

{{FOOTER}}

Ovviamente questo alla fine dovrebbe essere un po 'un sistema di templating, quindi il mio piano è quello di creare una hashmap per "stendere" su " il modello, come qualcosa del genere

$hash = array(
    'HEADER' => 'This is a header',
    'NAME' => 'David',
    'CONTENT' => array('PERSONS' => array(array('NAME' => 'Heino'), array('NAME' => 'Sebastian')),
    'FOOTER' => 'This is the footer'
    );

Vale la pena notare che le sezioni " " (i tag che iniziano con #), possono essere ripetuti più di una volta e penso che questo sia ciò che mi fa inciampare ...

Inoltre, qualsiasi sezione può contenere un numero qualsiasi di altre sezioni e tag regolari ...

Quindi ... come hai fatto?

È stato utile?

Soluzione

L'output previsto di questo è qualcosa del tipo:

Questa è un'intestazione

Ciao, mi chiamo David

This is the content ...

My name is Heino.

My name is Sebastian.

Questo è il piè di pagina


Come gestite la relazione tra array nidificati nella mappa hash e sezioni ripetibili nel modello? Qual è il comportamento effettivo del modello dovrebbe essere? Se viene fornito un array per un elemento non di sezione, cosa farà? Se a un elemento di sezione viene fornito un valore singolo, verrà trattato come un array con un solo elemento (suppongo di sì)?

Ad ogni modo, per quanto riguarda il parser per il modello (indipendentemente da ciò che si finisce con la mappatura dei dati) ... Quello che vorrei fare è creare una classe per ogni tipo di token, inclusa una generica per non -token content. Questi sarebbero ereditati da una classe base di token comune con metodi Parse, Render e Map ignorabili.

Traccia il diagramma del tuo stato e scopri quali sono i punti di entrata e di uscita per ciascuno stato, quindi codificalo nella struttura della chiamata tra i token. Alla fine, vuoi produrre una collezione enumerabile di token che descriva il tuo modello.

Una volta che lo hai in una forma astratta, puoi passare sopra la raccolta chiamando Mappa sui token per assegnare i dati dalla hashmap ai token, quindi chiamare Render per rendere il modello nella sua forma finale.

Spero che sia d'aiuto.

Altri suggerimenti

Il modo più efficace è compilare il modello in codice php. E solo includi la versione compilata.

Il Smarty Template Engine fa qualcosa di simile. Puoi anche guardare l'origine smarty e controllare come analizzano i tag.

Scommetti che è meglio usare qualcosa con un parser esistente come XML o JSON in modo da non dover scrivere il tuo parser e così che altri possano scrivere facilmente documenti per il tuo parser senza bisogno di strumenti specializzati. Tuttavia, se si desidera scrivere il proprio parser, è probabile che si desideri esaminare Lex e Yacc .

Vorrei andare con un parser di terze parti perché mi piace lavorare in modo più intelligente e non più difficile, ma se lo stai facendo come un esercizio o vuoi davvero costruire il tuo motore di template (in PHP suppongo a causa del tag ), Vorrei iniziare con la revisione dei modelli di progettazione, il modello di progettazione composita in particolare.

Il modello composito è molto usato nel framework Java per cose come questa, incluso l'analisi XML.

Userei qualcosa del genere all'interno di un file separato .php:

<?php echo $HEADER ?>

Hello my name is <?php echo $NAME?>

<div id="CONTENT">
    This is the content ...

    <?php foreach ($PERSONS as $PERSON) : ?>

        <p>My name is <?php echo $PERSON['NAME']?>.</p>

    <?php endforeach ?>

</div>

<?php echo $FOOTER ?>

E includi semplicemente il file sopra in quello in cui sono popolate le variabili di riferimento.

Che ci crediate o no, PHP fornisce già tutte le funzionalità che i sistemi di template là fuori stanno sostenendo di implementare. Non è necessario aggiungere un altro livello di astrazione (e complessità) oltre a PHP.

Uso DOM di PHP per questo. Il mio linguaggio modello è semplicemente HTML con attributi ID e classe Se vuoi rispettare il tuo piano, tuttavia, utilizzerei preg_replace_callback con uno schema che corrisponde alla tua sintassi e una funzione di callback che trova la sostituzione appropriata nell'hash, chiamandosi in modo ricorsivo sugli elementi contenitore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top