[php] Werking van een Template Parser

Pagina: 1
Acties:
  • 762 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik ben momenteel bezig met een template parser te schrijven. Deze zou dan een soort versimpelde versie moeten worden van de template parser die ik momenteel gebruik; TemplatePower.

Nu heb ik al het één en ander doorgelezen en de code van diverse classes (van template parsers) doorgekeken. Maar ik zie de "werking" van de template parser maar niet voor me. Ik wil namelijk zowel variabelen (á la: {VAR}) verwerken als diverse "blocks" (á la: <!-- START : block -->...<!-- END : block -->). En hier stuit ik dan op hét probleem; hoe pak ik dit aan?

Ik ben begonnen met een simpel opzetje. Ik heb twee regexes geschreven die alle blocks en variabelen uit de (geladen) template haalt. Alleen hoe verwerk ik deze? Als ik bijvoorbeeld in een block een variabele heb staan, hoe kan ik deze dan iedere keer dat het block opgeroepen wordt vervangen met een (wellicht) andere waarde?

Ik heb gelezen dat je dan het beste stack based moet gaan werken, maar hoe werk je volgens dit principe?

Alvast bedankt.

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Waarom wil je zo graag een template parser maken? Kijk eens naar andere mogelijkheden. PHP is zelf al een template parser, als je een beetje netjes werkt kunt je dus een mooie scheiding maken tussen code en output:
business.php:
PHP:
1
2
$GLOBALS['output']['titel']='homepage';
include('view.php');
view.php (tussen de lijnen staat het gehele bestand):
___________
PHP:
1
<?PHP $data=$GLOBALS['output']; ?>

<h1>
PHP:
1
<?PHP echo $data['titel']; ?>
</h1>
____________

Dit werkt enorm snel, je krijgt er standaard een error_reporting systeem, loopjes en vele andere handige functies bij. Denk er bijvoorbeeld aan dat je in layout 1 een hoofdletter bij de titel wilt hebben: www.php.net/ucfirst , en in layout 2 niet, dan kun je dit heel snel en netjes in je view.php bestand instellen.

[ Voor 85% gewijzigd door djluc op 18-02-2004 14:48 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb een tijd lang TemplatePower gebruikt, en dat bevalt me zeer goed. Nu ik echter ook weer wat ben gaan scripten voor enkele opdrachten van klanten, kan ik TemplatePower niet gebruiken voor die scripts. Dus ben ik maar gaan werken volgens een manier zoals jij aangeeft, alleen dat is mij der mate slecht bevallen. Dat ik toch wil werken met een template parser. Alleen omdat ik er nog weinig ervaring mee heb betreffende er één zelf te schrijven, post ik dit topic.

Het gebruik van een template parser beschouw ik als een groot voordeel. De HTML en PHP worden netjes van elkaar gescheiden. Aanpassingen zijn makkelijker te maken, de code is begrijpelijker, het staat veel netter en het is makkelijker werken (etc.)

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
NOFI hoor maar wat is er makkelijker aan te begrijpen, waarom is het beter gescheiden, en wat is er eenvoudiger aan te passen?
  • makkelijker te begrijpen? Je maakt gebruik van PHP, een van de meest egbruikte scripttalen de laatste tijd, een taal met de meest eenvoudige syntax, zeker als je in een view layer vrijwel alleen maar echo en foreach gebruikt. Daarnaast is een TemplateParser vrijwel altijd een andere weergave van in PHP ingebouwde functies.
  • Betere scheiding? Heb je mijn voorbeeldje van de hoofdletter gelezen? Dit is IMO een puur geval van het uiterlijk en heeft verder niets met de content te maken. (Even afgezien van het geval dat je namen in je titel wilt hebben) Dit zou met een templateparser niet te realiseren zijn, of je moet de source van de templateparser aan gaan passen.
  • Eenvoudiger aan te passen? Dat argument kan ik niet plaatsen, wat is er gemakkelijker aan het editten van een templatepowertemplate of een php-template?
  • snelheid? Wat denk je dat sneller is? Met een regexp de gehele template gaan onderzoeken, of gewoon PHP laten doen waar hij/zij goed in is?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Het is gewoon een voorkeur. De één werkt liever via jouw methode, de ander via een template parser in PHP en de ander werkt weer liever met XML/XSLT...

In jouw geval ontkom je er niet aan om HTML te gebruiken binnen je PHP code. En dat is gewoon iets wat ik liever niet heb.

Tevens, wanneer ik de komende tijd hiermee bezig houdt. Breid ik mijn kennis van PHP alleen maar uit en weet ik ook eens hoe je stack based te werk moet gaan...

Om mijn argument nog wat kracht bij te zetten; op de manier waarop jij werkt. Krijg je al snel een slordige HTML code. Ik neem aan dat je bij je eigen website (klik) dezelfde methode toepast, en als ik daar de bron van bekijk, dan ziet dat er niet erg netjes uit. Met een template parser is dit probleem opgelost en heb je naar mijn idee meer controle over de manier waarop je HTML code in elkaar zit.

[ Voor 35% gewijzigd door Verwijderd op 18-02-2004 15:09 ]


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Dus ben ik maar gaan werken volgens een manier zoals jij aangeeft, alleen dat is mij der mate slecht bevallen.
Maar zou je daar dan ook argumenten voor kunnen geven? Wat is jouw zo tegen gevallen, bepaalde code of iets anders specifieks?
Tevens, wanneer ik de komende tijd hiermee bezig houdt. Breid ik mijn kennis van PHP alleen maar uit en weet ik ook eens hoe je stack based te werk moet gaan...
Daar heb je 100% gelijk in.
over www.djluc.nl
Ik heb op mijn site yapter gebruikt, wat ik persoonlijk een fijne parser vind, maar toen ik deze techniek met layers ontdekte was ik al meteen overtuigd, vooral om de snelheid. Niet mooie HTML wil ik nu niet meteen zeggen, dit is mijn eerste test met divjes en CSS en vind het niet heel erg slecht gelukt als test. Wat jij bedoeld is waarschijnlijk de lege ruimtes en slechte indenting? Daarvoor moet je bij de source van www.tweakers.net zijn ;) Nee geintje, ik kreeg het niet voor elkaar om de source die de parser genereerd te achterhalen, vandaar dat ik er geen opmaak funtie overheen heb kunnen laten gaan.

[ Voor 44% gewijzigd door djluc op 18-02-2004 15:13 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
djluc schreef op 18 februari 2004 @ 15:09:
[...]
Maar zou je daar dan ook argumenten voor kunnen geven? Wat is jouw zo tegen gevallen, bepaalde code of iets anders specifieks?
Ten eerste heb je altijd HTML code binnen je PHP code. Dus is je HTML in de werkelijkheid nooit gescheiden van je PHP code.

Daarnaast heb je naar mijn idee veel minder invloed op de manier waarop je HTML cod e (bron) eruit ziet en ik vind dat ook dát in orde moet zijn als je een goede website maakt.

En om op mijn eerste punt terug te komen, als je dus veel HTML tussen je PHP code hebt zitten, dan wordt je code sowieso minder goed leesbaar. Althans, dat vind ik...

Btw, zie ook mijn edit (laatste alinea) in voorgaande post.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
djluc schreef op 18 februari 2004 @ 15:09:
over www.djluc.nl
Ik heb op mijn site yapter gebruikt, wat ik persoonlijk een fijne parser vind, maar toen ik deze techniek met layers ontdekte was ik al meteen overtuigd, vooral om de snelheid. Niet mooie HTML wil ik nu niet meteen zeggen, dit is mijn eerste test met divjes en CSS en vind het niet heel erg slecht gelukt als test. Wat jij bedoeld is waarschijnlijk de lege ruimtes en slechte indenting? Daarvoor moet je bij de source van www.tweakers.net zijn ;) Nee geintje, ik kreeg het niet voor elkaar om de source die de parser genereerd te achterhalen, vandaar dat ik er geen opmaak funtie overheen heb kunnen laten gaan.
Oké, maar... waarom gebruik jij voor díe website wél een parser á la Yapter? :)

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Verwijderd schreef op 18 februari 2004 @ 15:14:
[...]Ten eerste heb je altijd HTML code binnen je PHP code. Dus is je HTML in de werkelijkheid nooit gescheiden van je PHP code.
Het verschil tussen {variablenaam} en <?PHP echo $variablenaam; ?> OF wat sommigen gebruiken: <?=$variablenaam?> o.i.d. vind ik niet echt zo'n groot verschil.
Daarnaast heb je naar mijn idee veel minder invloed op de manier waarop je HTML cod e (bron) eruit ziet en ik vind dat ook dát in orde moet zijn als je een goede website maakt.
Ik begrijp je punt niet, waarom zou ik daar minder invloed op hebben? Ik zou zelf alle HTML nog door een XHTML validator kunnen sturen, probeer dat maar eens handig te doen met een template parser...
En om op mijn eerste punt terug te komen, als je dus veel HTML tussen je PHP code hebt zitten, dan wordt je code sowieso minder goed leesbaar. Althans, dat vind ik...
Ik niet, het is maar net hoe je het opmaakt Verder kun je met een goede editor heel duidelijk het verschil tussen de HTML en de PHP stukken zien omdat je syntax highlitening (spraakgeblek :X ) kunt gebruiken. Voor een template parser moe je daar vaak weer een speciale template voor maken. Voor PHP zijn die er al.
Oké, maar... waarom gebruik jij voor díe website wél een parser á la Yapter?
Toen ik het simpele CMSje dat ik voor die site gebruik gemaakt heb wist ik nog niets van dit alles af...

[ Voor 9% gewijzigd door djluc op 18-02-2004 15:23 ]


Acties:
  • 0 Henk 'm!

  • TRON
  • Registratie: September 2001
  • Laatst online: 16-09 13:13
@Obie: als je de sources van verschillende website van mij bekijkt, zal je ook zien dat mijn source er a la Tweakers.net uitziet. Waarom? Bij grotere pagina's scheelt het ontzettend met binnenhalen van de pagina's.

Mijn templates daarentegen hebben wel gewoon tabs, etc, dus het is en blijft voor mij heel overzichtelijk.

-toevoeging-
In mijn ogen is het handiger om met templates te werken, omdat je dan makkelijker van skin kunt veranderen, en eventueel je skins door anderen laten ontwerpen zonder dat je meteen je hele code kwijt bent.

[ Voor 27% gewijzigd door TRON op 18-02-2004 15:24 ]

Leren door te strijden? Dat doe je op CTFSpel.nl. Vraag een gratis proefpakket aan t.w.v. EUR 50 (excl. BTW)


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

Verwijderd schreef op 18 februari 2004 @ 15:14:
[...]


Ten eerste heb je altijd HTML code binnen je PHP code. Dus is je HTML in de werkelijkheid nooit gescheiden van je PHP code.

Daarnaast heb je naar mijn idee veel minder invloed op de manier waarop je HTML cod e (bron) eruit ziet en ik vind dat ook dát in orde moet zijn als je een goede website maakt.

En om op mijn eerste punt terug te komen, als je dus veel HTML tussen je PHP code hebt zitten, dan wordt je code sowieso minder goed leesbaar. Althans, dat vind ik...
Dat hoeft niet en hangt helemaal van je coding-style af. Je HOEFT geen complete stukken html te genereren ergens. Je kunt ook zorgen dat je VOOR dat je aan de HTML begint je netjes je data op orde hebt. Dan kun je in de html met simpele loopjes e.d. een complete template genereren.

Persoonlijk ben ik het dus met djluc eens. PHP is al een template parser als je het goed gebruikt. Om hier dan met een uitgebreide regexp/etc nog een template parser in te gaan zitten bouwen is dus nogal overbodig.

Als je al templates wilt gebruiken kijk dan naar XML/XSLT. Dan hebben je templates wat meer toegevoegde waarde, namelijk: compatibiliteit.

Acties:
  • 0 Henk 'm!

Verwijderd

Template parsers schrijven is erg leuk om te doen, maar het is wel enorm lastig, tenminste als je je niet wil beperken tot het simpelweg replacen van vars.

Je komt bij de betere template parsers altijd uit op stackbased parsers (of met grammatica, maar dit is het echte werk). Ze zijn niet alleen het snelst, maar er valt volgens dit principe ook beter te controleren op nesting van tags.

Stack van een template:

[bold]
[italic]
[/italic]
[/bold]

Deze stack heeft een lengte van 4. Zodra je iets in behandeling neemt pak je de eerste van de stack, in dit geval [bold] met index 0, en de laatste van de stack, [/bold] met index 3. Je kunt op een dergelijke manier heel goed controleren op valide nesting van tags.

Ik ben er zelf ook een tijdje mee bezig geweest en kwam behoorlijk ver, met attributes op tags etc, maar liep een beetje vast op het moment van oa looping en nested loops in een template en variabelen die dan worden gezet.

Het belangrijkte is in principe dat je je document opdeelt naar een stack, zodat je adhv die stack door je template kunt gaan.

[ Voor 3% gewijzigd door Verwijderd op 18-02-2004 15:26 ]


Acties:
  • 0 Henk 'm!

  • We Are Borg
  • Registratie: April 2000
  • Laatst online: 14:26

We Are Borg

Moderator Wonen & Mobiliteit / General Chat
TRON schreef op 18 februari 2004 @ 15:23:
In mijn ogen is het handiger om met templates te werken, omdat je dan makkelijker van skin kunt veranderen, en eventueel je skins door anderen laten ontwerpen zonder dat je meteen je hele code kwijt bent.
Zo zie ik het ook, maar wellicht dat er betere opties zijn dus daarom volg ik dit topic op de voet ;).

Zelf ben ik ook begonnen met een template parser. Ik weet dat het werken met een template parser je proces vertraagd, maar ik wil kost wat kost mijn HTML van mijn PHP scheiden.

Zo kan iemand eenvoudig de template veranderen (puur html) en hoeft hij niet tussen de php code te rotsooien met alle gevolgen van dien.

Wanneer de TS'er het wilt, zet ik vanavond wel een klein voorbeeld neer die drm me gemaild heeft. Gaat over hetzelfde onderwerp :)

Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

In mijn ogen is het werken met een aparte template parser alleen nuttig als er mensen aan templates moeten werken die niet technisch ingesteld zijn. Als je dan al gebruik maakt van een template parser moet de syntax om variabelen te gebruiken in je templates simpel zijn.

Smarty bijvoorbeeld, is een heel uitgebreide template engine. Er wordt veel functionaliteit geboden om variabelen in templates te bewerken en is dus erg flexibel. Nadeel hiervan is dat de smarty syntax in templates vaak qua complexiteit niet veel meer verschild met de php syntax. Je kan dan dus gaan overwegen om geen extra template parser te gebruiken. De mogelijkheid die djluc noemt is dan een goede. Voordeel hiervan is dat de overhead van een template parser vermeden wordt.

Zonder template engine:
database -> php -> html

Met template engine:
database -> php -> template engine -> html

moraal van het verhaal. Als je een template engine gebruikt hou hem heel simpel. Anders kan je net zo goed met php in je templates werken. (een misvatting is dat je zonder template engine niet met templates kan werken, een template engine is in feite een extra laag bovenop php om syntax binnen html simpel te houden.)

[ Voor 10% gewijzigd door Brakkie op 18-02-2004 15:49 ]

Systeem | Strava


Acties:
  • 0 Henk 'm!

  • MatHack
  • Registratie: Oktober 2001
  • Niet online

MatHack

Dev by day, Gamer by night

Als je alles in PHP wil doen (dus zonder template parsers o.i.d.), kan ik je het volgende artikel aanbevelen: Beyond the Template Engine, dit gaat over het scheiden van de business & view lagen, maar dan volledig met PHP.

There's no place like 127.0.0.1


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Om even te reageren op Gordijnstok z'n post. Het is iig niet de bedoeling dat ik een template parser ga maken waarin complete if-constructies in verwerkt zijn. Laat dat duidelijk zijn, want dan ben ik ook van mening dat je het beter maar kunt laten...

Ik wil het vrij simpel (voor zover je dit in deze zin kunt toepassen) houden. Globaal gezien wil ik er 3 mogelijkheden mee verzorgen:

• Template variabelen vervangen (zoals: {VAR})
• Blocks gebruiken (stukken HTML juist wél of niet laten zien, etc.)
• Invoegen van andere templates (zodat je in elk bestand een "algemene" header/footer kunt plaatsen)

En dit dus naar het idee van TemplatePower (dus zelfde syntax qua bovenstaande mogelijkheden).

De belangrijkste reden hiervoor is dan de scheiding van HTML en PHP. Want als je goed met CSS en div's werkt (wat ik al doe) dan valt de reden "Het gemakkelijk veranderen van skins" eigenlijk af...
We Are Borg schreef op 18 februari 2004 @ 15:36:
Wanneer de TS'er het wilt, zet ik vanavond wel een klein voorbeeld neer die drm me gemaild heeft. Gaat over hetzelfde onderwerp :)
Dat zou zeker mooi zijn :)
Bosmonster schreef op 18 februari 2004 @ 15:25:

Als je al templates wilt gebruiken kijk dan naar XML/XSLT. Dan hebben je templates wat meer toegevoegde waarde, namelijk: compatibiliteit.
Het ligt er net aan op welke manier je compatibiliteit bedoeld. Werk je via serverside parsing, dan moet die server wel ondersteuning hebben van Sablotron (schrijf ik het goed?) of PHP5. Werk je client-side dan heb je alleen de nieuwste browsers die het ondersteunen (als ik het goed heb).

[ Voor 10% gewijzigd door Verwijderd op 18-02-2004 16:17 ]


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Om even te reageren op Gordijnstok z'n post. Het is iig niet de bedoeling dat ik een template parser ga maken waarin complete if-constructies in verwerkt zijn. Laat dat duidelijk zijn, want dan ben ik ook van mening dat je het beter maar kunt laten...
Fijn dat je dat nu pas meld. In dat geval is er nog wel iets te zeggen voor een meer eenvoudige syntax. Maar wat doe je als je straks een if in je template-based site nodig hebt? Overstappen naar een andere techniek of snel een if functionaliteit aan je script toevoegen->je had beter een andere techniek kunnen gebruiken.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
djluc schreef op 18 februari 2004 @ 16:20:
[...]
Fijn dat je dat nu pas meld. In dat geval is er nog wel iets te zeggen voor een meer eenvoudige syntax. Maar wat doe je als je straks een if in je template-based site nodig hebt? Overstappen naar een andere techniek of snel een if functionaliteit aan je script toevoegen->je had beter een andere techniek kunnen gebruiken.
Elke if-constructie die je maakt met een template kun je ook maken met PHP... Dus ik zie geen reden daarvoor om dat erin te bouwen (blocks zijn voldoende functioneel).

Maar ik dacht trouwens dat ik duidelijk genoeg was in m'n openingspost (zie hieronder), zo niet. Mijn excuses.
Ik wil namelijk zowel variabelen (á la: {VAR}) verwerken als diverse "blocks" (á la: <!-- START : block -->...<!-- END : block -->). En hier stuit ik dan op hét probleem; hoe pak ik dit aan?

Acties:
  • 0 Henk 'm!

  • dusty
  • Registratie: Mei 2000
  • Laatst online: 15-09 18:24

dusty

Celebrate Life!

Verwijderd schreef op 18 februari 2004 @ 15:26:
[..]
Je komt bij de betere template parsers altijd uit op stackbased parsers (of met grammatica, maar dit is het echte werk). Ze zijn niet alleen het snelst, maar er valt volgens dit principe ook beter te controleren op nesting van tags.
[..]
Stackbased parsers zijn niet het snelst. Als je het namelijk goed doet is een recursieve template parser namelijk sneller. Maar dat is wel lastiger te programmeren dan een stackbased parser.

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


Acties:
  • 0 Henk 'm!

  • We Are Borg
  • Registratie: April 2000
  • Laatst online: 14:26

We Are Borg

Moderator Wonen & Mobiliteit / General Chat
[rml]drm in "[ PHP/HTML] PHP en HTML scheiden in code."[/rml]

Voorbeeld hoe je het kan aanpakken. Dit heb ik als uitgangspunt genomen voor mijn template parser. Uiteraard wat aangepast en in een functie gegoten :).

Hiermee kan (vast vele andere mogelijkheden) je dus het eerste deel van je vragen oplossen. Het veranderen van een {INHOUD_FOOTER} naar jouw input.

Het parsen van die blokjes ga ik vanavond even voor zitten. Zal vast iets heel ranzigs worden qua code (ben echt nog enorm nieuw met php), maar misschien kan je het gebruiken als opzet :)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
De variabelen lukken wel en het invoegen van andere templates lijkt mij ook niet echt een groot probleem. Daarentegen zijn de blocks wel weer een probleem, ik heb geen idee hoe ik dat goed kan krijgen...

Acties:
  • 0 Henk 'm!

  • We Are Borg
  • Registratie: April 2000
  • Laatst online: 14:26

We Are Borg

Moderator Wonen & Mobiliteit / General Chat
Bedoel je dit:
<html>

<head>

<title>Opzet</title>

</head>

<body>

<!—START: naam_blokje_1 à

<p>Dit is tekst 1</p>

<!—END: naam_blokje_1 à

<p>Gewoon wat tekst tussendoor wat altijd getoond moet worden</p>

<!—START: naam_blokje_2 à

<p>Dit is tekst 2 </p>

<!—END: naam_blokje_2 à

</body>

</html>


Een kleine pagina met wat comments gebruikt als bloknamen. Nu wil ik graag dat ik het bestand ophaal met php (geen probleem) en dan de blokjes wel of niet toon. Bijvoorbeeld:


<?php


Implode (‘een file’) {


$template_parse_niet->$blok[‘naam_blokje_1’];

$template_parse_wel->$blok[‘naam blokje_2’];

}

?>

Even erg snel en alleen ter verduidelijking
Klein stukje van een email :). Als je dit bedoelt, heb ik vanavond een klein opzetje voor als ik eruit kom :P

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
We Are Borg schreef op 18 februari 2004 @ 16:44:
Bedoel je dit:

[...]

Klein stukje van een email :). Als je dit bedoelt, heb ik vanavond een klein opzetje voor als ik eruit kom :P
Dat is inderdaad wat ik bedoel. Ik wens je veel succes :) Ik zelf probeer het ook nog maar eens.

Mocht het je btw helpen, met deze twee regexes haal je alle variabelen en blocks uit je template:

PHP:
1
2
preg_match_all("/<!-- START : ([a-zA-Z\._-]+) -->\r\n(.*?)\r\n<!-- END : \\1 -->/sm", $input, $blocks);
preg_match_all("/\{([a-zA-Z\._-]+)\}/i", $input, $variables);

[ Voor 39% gewijzigd door Verwijderd op 18-02-2004 16:49 ]


Acties:
  • 0 Henk 'm!

  • We Are Borg
  • Registratie: April 2000
  • Laatst online: 14:26

We Are Borg

Moderator Wonen & Mobiliteit / General Chat
Verwijderd schreef op 18 februari 2004 @ 16:47:
[...]
Dat is inderdaad wat ik bedoel. Ik wens je veel succes :) Ik zelf probeer het ook nog maar eens.
Zit me trouwens te bedenken, dat het misschien veel leuker is om de verschillen te zien tussen beide codes (van jou en van mij)

Kortom, hier de opzet die ik heb gekregen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
eel simpel voorbeeldje:

function bestwelzinloos ( $welofniet, $text ) {
    if ( $welofniet == 'wel' ) {
       return $text;
    } else {
       return '';
    }
}

$str = '
    [wel]dit wel[/wel]
    [niet]en dit niet[/niet]
';

$str = preg_replace (
    '/\\[(wel|niet)](.*)\\[\/\1]/es',
    'bestwelzinloos ( \'$1\', \'$2\' )',
    $str
);
echo $str;


Puur een opzet, maar het idee is gelijk duidelijk :)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik werk dan in een class, en die ziet er tot nu toe zo uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class template
{
    var $input;
    var $blocks = array();
    var $variables = array();
    var $used = array();

    function load($file)
    {
        if(file_exists($file))
        {
            $this->input = implode("", file($file));
        }
    }

    function init()
    {
        preg_match_all("/<!-- START : ([a-zA-Z\._-]+) -->\r\n(.*?)\r\n<!-- END : \\1 -->/sm", $this->input, $this->blocks);
        preg_match_all("/\{([a-zA-Z\._-]+)\}/i", $this->input, $this->variables);
    }

    function assign($array)
    {
        if(is_array($array))
        {
            while(list($key, $value) = each($array))
            {
                $this->used[] = "V:" . $key;
                // $this->input = str_replace("{" . $key . "}", $value, $this->input);
            }
        }
        else
        {
            $this->error("Er wordt een ongeldige bewerking uitgevoerd op de functie <code>assign</code>, de invoer is geen array");
        }
    }

    function block($name)
    {
        $this->used[] = "B:" . $name;

        while(list($key, $value) = each($this->blocks[0]))
        {
            if($this->blocks[1][$key] == $name)
            {
                $this->input = str_replace($this->blocks[0][$key], $this->blocks[2][$key], $this->input);
            }
        }
    }

    function process()
    {
        while(list($key, $value) = each($this->blocks[1]))
        {
            !in_array("B:" . $value, $this->used) ? $this->input = str_replace("\r\n" . $this->blocks[0][$key] . "\r\n", "", $this->input) : "";
        }
    }

    function error($error)
    {
        exit($error);
    }

    function output()
    {
        print($this->input);
    }
}
Sorry voor het verneuken van de layout ;)

[ Voor 19% gewijzigd door Verwijderd op 18-02-2004 16:56 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb een vrij interessant artikel gevonden, waar een soort van blocks-methode wordt toegepast. Zie hier.

Acties:
  • 0 Henk 'm!

  • We Are Borg
  • Registratie: April 2000
  • Laatst online: 14:26

We Are Borg

Moderator Wonen & Mobiliteit / General Chat
Mwah, ik maak het liever zelf. Niet omdat ik zo goed dingen zelf kan maken, maar daar leer je wat meer van dan bestaande code aanpassen. Ik wil ook niet al te veel code gebruiken. Ik post vanavond mijn werkje wel :)

Acties:
  • 0 Henk 'm!

Verwijderd

dusty schreef op 18 februari 2004 @ 16:30:
[...]

Stackbased parsers zijn niet het snelst. Als je het namelijk goed doet is een recursieve template parser namelijk sneller. Maar dat is wel lastiger te programmeren dan een stackbased parser.
Je hebt op zich wel gelijk, maar dan moet je wel verrot briljant programmeren. Tegen de tijd dat je met een recursieve template parser alle functionaliteit erin hebt die makkelijker met een stack based parser te bereiken is, veroorzaak je denk ik zoveel overload aan extra of zwaardere code dat de snelheidswinst verloren is.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

dusty schreef op 18 februari 2004 @ 16:30:
[...]

Stackbased parsers zijn niet het snelst. Als je het namelijk goed doet is een recursieve template parser namelijk sneller. Maar dat is wel lastiger te programmeren dan een stackbased parser.
kun je uitleggen hoe een recursieve parser dan te werk gaat? En een stack is ook recursief, wat is het verschil dan? Een goede parser doorloopt de source iig maar 1 keer, van begin tot eind

.edit: bliep, er is geen echt verschil, behalve dat een recursieve parser fysiek ook echt met recursieve functies is geprogrammeerd, waardoor ik me dus afvraag of dat idd ook sneller is, eerder langzamer juist. Function calls kosten meer overhead dan zelf een stack-datastructuur bijhouden en iteratief door de tokenstream heen stappen. Behalve implementatie is er feitelijk geen verschil tussen de 2 methoden: beide bouwen al dan niet impliciet een stack op

(bovendien vind ik php nog altijd de beste template parser :Y))

[ Voor 29% gewijzigd door .oisyn op 18-02-2004 18:41 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Ik denk dat de snelheid verschillen tussen daadwerkelijk van een stack parsen, ipv recursief op de gehele source, voor het grootste gedeelte afhankelijk is van de functionaliteit.

Voor zaken als looping, if else constructies, switch case constructies, evalueren van variabelen die runtime worden gezet etc. ben je sneller af met een voor het oog stack based parser.

Als je puur replacements doet, een recordset output of variabelen plempt op voorgedefinieerde plekken, dan ben je met een recursive parser sneller af. Je hoeft nl. minder lookups te gaan doen.

Acties:
  • 0 Henk 'm!

  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
Ik heb zelf een template-parser geschreven, met een beetje zoeken op GoT vindt je nog wat posts van mij terug waarin ik uitleg hoe ik em heb gemaakt :)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 18 februari 2004 @ 19:03:
Als je puur replacements doet, een recordset output of variabelen plempt op voorgedefinieerde plekken, dan ben je met een recursive parser sneller af. Je hoeft nl. minder lookups te gaan doen.
De vraag is of je zoiets überhaupt een parser kunt noemen ;)
Maar verder ben ik het oneens met je stelling. Als je iets als preg_replace () gebruikt dan is het sowieso geen parser, en ik had het meer over parsers in het algemeen (waarbij het doel feitelijk niets te maken heeft met het parsen zelf)

[ Voor 25% gewijzigd door .oisyn op 18-02-2004 20:36 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • We Are Borg
  • Registratie: April 2000
  • Laatst online: 14:26

We Are Borg

Moderator Wonen & Mobiliteit / General Chat
Ik ga wel even kijken naar het geposte voorbeeld, want het voorbeeld wat ik eerdere postte gaat niet helemaal werken. Kortom, geen code van mij maar blijf het topic wel volgen :)

Edit: wat .oisyn dus zegt :P

[ Voor 9% gewijzigd door We Are Borg op 18-02-2004 20:39 ]


Verwijderd

Topicstarter
Heeft iemand al enige bevindingen gemaakt? :) Ik ben helaas nog steeds niet verder gekomen dan dat ik al was, 't idee blijft telkens vast lopen...

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Verwijderd schreef op 19 februari 2004 @ 12:54:
Heeft iemand al enige bevindingen gemaakt? :) Ik ben helaas nog steeds niet verder gekomen dan dat ik al was, 't idee blijft telkens vast lopen...
Ik bouw nu een site (online-crm) waar alle input/output via xml/xslt gaat.
1) Het kost wat extra denkwerk
2) De gehele structuur van de applicatie word automatisch beter
3) Uiteindelijk gaat de ontwikkeling vele malen sneller
4) Je kunt heel makkelijk aangepaste output genereren voor andere clients (bijvoorbeeld wml voor pocket-pc's)
5) Bouwen van affiliates is zeer makkelijk
6) Koppelen van de database is simpel (uploaden en downloaden van data)
7) Door dit te doen m.b.v. apache/php/mysql kost het zeer weinig i.p.v. tonnen!

Zo poep ik xml rechtstreeks in mysql:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
        $extid = selectSingleNodeContent($domdoc, "//id") or crm_die(3, 'sync: can\'t find id');
        
        $sql = 'SELECT `id` '
         . ' FROM `klantkaart` '
         . ' WHERE `extid` = \'' . mysql_real_escape_string($extid) . '\' LIMIT 0, 2';
        $result = mysql_query($sql) or crm_die(4, "sync: mysql query error during id searching:", mysql_error());
        if ($row = mysql_fetch_array($result))
        { 
          // klantkaart is already present in the database
          $id = $row[0];
        } 
        else
        {
          $sql = 'INSERT INTO `klantkaart` (`extid`) '
           . ' VALUES  (\'' . mysql_real_escape_string($extid) . '\');';
          $result = mysql_query($sql) or crm_die(5, "sync: mysql query error with new:", mysql_error());
          $id = mysql_insert_id();
        };
        
        $klantkaart = selectSingleNode($domdoc, "//klantkaart");
        
        $columns = array(   'afspraaktijd' => selectSingleNodeContent($domdoc, '//klantkaart/status/afspraakdatum').' '
                                                .selectSingleNodeContent($domdoc, '//klantkaart/status/afspraaktijd'),
                            'omschrijving' => selectSingleNodeContent($domdoc, '//klantkaart/bedrijf/handelsnaam1_30'). ' / '
                                                .selectSingleNodeContent($domdoc, '//klantkaart/bedrijf/handelsnaam2_30'),
        
                            'telefoonnr' => selectSingleNodeContent($domdoc, '//klantkaart/bedrijf/telefoonnummer'),
                            'postcode' => selectSingleNodeContent($domdoc, '//klantkaart/bedrijf/va_postcode'),
                            'cpnaam' => selectSingleNodeContent($domdoc, '//klantkaart/contactpersoon/xtra/volledig'),
        
                            'actie' => selectSingleNodeContent($domdoc, '//klantkaart/status/huidactiecode'),
                            'plaats' => selectSingleNodeContent($domdoc, '//klantkaart/bedrijf/va_woonplaats_nen'),
                            'afspraakstop' => '0000-00-00 00:00:00',
                            'vertegenwoordiger' => selectSingleNodeContent($domdoc, '//klantkaart/status/vertegenwoordiger'),
                            'xml' => $domdoc->dump_node($klantkaart));
        
        $columns['cpnaam'] = wsstrip($columns['cpnaam']);
        if ($columns['cpnaam'] == '()') {
            $columns['cpnaam'] = '';
        }
        
        if (selectSingleNodeContent($domdoc, '//klantkaart/status/actiedoor') != 'O') {
            $columns['vertegenwoordiger'] = 'SEL';
        }                   
                            
        $addcolumn = false;
        $sql = 'UPDATE `klantkaart` SET';
        foreach ($columns as $key => $value)
        {
          $value = mysql_real_escape_string(wsstrip($value));
          if ($addcolumn) {
              $sql .= ",";
          }
          $sql .= " `$key` = '$value'";
          $addcolumn = true;
        }
        $sql .= " WHERE `id` = '$id' LIMIT 1 ;";
        
        mysql_query($sql) or crm_die(6, "sync: mysql query error with update: ", mysql_error());
        
        $domdoc->free();
        crm_die(0, "success!");

seweso's blog


Verwijderd

dus.... wat parse je nu? :D

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Ik? eeh xml natuurlijk. Maar of ik het pars kun je over discussieren omdat ik het uitbesteed aan domxml. Maar ja je gebruikt altijd wel een hulpmiddel. Maar ik denk altijd: waarom fietsen als je een auto hebt. Natuurlijk kost zo'n auto een paar centen maar dan heb je wel wat: leesbare en overdraagbare code!

seweso's blog


Acties:
  • 0 Henk 'm!

  • We Are Borg
  • Registratie: April 2000
  • Laatst online: 14:26

We Are Borg

Moderator Wonen & Mobiliteit / General Chat
Verwijderd schreef op 19 februari 2004 @ 12:54:
Heeft iemand al enige bevindingen gemaakt? :) Ik ben helaas nog steeds niet verder gekomen dan dat ik al was, 't idee blijft telkens vast lopen...
Misschien dat je wat aan mijn code hebt:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$str2 = ' 
    <!--BEGIN:wel-->dit wel<!--STOP:wel-->
    <!--BEGIN:niet-->en dit niet<!--STOP:niet-->
    dit is html buiten de comments
'; 
function dont_parse ( $blockname, $str2 ) {

$str2 = 
preg_replace 
( '/\<!--BEGIN:('.$blockname.')-->(.*)\<!--STOP:\\1-->/es', '', $str2 );
return $str2;
}

echo dont_parse ( 'wel' , $str2 );


Kies een blok wat je niet wilt tonen en gebruik de functie om deze blokken eruit te halen :). Nog niet helemaal wat ik wil, maar het begin is er :). Laat maar weten of je er wat aan hebt.

Als iemand opmerkingen of tips heeft dan hoor ik dat graag ;).

Topic gekicked omdat Obie geen email adres heeft ingevuld en misschien heeft hij er wat aan

[ Voor 7% gewijzigd door We Are Borg op 04-03-2004 15:38 ]


Acties:
  • 0 Henk 'm!

  • eborn
  • Registratie: April 2000
  • Laatst online: 18-09 19:03
Het is wel heel erg leuk om met template parsers te experimenteren. De afgelopen maanden ben ik zelf voor een paar sites bezig geweest met m'n eigen (redelijk simpele) parser. Momenteel ondersteund hij if-else-blocks, loops (foreach), variabelen setten (en gebruiken) en het 'cachen' van templates.

Op zich is het principe redelijk simpel:
• Eerst kijk ik of er een cache-file bestaat. Deze file bevat een geserialiseerde versie van de functie-boom. Als de file bestaat lezen we dit array direct in.
• Als er geen cache is dan lees ik de file commando voor commando in. Hierbij worden regexen gebruikt, zodat er per functie variabele parameters ingesteld kunnen worden.
• Als de hele boom ingelezen is saven we hem eventueel als cache
• Vervolgens doe ik een zoek-en-vervang van de globale paren (key->value)
• Als alles gereed is loop ik door de boom en roep ik een recursieve functie op de root aan. De onderliggende functies kunnen vervolgens zelf bepalen wat ze met hun kinderen doen. Een if kan bepaalde content overslaan (aan de hand van de expressie) en een loopje kan een x aantal keer loopen, waarbij je binnen de template toegang krijgt tot de variabelen van het te doorlopen array.

If'jes en loops zijn natuurlijk binnen elkaar te plaatsen, zodat je de informatie uit PHP nog enigsinds kunt 'bewerken'. Uiteindelijk komt alle output in een string die in zijn geheel geoutput wordt. Er zal vast nog zat te optimaliseren zijn (momenteel is de hele klasse 433 regels code), maar ik heb nog geen tijd en zin gehad om me daar echt in te verdiepen. Het werkt nu namelijk goed voor het doel waar ik het voor ontworpen heb. En het was leuk om te doen :)

[ Voor 8% gewijzigd door eborn op 05-03-2004 00:25 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Tot zoiets dergelijks kwam ik ook. Ik heb tevens een regex gemaakt die alle blocks uit de template haalt. Maar dan komt pas het lastigste deel, helemaal wanneer je ook template-variabelen wilt toepassen ({VAR}) want de ene var moet alleen getoond worden mits deze in het block staat waarop deze geset is. En daarnaast moeten blocks ook nu kunnen loopen, waarbij de mogelijke template-variabelen een andere waarde moeten hebben. Ik loop daar voornamelijk op vast...

Iemand die ik ken is er nu ook weer meebezig, wel wat langer dan ik ben. Wellicht kan hij ons een handje helpen... mocht dat zo zijn. Dan zal ik het uiteraard hier posten :)

[ Voor 23% gewijzigd door Verwijderd op 05-03-2004 09:37 ]


Acties:
  • 0 Henk 'm!

  • eborn
  • Registratie: April 2000
  • Laatst online: 18-09 19:03
Verwijderd schreef op 05 maart 2004 @ 09:37:
Maar dan komt pas het lastigste deel, helemaal wanneer je ook template-variabelen wilt toepassen ({VAR}) want de ene var moet alleen getoond worden mits deze in het block staat waarop deze geset is.
Op zich kun je dat makkelijk oplossen. Als je elke tak aan de boom zijn eigen content geeft (dus een if-block heeft onder de waarde content de inhoud van het blok staan), dan kun je zeggen: if-true then add content to outputbuffer.
En daarnaast moeten blocks ook nu kunnen loopen, waarbij de mogelijke template-variabelen een andere waarde moeten hebben. Ik loop daar voornamelijk op vast...
Dat is inderdaad een ander punt. In mijn geval gebruik ik gewoon een reference naar een array waar alle variabelen instaan. Elke loop heeft drie parameters: type (momenteel alleen array), var (de naam van het array binnen mijn PHP-to-template waarden) en name. De laatste is belangrijk. Alle functies die onder mijn loop hangen krijgen toegang tot de variabelen {<loopname>_<key>} (of als het array alleen maar values bevat {<loopname>_value}). Op deze manier kun je meerdere loops in elkaar hangen, waarbij elke diepere loop zijn eigen waarden kan terugkoppelen naar de template.

[ Voor 9% gewijzigd door eborn op 05-03-2004 10:26 ]


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

We Are Borg schreef op 18 februari 2004 @ 16:38:
[rml]drm in "[ PHP/HTML] PHP en HTML scheiden in code."[/rml]

Voorbeeld hoe je het kan aanpakken. Dit heb ik als uitgangspunt genomen voor mijn template parser. Uiteraard wat aangepast en in een functie gegoten :).

Hiermee kan (vast vele andere mogelijkheden) je dus het eerste deel van je vragen oplossen. Het veranderen van een {INHOUD_FOOTER} naar jouw input.

Het parsen van die blokjes ga ik vanavond even voor zitten. Zal vast iets heel ranzigs worden qua code (ben echt nog enorm nieuw met php), maar misschien kan je het gebruiken als opzet :)
Simpele find/replace is best een leuke optie, maar om in jouw voorbeeld te blijven: wat nu als iemand als username {INHOUD_FOOTER} kiest of op een forum die tekst in een post plaatst? :)

Professionele website nodig?

Pagina: 1