[PHP] template macro's

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Het template systeem van mijn CMS'je werkt als volgt: de gebruiker kan een html bestand schrijven met daarin een aantal {tokens}. Dat is de template. De tokens worden dan ingelezen en vervangen door functie outputs. Klein voorbeeld:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function getNews($number)
{
  $output = '';

  $result = db_query("SELECT * FROM news LIMIT %d", $number);
  while ($article = db_fetch_array($result))
  {
    $output.= '<p>'.$article['text'].'<br>'.$article['date'].'</p>';
  }
  return $output;
}

$news = getNews(get_setting('number_of_articles'));
$body = getBody();

// $tpl komt normaal uit database...

$tpl  = '<html><head><body><p>{news}</p><p>{body}</p>';
$tags = array('{news}', '{body}');
$repl = array($news,   $body);
$html = str_replace ($tags, $repl, $tpl);

echo $html;

Dus bijvoorbeeld {news} wordt vervangen door een aantal nieuwsartikelen. Het aantal artikelen dat uit de database getrokken wordt, kun je instellen in het admin gedeelte. Dit is alleen onhandig. Daarom wil ik nu het volgende systeem opzetten en volgends mij worden dat ook wel macro's genoemd:

PHP:
1
$tpl  = '<html><head><body><p>{news, 5}</p><p>{body}</p>';


De functie getNews() moet nu aangeroepen worden met de waarde 5 voor $number. Ik heb hiervoor goed gezocht op internet en op de GoT zoekfunctie, maar vind nergens een tutorial hoe je {tokens} kunt uitbreiden zodat ze meer informatie door kunnen geven. Ik heb een aantal problemen:
  • Ik kan nu niet meer zoeken op vaste needles (zoals {news}), want de vorm kan verschillen ({news, 3}, {news, 8} of zelfs {news,4} -- zonder spatie)). Hoe begin ik met het zoeken naar zo'n vorm in de template?
  • Hoe roep ik vervolgens op correct wijze de (bijvoorbeeld getNews()) functies aan?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
Je zult waarschijnlijk met Regular Expressions moeten gaan werken :) Daarmee geef je als het ware een patroon op waaraan de items moeten voldoen die je wil replacen. Een regex voor jouw 'macro's' zou kunnen zijn:

code:
1
/\{([a-Z0-9,]+)\}/i


Met preg_replace kun je met de /e modifier ook functies zoals getNews aanroepen :)

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Beter is nog om preg_replace_callback te gebruiken; voorbeeldje:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$tpl = '<html><body>{news , 5 }</body></html>';
$html = preg_replace_callback('/{news\s*,\s*(\d+)\s*}/', 'news', $tpl);
echo $html;

function news($matches)
{
    $count = (int)$matches[1];
    $return = '';
    for ($i = 1; $i <= $count; $i++)
    {
        $return .= 'Newsitem ' . $i . '<br />';
    }
    return $return;
}

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Dank je! Zou iemand hiervan een iets duidelijker voorbeeld kunnen geven? Ik heb zojuist de preg_replace pagina op php.net bekeken, maar wordt niet veel wijzer daarvan. Er staat nergens kalm uitgelegd hoe je regular expressions opbouwt en wat alles betekent.

Zijn er trouwens nog extra (beveiligings-)issues waar je op moet letten bij het schrijven van een regular expression?

[edit] Oeps! te vroeg geblaat - Crisp heeft zojuist een uitgebreider voorbeeld gepost :)

[ Voor 11% gewijzigd door Reveller op 06-11-2004 17:00 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

P&W FAQ - Regular expressions
http://www.php.net/pcre

[ Voor 15% gewijzigd door crisp op 06-11-2004 16:58 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

crisp; misschien toch een kleine uitleg over het volgende?

je hebt {news, 5} oftewel '{nieuws met 5 artikelen en eindigend met }' maar in je code staat dan dit '/{news\s*,\s*(\d+)\s*}/' oftewel {news met (alles?) tot aan de comma en dan alles en dan het nummer en weer alles tot }

beetje vaag vertaald maar wel te begrijpen...

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

\s = whitespace

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Cavorka
  • Registratie: April 2003
  • Laatst online: 27-03-2018

Cavorka

Internet Entrepreneur

The Reg-Ex Coach, een tool om regular expressions te checken. Super handig, hiermee leer je echt heel snel met reg-exp's werken.

offtopic:
crisp, misschien een idee om deze link toe te voegen aan de FAQ, want ik post hem nogal regelmatig...

the-blueprints.com - The largest free blueprint collection on the internet: 50000+ drawings.

Pagina: 1