[PHP]Templates modulair opbouwen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Ik ben bezig met eigen framework, en heb een simpele template engine.

Include bestanden waar PHP echo's instaan, niet echt netjes maar het werkt.

Maar ik wil het uitbreiden zoals Smarty met smart tags, en ook looping e.d. inbouwen.

Nu kom ik alleen tot het punt hoe een template opbouwen.

Zoals meeste sites bestaat een template uit een header, een menu links en een footer.

Nu moet er code natuurlijk (dynamisch) geparsed worden in het menu, inlogde gebruiker e.d.

Maar hoe kan ik dit makkelijk verwerken? Wat ik nu heb:
lib/template.php bevat de template class.
index.php bevat alle php code voor de index, deze roept weer de template class aan:
PHP:
1
2
3
4
5
6
$Template = new Template();
$Template->Title = 'Page title';
$Template->Set('TestText', 'text');
echo $Template->Header();
echo $Template->Fetch('index');
echo $Template->Footer();


Nu is het alleen lastig om hier modules in te verwerken, Header is een aparte functie die weer verwerkt is in de klasse.

PHP:
1
2
3
4
5
function Header()
{
global $_USER, $_LANG;
return $this->HeaderHTML().$this->Fetch('header');
}


Nu wil ik hier vanaf, ik wil geen functies meer in de hoofdklasse die te maken hebben met dynamische content.

Wat zou een makkelijke manier zijn om hier vanaf te stappen?

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Ik begrijp er geen fluit van. Wat wil je nou precies?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • flashin
  • Registratie: Augustus 2002
  • Laatst online: 17-12-2023
Je logica is niet zoals je zou moeten nadenken. Je gebruikt middelen nu als doel terwijl je meer naar het resultaat moet kijken. Hoe kom ik in een combinatie van snelheid en kwaliteit tot een goed eindresultaat?

- als je echt meer controle over je templates wilt, gebruik een goede templateparser.
- begin met een header en een footer te includen. hierin kun je uiteraard gewoon het menu in maken

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
flashin schreef op zaterdag 14 februari 2009 @ 13:30:
Je logica is niet zoals je zou moeten nadenken. Je gebruikt middelen nu als doel terwijl je meer naar het resultaat moet kijken. Hoe kom ik in een combinatie van snelheid en kwaliteit tot een goed eindresultaat?

- als je echt meer controle over je templates wilt, gebruik een goede templateparser.
- begin met een header en een footer te includen. hierin kun je uiteraard gewoon het menu in maken
Dat doe ik nu ook, die template class bevat een template parser.

Misschien dat ik niet duidelijk ben geweest.

Ik heb mijn eigen template parser. Als ik index.php aanroep, dan wordt de index.php template geparsed. Nu wil ik een methode vinden die ook de header en footer kan parsen, zonder dat ik de code hoef te verstoppen in de template class zelf.

Acties:
  • 0 Henk 'm!

  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Hmm ... ik ben eigenlijk van mening dat een template parser 'dom' moet zijn. Een parser moet zich helemaal niet bezig houden met of een onderdeel van wat hij parst een header danwel een footer is. Hij moet gewoon een combinatie maken van willekeurige gegevens en een willekeurig template, door ze op zo'n manier door elkaar te husselen, dat er iets uit komt rollen wat je naar de browser stuurt.

Zelf heb ik het zo aangepakt, dat de parser ofwel een verwijzing naar een bestand (het template), ofwel een string (de inhoud van het template) meekrijgt. Daarnaast krijgt de parser de gegevens aangereikt die hij in het template moet zetten, op zo'n manier, dat hij weet welke gegevens op welke plek in het template moeten komen.

Als template geladen is en de te-parsen-data is aangereikt, dan gaat de parser z'n "ding" doen en krijg je het resultaat terug.

Door de parser dom te houden, en dus niet specifiek in te richten rond een header, een footer of een menu, wordt hij veel generieker en dus breder inzetbaar. Als je hem immers rond een bepaalde indeling opbouwt ... waar houdt het dan op? Als er een kolom bijkomt in je website, moet er dan een extra functie in je parser komen "ParseColumn()", en "ParseForm()" voor het formulier? Dan is in mijn optiek het einde zoek en eindig je met een gedrocht van een class, die ook nog eens per website aangepast moet worden.

De parser die ikzelf gebouwd heb en voor zo'n beetje alles gebruikt, is bijzonder light-weight en zet ik niet alleen in voor websitepagina's, maar ook voor formulieren, e-mailberichten, etc. etc.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Eleganter en breder inzetbaar dan wat Smarty bijvoorbeeld doet gaat het je niet lukken denk ik.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
gvanh schreef op zaterdag 14 februari 2009 @ 14:32:
Door de parser dom te houden, en dus niet specifiek in te richten rond een header, een footer of een menu, wordt hij veel generieker en dus breder inzetbaar. Als je hem immers rond een bepaalde indeling opbouwt ... waar houdt het dan op? Als er een kolom bijkomt in je website, moet er dan een extra functie in je parser komen "ParseColumn()", en "ParseForm()" voor het formulier? Dan is in mijn optiek het einde zoek en eindig je met een gedrocht van een class, die ook nog eens per website aangepast moet worden.
Dat is wat ik nu heb, en weer van af wil. Als ik een module erbij wil maken moet ik weer in de source gaan zitten spitten.
NMe schreef op zaterdag 14 februari 2009 @ 15:03:
Eleganter en breder inzetbaar dan wat Smarty bijvoorbeeld doet gaat het je niet lukken denk ik.
Hm ja, dat kan inderdaad, dat is wat ik nu ook doe, alleen dan niet in de template zelf.

Maar hoe parsed Smarty die included template dan weer, aangezien er geen PHP code in hoort te staan, wat als die nu dynamische content moet weergeven?

[ Voor 42% gewijzigd door Megamind op 14-02-2009 15:09 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Ik weet niet of ik je kan helpen maar dit is wel handig:
http://wmcity.nl/scripts.php?actie=bekijk&id=2018
Het is een simpele Template parser maar werkt perfect.
Ik gebruik het zelf ook voor me mini framework ;)

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Megamind schreef op zaterdag 14 februari 2009 @ 15:08:
Hm ja, dat kan inderdaad, dat is wat ik nu ook doe, alleen dan niet in de template zelf.

Maar hoe parsed Smarty die included template dan weer, aangezien er geen PHP code in hoort te staan, wat als die nu dynamische content moet weergeven?
Zoeken naar met regexp/parser waarmee je de te includen file uitvogelt en die vervolgens in een variabele opslaan met file_get_contents/include/whatever om hem vervolgens in te voegen met een simpele replace? Gokje hoor. :P
Verwijderd schreef op zaterdag 14 februari 2009 @ 15:08:
Ik weet niet of ik je kan helpen maar dit is wel handig:
http://wmcity.nl/scripts.php?actie=bekijk&id=2018
Het is een simpele Template parser maar werkt perfect.
Ik gebruik het zelf ook voor me mini framework ;)
Als je die parser gebruikt kun je er net zo goed geen gebruiken. Dat ding doet amper wat en uiteindelijk gebruik je alsnog gewoon PHP in je templates. Wat overigens niet slecht is hoor, daar niet van.

[ Voor 31% gewijzigd door NMe op 14-02-2009 15:46 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
NMe schreef op zaterdag 14 februari 2009 @ 15:43:
[...]

Zoeken naar met regexp/parser waarmee je de te includen file uitvogelt en die vervolgens in een variabele opslaan met file_get_contents/include/whatever om hem vervolgens in te voegen met een simpele replace? Gokje hoor. :P
Dat zou ik wellicht kunnen doen.

Een folder maken die modules oid heet, waar dan de php code in komt per module, welke dan weer geinclude wordt door de template parser.

Acties:
  • 0 Henk 'm!

  • harrald
  • Registratie: September 2005
  • Laatst online: 16-09 08:44
maar waarom zo moeilijk doen als er al zoiets bestaat? begrijp me niet verkeerd ik probeer ook altijd zoveel mogelijk dingen zelf te maken maar smarty is een kant en klaar product wat zichzelf al bewezen heeft. bespaar jezelf een hoop werk en gebruik gewoon smarty, kan jij je tijd in andere zaken steken. :)

(edit: het is overigens kinderlijk eenvoudig zelf plugins te maken voor smarty als je functionaliteit mist.)

[ Voor 15% gewijzigd door harrald op 14-02-2009 18:50 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

harrald schreef op zaterdag 14 februari 2009 @ 18:49:
maar waarom zo moeilijk doen als er al zoiets bestaat? begrijp me niet verkeerd ik probeer ook altijd zoveel mogelijk dingen zelf te maken maar smarty is een kant en klaar product wat zichzelf al bewezen heeft. bespaar jezelf een hoop werk en gebruik gewoon smarty, kan jij je tijd in andere zaken steken. :)

(edit: het is overigens kinderlijk eenvoudig zelf plugins te maken voor smarty als je functionaliteit mist.)
Ik kan diezelfde vraag projecteren op het gebruik van Smarty zelf natuurlijk. ;) PHP heeft van zichzelf alles in zich om fijne en leesbare templates te maken, en toch zweren heel veel mensen bij Smarty. Soms zoek je gewoon nét iets anders. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Precies, en zelfs bij Smarty kwam ik op hetzelfde probleem.

Zoals Joomla die modules eigenlijk heeft, kan Smarty geen goede oplossing bedenken.

Smarty is leuk, maar niet voor een light frameworkje, teveel gedoe :P

Acties:
  • 0 Henk 'm!

Verwijderd

NMe schreef op zaterdag 14 februari 2009 @ 15:43:
[...]

Als je die parser gebruikt kun je er net zo goed geen gebruiken. Dat ding doet amper wat en uiteindelijk gebruik je alsnog gewoon PHP in je templates. Wat overigens niet slecht is hoor, daar niet van.
Daar ben ik het niet mee eens. Als je het goed gebruikt geeft het wel degelijk meer overzicht dan gewoon de HTML tussen PHP code echoen. ;)

Acties:
  • 0 Henk 'm!

  • TvdW
  • Registratie: Juli 2007
  • Laatst online: 30-08-2021
Verwijderd schreef op zaterdag 14 februari 2009 @ 22:18:
[...]

Daar ben ik het niet mee eens. Als je het goed gebruikt geeft het wel degelijk meer overzicht dan gewoon de HTML tussen PHP code echoen. ;)
ja, maar wat dacht je van
include 'template.php';

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
TvdW schreef op zondag 15 februari 2009 @ 00:13:
[...]

ja, maar wat dacht je van
include 'template.php';
En hoe zet jij daar dan dynamische content in ;)

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Verwijderd schreef op zaterdag 14 februari 2009 @ 22:18:
[...]

Daar ben ik het niet mee eens. Als je het goed gebruikt geeft het wel degelijk meer overzicht dan gewoon de HTML tussen PHP code echoen. ;)
Ehm...zoek de verschillen:
HTML:
1
2
3
4
5
6
7
8
9
<html>
  <head>
    <title>{$title}</title>
  </head>
  <body>
    <h1>{$header}</h1>
    {include file='content.tpl'}
  </body>
</html>

PHP:
1
2
3
4
5
6
7
8
9
<html>
  <head>
    <title><?=$title;?></title>
  </head>
  <body>
    <h1><?=$header;?></h1>
    <? include 'content.tpl'; ?>
  </body>
</html>

Verschil in overzicht is er bij de meeste standaardtemplates helemaal niet. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Kettrick
  • Registratie: Augustus 2000
  • Nu online

Kettrick

Rantmeister!

Smarty biedt wat voordelen met sections, formatters etc, dat maakt het soms iets leesbaarder. maar als je het zo eenvoudig gebruikt als hierboven voegt het weinig toe :)

[ Voor 2% gewijzigd door Kettrick op 15-02-2009 02:26 . Reden: bier-typo's weggeedit .. ]


Acties:
  • 0 Henk 'm!

Verwijderd

NMe schreef op zondag 15 februari 2009 @ 01:36:
[...]

Ehm...zoek de verschillen:
HTML:
1
2
3
4
5
6
7
8
9
<html>
  <head>
    <title>{$title}</title>
  </head>
  <body>
    <h1>{$header}</h1>
    {include file='content.tpl'}
  </body>
</html>

PHP:
1
2
3
4
5
6
7
8
9
<html>
  <head>
    <title><?=$title;?></title>
  </head>
  <body>
    <h1><?=$header;?></h1>
    <? include 'content.tpl'; ?>
  </body>
</html>

Verschil in overzicht is er bij de meeste standaardtemplates helemaal niet. ;)
Ik had hier een hele simpele "language function" voor gevonden... maar op een of andere manier ben ik hem kwijt/niet gebookmarked.

{header} zou namelijk erg makkelijk zijn als dit gewoon "anywhere" in the code kunt gebruiken als je de "translate" function gebruikt om de boel uit een array the peuteren.

/me gaat weer zoeken.

Acties:
  • 0 Henk 'm!

  • Erik Jan
  • Registratie: Juni 1999
  • Niet online

Erik Jan

Langzaam en zeker

PHP is zelf al een template engine, maar "enterprise" (of "zware") template engines hebben ook wel bestaansrecht:

• Programmeur en UI-designer zijn twee verschillende banen, en om effectief te kunnen samenwerken in een source-control moet de boel wel op bestandsniveau te scheiden zijn. => losse template bestanden

• UI-designers hebben beperkte programmeercapaciteiten en je moet dus een simpel presentatie-logica-taaltje hebben (een subsetje van de taal waarin je werkt). Met één handleiding/specificatie die je kan overhandigen aan de designers en zodat zij dat weer op hun CV kunnen zetten.

• De UI-logica moet in een sandbox blijven en bijvoorbeeld niet bij je database kunnen komen. => veiligheid, verdeling van verantwoordelijkheden, afdwingen modulair ontwerp.

Voor kleine projecten zou ik altijd voor de ingebouwde PHP functionaliteit zoals in NMe zijn post gaan, om te voorkomen dat je langzaam het wiel opnieuw aan het uitvinden bent met een eigen template-dialect.

Heb je ambities dan kan je maar gelijk het beste investeren en voor een op dat moment heersende industriestandaard kiezen.

This can no longer be ignored.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Verwijderd schreef op zondag 15 februari 2009 @ 02:34:
[...]

Ik had hier een hele simpele "language function" voor gevonden... maar op een of andere manier ben ik hem kwijt/niet gebookmarked.

{header} zou namelijk erg makkelijk zijn als dit gewoon "anywhere" in the code kunt gebruiken als je de "translate" function gebruikt om de boel uit een array the peuteren.

/me gaat weer zoeken.
De enige "translate"-functie die ik ken is gettext maar die lijkt me hier redelijk ontoepasbaar. :P
Erik Jan schreef op zondag 15 februari 2009 @ 02:39:
PHP is zelf al een template engine, maar "enterprise" (of "zware") template engines hebben ook wel bestaansrecht:
Ik betwist het bestaansrecht ervan niet, ik zeg alleen dat je ze om de goeie reden moet gebruiken. :)
[quote]• Programmeur en UI-designer zijn twee verschillende banen, en om effectief te kunnen samenwerken in een source-control moet de boel wel op bestandsniveau te scheiden zijn. => losse template bestanden
Dat kan (gelukkig) ook gewoon zonder aparte templating classes, zie mijn voorbeeld hierboven. :)
[quote]• UI-designers hebben beperkte programmeercapaciteiten en je moet dus een simpel presentatie-logica-taaltje hebben (een subsetje van de taal waarin je werkt). Met één handleiding/specificatie die je kan overhandigen aan de designers en zodat zij dat weer op hun CV kunnen zetten.
Als je een UI-designer zonder verdere programmeerervaring een van de beide methodes die ik hierboven post laat leren gaat hij de ene niet sneller onder de knie krijgen dan de ander hoor. :P
[quote]• De UI-logica moet in een sandbox blijven en bijvoorbeeld niet bij je database kunnen komen. => veiligheid, verdeling van verantwoordelijkheden, afdwingen modulair ontwerp.
Dát is het enige argument dat je aandraagt dat IMO standhoudt, al kun je je afvragen waarom je je druk maakt om de database als je weet wie de UI-ontwerper is en je gewoon bij zijn code kan. ;)


Hoe dan ook, terug ontopic: drm in "[PHP]Templates modulair opbouwen" had eigenlijk best wel een boeiende vraag. Wat wil je nou precies, Megamind? En waarom voldoet (bijvoorbeeld) Smarty dan niet? Want dat is me nog steeds niet duidelijk eigenlijk. :)

[ Voor 14% gewijzigd door NMe op 15-02-2009 05:16 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Het is lastig uitleggen :P Ik zal het proberen makkelijker te omschrijven, het is een beetje een praktisch probleem.

Mijn framework bestaat uit een aantal bestanden:
index.php (php code voor de index)
lib/template.php (template parser)
templates/index.tpl (layout voor index)
templates/header.tpl (de header layout)

index.php roept de template engine aan, welke de index.tpl parsed met dynamische content, of laat een cached pagina zien, wat Smarty dus ook doet ja.

Elke pagina moet dus ook een header hebben, waar dynamische informatie instaat.

Deze header kan ik niet zomaar includen aangezien er dynamische content instaat welke ergens vandaan moet komen. Maar deze content kan ik niet in index.php defineren, want dan zou ik dat op elke nieuwe pagina opnieuw moeten defineren.

Wat ik nu dus heb gemaakt (versimpeld):

lib/template.php
Dit is de template engine class, dit bestand mag je dus eigenlijk niet veranderen per website, aangezien deze makkelijk upgradebaar moet zijn.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class TemplateEngine {
    function Fetch($file) 
    {
        global $_LANG, $_USER;
        $FileName = ROOT . $this->Path . $file . $this->Extension;
        if (File_Exists($FileName))
        {
            include($FileName);
            return $Contents;
        }
    }

    function HeaderHTML()
    {
        $SiteTitle = IsSet($_LANG->SiteTitle) ? $_LANG->SiteTitle : $_CONFIG['SiteTitle'];
        return $this->Fetch('header_html');
    }
}


lib/dynamische_modules.php
Hier wordt dus dynamische informatie die in modules komen verwerkt.
PHP:
1
2
3
4
5
6
7
8
9
class Template extends TemplateEngine 
{
    function Header()
    {
        global $_USER, $_LANG;
        $this->Set('username', $_USER->Username);
        return $this->HeaderHTML().$this->Fetch('header');
    }
}


index.php
PHP:
1
2
3
4
5
6
7
require_once("lib/template.php");
$Template = new Template();
$Template->Title = 'Page title';
$Template->Set('Test', 'Test String');
echo $Template->Header();
echo $Template->Fetch('index');
echo $Template->Footer();


Nu wordt dus de header en footer in die dynamische_modules.php verwerkt, deze is nu nog klein, maar ik heb website waar wel 20 modules voor komen, om het overzichtelijk te houden.

Hier wil ik juist vanaf stappen, ik wil het makkelijker maken om dynamische modules te maken. Ik gewoon bv gewoon een folder hebben /modules waar ik php code inzet die gebruikt kan worden als dynamische module. Maar dat kan niet aangezien ik nu een extended class gemaakt heb van TemplateEngine.

Het is te vergelijken met Tweakers FP tracker. Deze tracker bestaat ook uit verschillende modules, welke op elke pagina zichtbaar zijn. Hoe wordt deze geinclude bv?

Ik hoop dat het zo iets duidelijker is :P

[ Voor 3% gewijzigd door Megamind op 15-02-2009 12:18 ]


Acties:
  • 0 Henk 'm!

  • TvdW
  • Registratie: Juli 2007
  • Laatst online: 30-08-2021
Megamind schreef op zondag 15 februari 2009 @ 00:40:
[...]

En hoe zet jij daar dan dynamische content in ;)
oh, ik gebruik normaal altijd smarty, maar ik reageerde even op die template parser @ wmcity,saven

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Ik heb het nu opgelost door van die template parser class een interface te maken.

Nu kan ik dus daar simpel modules aan toevoegen zonder door de code te hoeven spitten :)


Helaas, dat werkte toch niet helemaal goed :P

[ Voor 13% gewijzigd door Megamind op 15-02-2009 15:43 ]


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Volgens mij is je probleem dat je, doordat je feitelijk template logica in je class stopt, je class onderdeel wordt van het probleem.

Voorbeeld: je hebt in je TemplateEngine class hierboven een method HeaderHTML. Maar feitelijk is dat niets anders dan een shorthand voor een template-variabele setten en vervolgens een template (snippet) includen. Als je die stap in plaats van in je "template engine" gewoon in de template zelf doet, heb je dat probleem niet meer.

denk ik, wat ik begrijp het nog steeds niet helemaal.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
drm schreef op dinsdag 17 februari 2009 @ 21:57:
Volgens mij is je probleem dat je, doordat je feitelijk template logica in je class stopt, je class onderdeel wordt van het probleem.

Voorbeeld: je hebt in je TemplateEngine class hierboven een method HeaderHTML. Maar feitelijk is dat niets anders dan een shorthand voor een template-variabele setten en vervolgens een template (snippet) includen. Als je die stap in plaats van in je "template engine" gewoon in de template zelf doet, heb je dat probleem niet meer.

denk ik, wat ik begrijp het nog steeds niet helemaal.
Ik denk dat je het wel begrijpt ;)

Je hebt gelijk, die HeaderHTML heeft eigenlijk niets te maken met de template engine zelf. Dus waar anders zou jij al die variable setten? Zou je een aparte extended class maken waar deze functies in komen? Want je kan geen PHP code in de templates zetten.

Dit probleem had ik dus, dat er teveel template functies, die eigenlijk niets met de engine te maken hebben, in de class stonden.

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Megamind:
Ik denk dat je het wel begrijpt ;)

Je hebt gelijk, die HeaderHTML heeft eigenlijk niets te maken met de template engine zelf. Dus waar anders zou jij al die variable setten? Zou je een aparte extended class maken waar deze functies in komen? Want je kan geen PHP code in de templates zetten.
Wat bedoel je met variable setten? Ik neem even aan dat je daarmee bedoelt "bekendmaken aan de template". In dat geval: Het setten ervan doe je gewoon in de index.php, of in een class. In de "controller" in ieder geval, als het MVC pattern je iets zegt. Je laat het vervolgens aan de template over waar de variabele getoond wordt.

[ Voor 14% gewijzigd door drm op 17-02-2009 22:23 ]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
drm schreef op dinsdag 17 februari 2009 @ 22:22:
[...]
Wat bedoel je met variable setten? Ik neem even aan dat je daarmee bedoelt "bekendmaken aan de template". In dat geval: Het setten ervan doe je gewoon in de index.php, of in een class. In de "controller" in ieder geval, als het MVC pattern je iets zegt. Je laat het vervolgens aan de template over waar de variabele getoond wordt.
Dat bedoel ik, daarom vroeg ik advies hoe ik dit het makkelijkst structureel kan oplossen.

Ik wil dus niet met enormle classes werken als controller, als er iets veranderd moet worden dat het uitpuilt van code.

Als je begrijpt wat ik bedoel :P

[ Voor 42% gewijzigd door Megamind op 17-02-2009 22:25 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Megamind schreef op dinsdag 17 februari 2009 @ 22:23:
[...]

Ik wil dus niet met enormle classes werken als controller, als er iets veranderd moet worden dat het uitpuilt van code.
Dan begrijp ik niet zo waarom je bijvoorbeeld een Header() en Footer() method gemaakt hebt. ;) Gewoon netjes includen vanuit je template is duidelijker voor een eventuele templatebouwer en makkelijker te implementeren. Win-win. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
NMe schreef op dinsdag 17 februari 2009 @ 23:10:
[...]

Dan begrijp ik niet zo waarom je bijvoorbeeld een Header() en Footer() method gemaakt hebt. ;) Gewoon netjes includen vanuit je template is duidelijker voor een eventuele templatebouwer en makkelijker te implementeren. Win-win. :P
Omdat ik met meer modules werk dan alleen header en footer :P Dat is juist het punt.

Wat ik nu heb gedaan:
De template engine kan bestanden importeren door ze te inluden. Deze bestanden bevatten dan klasse zoals deze:
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
class HTML
{
    var $Parent;
    
    public function __construct(&$Parent)
    {
        $this->Parent = $Parent;
    }
    function FooterHTML()
    {
        Global $_CONFIG;
        
        /**
         * Do we want to show the debug
         */
        If($_CONFIG["DebugShow"])
        {
            return $this->Debug().$this->fetch('footer_html');
        }
        else
        {
            return $this->fetch('footer_html');
        }
    }
}


Deze kan ik dan weer aanroepen met de template engine.

Zo houd ik overzicht in mijn project, code en layout blijft gescheiden en modules worden apart opgeslagen.

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Het probleem bij dit soort topics is dat je vaak te moeilijk denkt en daarom hulp wil om om de door jouzelf gecreëerde gedachtenkronkels heen te komen, terwijl de eigenlijke oplossing veel dichterbij ligt.

Zoals NMe al zegt is de eenvoudigste oplossing includen vanuit je template.

Stel, je hebt de template "view_article" waarmee je een nieuwsbericht bekijkt. Deze "view_article" bevat de volgende code:
HTML:
1
2
3
4
{include=header.tpl}
<h1>{title}</h1>
<p>{articleBody}</p>
{include=footer.tpl}


Vervolgens heb je header:
HTML:
1
2
3
4
5
<html>
 <head>
  <title>{pageTitle}</title>
 </head>
 <body>


En je footer:
HTML:
1
2
 </body>
</html>


Met deze drie bestanden ben je zo dynamisch als je wil. In de header kan per pagina een andere titel komen te staan, terwijl de html hiervoor niet verandert en dus op één plek (in één bestand) kan staan. Per "pagina", dus per template, kan alle html vervolgens aangepast worden terwijl je header en footer hetzelfde blijven.

Als dat niet werkt klopt je templatelogica niet, en zou je beter eerst iets simpels als TemplatePower gebruiken om de basics van templates door te krijgen.

[ Voor 16% gewijzigd door CodeCaster op 17-02-2009 23:42 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Megamind schreef op dinsdag 17 februari 2009 @ 23:27:
[...]

Omdat ik met meer modules werk dan alleen header en footer :P Dat is juist het punt.
Mijn hele punt is dat je dat juist niet moet willen doen. ;) Het is hierboven al eens gezegd, maar je maakt je templateclass slimmer dan hij moet zijn. Wat boeit het voor je templatesysteem of hij websites aan het bouwen is of tekstdocumenten? Wat boeit het of je een header, footer, menu, wat dan ook hebt? De header is een aparte file die je wil includen, de footer ook. Het menu ook. Wat jij nu doet is zo'n beetje hetzelfde als voor elke aparte query in je databaseclass een aparte method aan te maken die je aanroept waar je die query nodig hebt, in plaats van één enkele query functie die je aan kan roepen met de query als parameter. ;)

Op TheDailyWTF.com stond toevallig vandaag een fijn artikel dat precies omschrijft wat jij hier probeert te doen, volgens mij. :)

[ Voor 11% gewijzigd door NMe op 17-02-2009 23:43 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • MrNGm
  • Registratie: Augustus 2004
  • Laatst online: 01-09 13:45
Hmmz en zelfs een van mijn eerste template "parser"s was nog simpeler en had nog nikseen beetje OOPigs. Je wil graag je eigen template engine maken, geen enkel probleem mee (alhoewel Smarty je een hoop werkt uit handen haalt. Dan kan je tenminste gaan proggen aan je modules ipv allerlei dingen inbouwen in je template engine. Bovendien kan je ook foreach loopjes gebruiken in Smarty, maar dat terzijde).

Wat moet een template parser nou doen. Hij vervangt {blaat} voor content. Dus eigenlijk heb je maar 2 functies nodig. SetVar en Parse. In de eerste zet je alle {var}'s in een array en met de tweede loop je die array af en str_replace je de {$var} in je .tpl. Dat zijn de basics voor een template engine (en zo zag mijn eerste er ook uit ^^).

Nu kan ik dus in m'n index.tpl het volgende zetten:
<body><div id="menu">{menu}</div></body>
In m'n php script include ik dan de template engine en doe ik $t->SetVar('menu', <contents van het menu>);

Het menu moet dynamisch? Ok, dan laat ik een _ander_ php scriptje de html code daarvoor genereren en die geeft het door aan index.php, die het weer doorgeeft aan de template engine. Of vanuit de menugenerator direct de template in.

Daarnaast, niet elk template bestaat uit een header, footer en menu, zoals reeds gezegd. KISS (Keep It Simple Stupid) is hier van belang. Je wil 30 modules hebben met elk hun eigen template? Dan wil je echt je code zo simpel en 'dom' mogelijk houden.

Heb je ook iets van een controller die bij een module automagisch een template toewijst? Iets in de trant van module $forum staat in /website/modules/forum, dus staan de $forum-specifieke templates in /website/modules/forum/tpl ?

En ook: wat wil je nu *precies*. Het is me nog een beetje vaag

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
CodeCaster schreef op dinsdag 17 februari 2009 @ 23:40:
HTML:
1
2
3
4
{include=header.tpl}
<h1>{title}</h1>
<p>{articleBody}</p>
{include=footer.tpl}


Vervolgens heb je header:
HTML:
1
2
3
4
5
<html>
 <head>
  <title>{pageTitle}</title>
 </head>
 <body>


En je footer:
HTML:
1
2
 </body>
</html>


Met deze drie bestanden ben je zo dynamisch als je wil. In de header kan per pagina een andere titel komen te staan, terwijl de html hiervoor niet verandert en dus op één plek (in één bestand) kan staan. Per "pagina", dus per template, kan alle html vervolgens aangepast worden terwijl je header en footer hetzelfde blijven.
Ik begrijp wat je bedoelt, en ik zie ook dat dit wellicht makkelijker is. Misschien denk ik inderdaad te moeilijk, maar ik ben het nu praktisch aan het uitdenken. In die header.tpl staat bv {pageTitle}, waar zou jij die laten parsen? In de template parser, maar als je bv meerdere dingen hebt:
PHP:
1
2
3
4
5
6
7
{include=header.tpl}
{include=usermenu.tpl}
{include=favorieten.tpl}
{include=navigatie1.tpl}
<h1>{title}</h1>
<p>{articleBody}</p>
{include=footer.tpl}

Waar en hoe zou je die logische code opslaan? Dat wil ik nu een beetje uitvinden en een makkelijke oplossing voor verzinnen.

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Megamind schreef op dinsdag 17 februari 2009 @ 23:56:
[...]

Ik begrijp wat je bedoelt, en ik zie ook dat dit wellicht makkelijker is. Misschien denk ik inderdaad te moeilijk, maar ik ben het nu praktisch aan het uitdenken. In die header.tpl staat bv {pageTitle}, waar zou jij die laten parsen? In de template parser, maar als je bv meerdere dingen hebt:
PHP:
1
2
3
4
5
6
7
{include=header.tpl}
{include=usermenu.tpl}
{include=favorieten.tpl}
{include=navigatie1.tpl}
<h1>{title}</h1>
<p>{articleBody}</p>
{include=footer.tpl}

Waar en hoe zou je die logische code opslaan? Dat wil ik nu een beetje uitvinden en een makkelijke oplossing voor verzinnen.
Als je usermenu, favorieten en navigatie op iedere pagina voorkomen zou ik ze lekker in de header erbij zetten.

In ieder geval zou ik recursief alle includes aflopen vóórdat ik begin met parsen. Ik zou dus de te parsen template in een variabele zetten, waarbij ik iedere keer dat een {include=} gevonden wordt éérst de inhoud van het include-bestand toegevoegd wordt aan de variabele, en wanneer de hele include is gelezen gaat de parser pas verder met het lezen van de volgende regel in het oorspronkelijke bestand.

Wanneer uiteindelijk het oorspronkelijke bestand én alle includes zijn gelezen heb je één grote string, die begint met "<html>\n <head>\n <title>{pageTitle}</title>\n </head>\n <body>\n <h1>{articleTitle}"... dan zorg je in het bestand dat je template parser aanroept dat al die templatevariabelen (pageTitle en articleTitle in dat geval) vervangen worden door de door jou bepaalde inhoud ($tpl->assign('pageTitle', 'Mijn testpagina');).

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Ja ok dat begrijp ik, en dat heb ik nu ook.

Het gaat mij meer om de code achter die templates.

usermenu.tpl is zou er zo uit kunnen zien:
PHP:
1
2
3
Name: {username}
Picture: {picture}
enz enz


Deze {username} moet ergens vandaan komen, ok misschien is dit simpel voorbeeld maar je kan ook meer complexe modules krijgen. Deze variable moet ergens vandaan komen, je kan niet elke pagina van je script weer
$Template->Set('Username', $User->Username)
gaan doen, want dat is niet handig.

Acties:
  • 0 Henk 'm!

  • MrNGm
  • Registratie: Augustus 2004
  • Laatst online: 01-09 13:45
Megamind schreef op woensdag 18 februari 2009 @ 00:23:
maar je kan ook meer complexe modules krijgen
Waar doel je dan op? Dat je een array met gegevens uit een DB hebt die je in een tabel wil zetten zonder al te veel moeite?

Zolang je een goede structuur hebt van includen (zowel in PHP als in je template engine) hoef je ook maar op 1 plek $t->set('blaat', $this->blaat) te doen. In mijn framework is het nu zo dat ik alleen maar de variabelen in de template die bij 1 specifieke module horen ook alleen in die ene specifieke module laat declareren.

Kan je anders wat meer code posten van je framework? Hoe worden de modules e.d. geladen, waar doel je precies op met de complexe modules. Bedoel je met modules, stukjes in de HTML pagina, zoals een menu of zoekbalk, of bedoel je modules als in PHP scripts die voor de login, user management e.d. zorgen?

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Ik zal wat code posten want het is nog niet duidelijk zo te zien :P

/index.php
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Require_Once(ROOT . 'lib/main.php');

Function ShowIndex()
{
    global $_DB, $_USER, $_LANG, $_CONFIG;

    $TestArray = Array(1 => 'Test',
                       2 => 'Blaat',
                       3 => 'Gek!');

    $Template = new Template();
    $Template->Import('fp_basic', 'FrontpageBasic');
    $Template->PageTitle = 'Index';
    $Template->Set('Test', 'This is a test string');
    $Template->Set('TestArray', $TestArray);
    Echo $Template->Module('Header');
    Echo $Template->Fetch('Index');
    Echo $Template->Module('Footer');
}


lib/template.php
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
Class Template
{

    Public Function Import($Filename, $ClassName)
    {
        $Filename = ROOT . 'modules/' . $Filename . '.php';

        If (File_Exists($Filename))
        {
            Require_Once($Filename);

            If (Class_Exists($ClassName))
            {
                $TmpObject = new $ClassName($this);

                $ImportFunctions = Get_Class_Methods($TmpObject);

                $ImportName = Get_Class($TmpObject);

                $this->Imported[$ImportName] = $TmpObject;

                ForEach($ImportFunctions As $Key => $FunctionName)
                {
                    $this->ImportedFunctions[$FunctionName] = $ImportName;
                }
            }
            Else
            {
                Trigger_Error('Module <strong>"' . $ModulePath . '"</strong> has no class <strong>"' . $ClassName . '"</strong>', E_USER_ERROR);
            }
        }
        Else
        {
            Trigger_Error('Module <strong>"' . $ModulePath . '"</strong> could not be imported', E_USER_ERROR);
        }
    }

    Public Function Module($Name)
    {
        If (Array_Key_Exists($Name, $this->ImportedFunctions))
        {
            Return Call_User_Func_Array( Array($this->Imported[$this->ImportedFunctions[$Name]], $Name), null);
        }
        Else
        {
            Trigger_Error('Module <strong>"' . $Name . '"</strong> was not found', E_USER_ERROR);
        }
    }

    Public Function Set($Key, $Value)
    {
        $this->Vars[$Key] = $Value;
    }

    Public Function Fetch($File)
    {
        Global $_LANG, $_USER;

        $Filename = $this->Path . StrToLower($File) . $this->Extension;

        If (File_Exists($Filename))
        {
            Ob_Start();

            Require($Filename);

            $Contents = Ob_Get_Contents();

            Ob_End_Clean();

            $Contents = Preg_Replace('/\r/', '', $Contents);

            $MatchArray = Array();
            $ReplaceArray = Array();

            $Contents = $this->ParseVars($Contents);
            $Contents = $this->ParseForEach($Contents);

            $Contents = preg_replace_callback($Match, 'ReplaceLanguageTags', $Contents);

            Return $Contents;
        }
        Else
        {
            Trigger_Error('Template <strong>"' . $Filename . '"</strong> could not be found', E_USER_ERROR);
            Return False;
        }
    }

    Protected Function ParseVars($Contents)
    {
        $MatchArray = Array();
        $ReplaceArray = Array();

        $Match = '/({VAR:(.*?)})/i';
        Preg_Match_All($Match, $Contents, $Matches);

        For($I = 0; $I < Count($Matches[0]); $I++)
        {
            If (IsSet($this->Vars[$Matches[2][$I]]))
            {
                $MatchArray[] = '/' . $Matches[1][$I] . '/';
                $ReplaceArray[] = $this->Vars[$Matches[2][$I]];
            }
            Else
            {
                $MatchArray[] = '/' . $Matches[1][$I] . '/';
                $ReplaceArray[] = '<strong>Undefined variable</strong>';
                Trigger_Error('Variable <strong>"' . $Matches[2][$I] . '"</strong> could not be found', E_USER_NOTICE);
            }
        }

        $Contents = Preg_Replace($MatchArray, $ReplaceArray, $Contents);

        Return $Contents;
    }

    Protected Function ParseForEach($Contents)
    {
        Global $_LANG;

        $MatchArray = Array();
        $ReplaceArray = Array();

        $Match = "/{foreach\b" .                            // Foreach begin
                 "(?>\s+(?:" .
                 "from=([^\s|^}]*)|" .                      // match from= attribute
                 "key=([^\s|^}]*)|" .                       // match key= attribute
                 "value=([^\s|^}]*)|" .                     // match value= attribute
                 "index=([0-9]*)|" .                        // match index= attribute (numeric only)
                 "indexname='([^']*)'" .                    // match indexname= attribute (between '')
                 ")|[^\s>]+|\s+)*" .                        // match rest of contents until {foreachelse} or {/foreach}
                 "}\n" .                                    // match {foreachelse} or {/foreach} (unused)
                 "((?:(?!{(?:foreachelse|\/foreach)}).)*)" .
                 "(?:{foreachelse}((?:(?!{\/foreach}).)*))?".
                 "{\/foreach}".                             // match {foreachelse} block IF exists
                 "/is";                                     // treat as single line, case independant

        Preg_Match_All($Match, $Contents, $Matches);

        For($I = 0; $I < Count($Matches[0]); $I++)
        {
            $Match = Str_Replace('/', '\/', $Matches[0][$I]);
            $From = Trim($Matches[1][$I]);
            $KeyID = Trim($Matches[2][$I]);
            $ValueID = Trim($Matches[3][$I]);
            $IndexID = Trim($Matches[4][$I]);
            $IndexNameID = $Matches[5][$I];
            $Line = $Matches[6][$I];
            $Else = Trim($Matches[7][$I]);

            If (IsSet($this->Vars[$From]) && Is_Array($this->Vars[$From]) && Count($this->Vars[$From]) > 0)
            {
                $NewBlock = '';

                ForEach($this->Vars[$From] As $Key => $Value)
                {
                    $TmpMatch = Array();
                    $TmpReplace = Array();
                    If ($IndexID <> '' && $IndexID == $Key)
                    {
                        $TmpMatch[] = '/{index}/i';
                        $TmpReplace[] = $IndexNameID;
                    }
                    Else
                    {
                        $TmpMatch[] = '/{index}/i';
                        $TmpReplace[] = '';
                    }
                    $TmpMatch[] = '/{' . $KeyID . '}/';
                    $TmpReplace[] = $Key;
                    $TmpMatch[] = '/{' . $ValueID . '}/';
                    $TmpReplace[] = $Value;

                    $NewBlock.= Preg_Replace($TmpMatch, $TmpReplace, $Line);
                }
                $MatchArray[] = '/' . $Match . '/';
                $ReplaceArray[] = $NewBlock;
            }
            Else
            {
                $MatchArray[] = '/' . $Match . '/';
                $ReplaceArray[] = $Else;
            }
        }
        $Contents = Preg_Replace($MatchArray, $ReplaceArray, $Contents);

        Return $Contents;
    }

    Public Function HeaderHTML()
    {
        Global $_USER, $_CONFIG, $_LANG, $_XAJAX;

        /**
         * Make the site title with the given title
         */
        $SiteTitle = IsSet($_LANG->SiteTitle) ? $_LANG->SiteTitle : $_CONFIG['SiteTitle'];

        If ($this->PageTitle <> '')
            $this->Set('PageTitle', $SiteTitle . ' - ' . $this->PageTitle);
        Else
            $this->Set('PageTitle', $SiteTitle);

        If (File_Exists(ROOT . 'js/' . ThisFile . '.js'))
            $this->Javascript[] = ThisFile . '.js';

        $this->Javascript[] = RELATIVE . 'js/common.js';
        $this->Javascript[] = RELATIVE . 'js/dialog.js';
        $this->Javascript[] = RELATIVE . 'js/md5.js';
        $this->Javascript[] = RELATIVE . 'js/jquery-1.3.1.min.js';

        $this->Set('Javascript', $this->Javascript);

        If (File_Exists(ROOT . 'css/' . ThisFile . '.css'))
            $this->CSS[] = RELATIVE . 'js/' . ThisFile . '.css';

        $this->CSS[] = RELATIVE . 'css/global.css';

        $this->Set('CSS', $this->CSS);

        $this->Set('Charset', $_LANG->Charset);
        $this->Set('LanguageShort', $_LANG->LanguageShort);
        $this->Set('RelativePath', RELATIVE);

        Return $this->Fetch('header_html') . $this->Fetch('Dialog');
    }
    
    Public Function FooterHTML()
    {
        Global $_CONFIG;

        If ($_CONFIG['DebugShow'])
        {
            Return $this->Debug() . $this->Fetch('Footer_HTML');
        }
        Else
        {
            Return $this->Fetch('Footer_HTML');
        }
    }
}


modules/fp_basic.php
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class FrontpageBasic
{
    var $Parent;
    
    public function __construct(&$Parent)
    {
        $this->Parent = $Parent;
    }

    Public Function Header()
    {
        Return $this->Parent->HeaderHTML() . $this->Parent->Fetch('Header');
    }

    Public Function Footer()
    {
        Return $this->Parent->Fetch('Footer') . $this->Parent->FooterHTML();
    }
}


templates/index.tpl
PHP:
1
2
3
4
5
6
7
8
9
{VAR:Test}
<br />
<ul>
{foreach from=TestArray key=tmpk value=tmpv index=2 indexname=' ik ben index!'}
<li>{tmpk}: {tmpv}{index}</li><br />
{foreachelse}
No results
{/foreach}
</ul>


templates/header_html.tpl
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{LANG:LanguageShort}" lang="{LANG:LanguageShort}">
<head>
    <title>{VAR:PageTitle}</title>
    {VAR:xAjaxJavascript}
    <link rel="shortcut icon" href="{VAR:RelativePath}images/favicon.ico" type="image/x-icon" />
    {foreach from=CSS value=css}
    <link rel="stylesheet" type="text/css" href="{css}" />
    {/foreach}
    <meta http-equiv="Content-Type" content="text/html; charset={LANG:Charset}" />
    {foreach from=Javascript value=js}
    <script type="text/javascript" src="{js}"></script>
    {/foreach}
</head>
<body>


Ze zijn een beetje gestript, en natuurlijk mist er nog 90% van het framework, maar dit is waar het om gaat.

Die modules/fp_basic.php bevat een class met basis functies voor HTML codes, niets speciaals, ik heb de echte HTML parsing in de template engine gehouden omdat deze voor alle pagina's gebruikt wordt.

Ik kan ook een bestand modules/widgets.php hebben, deze bevat alle code om widgets op de frontpage te maken, welke onderdeel zijn van de vaste structuur.

Als ik er zo naar kijk vind ik hoe de modules in de template engine worden gestopt, vies. Daarom mijn vraag, hoe kan dit beter.

[ Voor 6% gewijzigd door Megamind op 18-02-2009 01:03 ]


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44

MBV

Wat ik in een vorig project tegenkwam qua template parsen, was heel complex opgezet (templates in database opslaan enzo), maar jouw probleem was prima opgelost:
- include op elke pagina header.php. Daarin wordt een template-object wordt aangemaakt, en 'globale variabelen' die in elke template vervangen moeten kunnen worden (pak-em-beet de datum van vandaag, of de persoon die ingelogd is) worden aan die klasse meegegeven (SetVar('username', $_SESSION['user']->name);)
- template parser werkt recursief: zodra hij het 'magic word' voor een include tegenkomt, start hij voor dat template de template parser opnieuw (met dezelfde set gegevens)
- voor de website er was een 'default template', waarin de opgevraagde pagina werd ge-include. Dat werd doodleuk in een string-bewerking aangepast, en als een willekeurige gewone include behandeld.

Dat laatste is niet altijd handig (kan onnodig complex zijn), maar o.a. Joomla doet het op dezelfde manier.

Acties:
  • 0 Henk 'm!

  • --MeAngry--
  • Registratie: September 2002
  • Laatst online: 19-09 16:35

--MeAngry--

aka Qonstrukt

Ik snap eerlijk gezegd niet zo goed waarom iedereen hier bij Smarty blijft zweren. Als er namelijk wel 1 crappy stuk script is...

Het werkt op zich wel, maar het is destijds geschreven voor PHP 4, niet voor 5, en dat merk je al als je een beetje OOP begint te gebruiken. Ik onderhoud zelf een CMS dat met modules werkt, maar als ik zo'n module-instantie aan Smarty doorgeef, kan ik dit niet eens doen:

PHP:
1
{assign var="blaat" value=$module_naam->getZooi()->doeDit()}


Want Smarty gaat gewoon over de zeik van die tweede pijl. 8)7

Laat iemand die hier net mee gaat werken alsjeblieft geen Smarty gebruiken, maar 1 van de andere goede template-engines die al bestaan en wel weten dat er een versie 5 is van PHP.
Als versie 3 van Smarty (ooit) uit komt, dan praten we wel weer verder. :P

Tesla Model Y RWD (2024)


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Waarom zit je ook functies aan te roepen binnen je template? Je gebruikt een templating systeem en gaat daar vervolgens programmalogica inbouwen aanroepen, niet logisch IMO. Daarnaast gaat het volgens mij niet om die tweede pijl maar om die tweede pijl voorafgegaan door functiehaken. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • disjfa
  • Registratie: April 2001
  • Laatst online: 03-07 14:47

disjfa

be

Megamind schreef op zondag 15 februari 2009 @ 10:43:
Het is lastig uitleggen :P Ik zal het proberen makkelijker te omschrijven, het is een beetje een praktisch probleem.
Dus een lastig probleem moeilijker maken :P

Je probeert een head en title tag te modden in een zelf gemaakte template classe. Waarom is de groote vraag en waarom dit lastig is begrijp ik copleet niet aan de hand van je verhaal. Stop het er gewoon in of gebruik een template parser zoals eerser al gezegd zoals smarty.

Wat probeer je nu?

disjfa - disj·fa (meneer)
disjfa.nl


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

disjfa schreef op woensdag 18 februari 2009 @ 01:44:
[...]

Stop het er gewoon in of gebruik een template parser zoals eerser al gezegd zoals smarty.
Er is ook "gewoon" een middenweg hoor: zelf ontwikkelen naar je eigen wensen, maar zonder die rare functies die het zaakje minder breed inzetbaar maken. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
disjfa schreef op woensdag 18 februari 2009 @ 01:44:
[...]

Dus een lastig probleem moeilijker maken :P

Je probeert een head en title tag te modden in een zelf gemaakte template classe. Waarom is de groote vraag en waarom dit lastig is begrijp ik copleet niet aan de hand van je verhaal. Stop het er gewoon in of gebruik een template parser zoals eerser al gezegd zoals smarty.

Wat probeer je nu?
Wat nou als je dit doet, voorbeeldje tweakers:
code:
1
2
3
4
5
6
{include header.tpl}
{include tracer.tpl}
Hier het nieuws van vandaag
<?php echo date('d-m-Y'); // Dit wil ik dus zo min mogelijk hebben! ?>
{include poll.tpl}
{include footer.tpl}


Je template parser gaat door de code, komt een include tag tegen en dan? Moet hij hem maar gewoon doodleuk includen?

De tracker moet natuurlijk ingedeeld worden naar users wens, en de poll moet uit de db gehaald worden enz. Waar zouden jullie deze code neer zetten dan?

Zoiets als dit:
PHP:
1
2
If ($Include == 'poll')
  maak_poll();

Dat lijkt mij een van de vieste oplossingen, en minst schaalbaar.

Ik heb naar Joomla, Smarty en andere frameworks gekeken, maar ik kan geen goede oplossing vinden.

Joomla doet het met componenten, die geeval'd worden, Smarty hoor ik geen goede verhalen over, heb er ook geen goede ervaring mee (www.nosmarty.net).

[ Voor 13% gewijzigd door Megamind op 18-02-2009 11:42 ]


Acties:
  • 0 Henk 'm!

  • harrald
  • Registratie: September 2005
  • Laatst online: 16-09 08:44
NMe schreef op woensdag 18 februari 2009 @ 01:46:
[...]

Er is ook "gewoon" een middenweg hoor: zelf ontwikkelen naar je eigen wensen, maar zonder die rare functies die het zaakje minder breed inzetbaar maken. ;)
Wat maakt smarty niet breed inzetbaar?
Ik ben echt heel benieuwd :)

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Megamind schreef op woensdag 18 februari 2009 @ 10:58:
[...]

Je template parser gaat door de code, komt een include tag tegen en dan? Moet hij hem maar gewoon doodleuk includen?
Je kan toch gewoon een parser maken die "{include poll.tpl}" kan lezen, interpreteren en de juiste file opent, in een variabele zet en afdrukt? Ik begin een beetje het idee te krijgen dat we langs elkaar heen aan het praten zijn hier. :)
harrald schreef op woensdag 18 februari 2009 @ 11:39:
[...]

Wat maakt smarty niet breed inzetbaar?
Ik ben echt heel benieuwd :)
Ik doelde daarmee op de rare functies die Megamind schrijft, niet op Smarty. ;)

[ Voor 52% gewijzigd door NMe op 18-02-2009 11:42 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
NMe schreef op woensdag 18 februari 2009 @ 11:41:
[...]

Je kan toch gewoon een parser maken die "{include poll.tpl}" kan lezen, interpreteren en de juiste file opent, in een variabele zet en afdrukt? Ik begin een beetje het idee te krijgen dat we langs elkaar heen aan het praten zijn hier. :)
Dat is precies wat ik bedoel.

Ik heb een parser die poll.tpl leest.

Nu is juist de vraag, waar zal ik die file intepreteren? Gewoon alle code in poll.tpl zetten? En dan nog een apart poll_template.tpl template bestand ernaast?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Megamind schreef op woensdag 18 februari 2009 @ 11:43:
[...]

Dat is precies wat ik bedoel.

Ik heb een parser die poll.tpl leest.

Nu is juist de vraag, waar zal ik die file intepreteren? Gewoon alle code in poll.tpl zetten? En dan nog een apart poll_template.tpl template bestand ernaast?
Ik vind de manier waarop Smarty dat aanpakt redelijk elegant.
code:
1
{include file='links.tpl' title='Newest links' links=$link_array}

Je hebt de code dan gewoon in je algemene PHP-file, en de templates doen niets meer dan zooi afdrukken en elkaar includen met wat parameters. De variabelen die je in je poll.tpl wil weergeven geef je dus mee aan je allesomvattende templatefile, die ze weer doorgeeft aan de polltemplate.

[ Voor 10% gewijzigd door NMe op 18-02-2009 11:48 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
NMe schreef op woensdag 18 februari 2009 @ 11:47:
[...]

Ik vind de manier waarop Smarty dat aanpakt redelijk elegant.
code:
1
{include file='links.tpl' title='Newest links' links=$link_array}

Je hebt de code dan gewoon in je algemene PHP-file, en de templates doen niets meer dan zooi afdrukken en elkaar includen met wat parameters. De variabelen die je in je poll.tpl wil weergeven geef je dus mee aan je allesomvattende templatefile, die ze weer doorgeeft aan de polltemplate.
Ja dat is wel handig, maar stel ik heb een website met 100 pagina's.

Op elke pagina zitten bv 20 kleine modules, poll, forum tracker, news tracker, ingelogde gebruiker, persoonlijke kalender etc etc.

Dan zou ik dus op elke van die 100 pagina's de variable van die modules meegeven aan Smarty! Als er dan 1 dingetje anders zou moeten later, kan je al die pagina's langs :?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Megamind schreef op woensdag 18 februari 2009 @ 12:00:
[...]

Ja dat is wel handig, maar stel ik heb een website met 100 pagina's.

Op elke pagina zitten bv 20 kleine modules, poll, forum tracker, news tracker, ingelogde gebruiker, persoonlijke kalender etc etc.

Dan zou ik dus op elke van die 100 pagina's de variable van die modules meegeven aan Smarty! Als er dan 1 dingetje anders zou moeten later, kan je al die pagina's langs :?
PHP-files kunnen ook gewoon elkaar includen hoor. ;) Het opbouwen van die losse modules kun je prima uitsplitsen naar andere PHP-files.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
NMe schreef op woensdag 18 februari 2009 @ 12:20:
[...]

PHP-files kunnen ook gewoon elkaar includen hoor. ;) Het opbouwen van die losse modules kun je prima uitsplitsen naar andere PHP-files.
En dan komen we bij mijn originele vraag :P Ik wil dus graag weten wat een nette oplossing hiervoor is, praktisch gezien.

Zou je 1 php bestand per module maken? En deze dan includen, waarna deze bestanden hun output echo'en?

Acties:
  • 0 Henk 'm!

  • MrNGm
  • Registratie: Augustus 2004
  • Laatst online: 01-09 13:45
In mijn framework doe ik het als volgt:
code:
1
2
3
4
5
6
7
8
9
10
- FW_Object
  |- FW_Object_DB (database connectie, aanroepbaar via $this->db)
    |- FW_Object_Web (authenticatie, moet nog afgemaakt worden)
      |- FW_Module (basis voor de modules)
        |- FW_Common (functies die elke module kan gebruiken)
          |- Module_X
          |- Module_Y
    |- FW_Presenter_common
      |- FW_Presenter_smarty (include Smarty.class.php uit een andere dir)
- FW_Presenter (factory functie om de gewenste presenter te laden (Smarty, print/pdf etc. etc.)


Zoals je ziet kan zowel Module_X als Module_Y gebruik maken van de DB en van de Common functies. In elk bestand staat
PHP:
1
2
3
  public function __construct() {
    parent::__construct();
  }

dus wordt in index.php modules/admin/admin.php geladen, dan wordt automagisch elk bovenstaande klasse geladen (admin.php: class admin extends FW_Common)

Door het autoload principde toe te passen kan je makkelijk een nieuwe module 'laden' in bijv. Module_Y.

Dan zeg je iets als $poll = new FW_Module_Poll; en dan zoekt PHP naar een bestand Poll.php in includes/Module/ en include 'm. Dan wordt die poll module wel integraal onderdeel van je framework, maar je kan 'm overal aanroepen.
Je zou zelfs in je config een aantal modules kunnen opgeven die automatisch worden geladen en bereikbaar zijn via $this->$modulename->$functie...

Misschien niet de elegantste oplossing, maar voor mij werkt het 8)

[ Voor 18% gewijzigd door MrNGm op 18-02-2009 13:41 . Reden: presentatielaag opgenomen & __construct functie uitleg ]

Pagina: 1