Ik ben al een langere tijd bezig met mijn eigen templateparser. Dit was niet mijn eerste keuze maar het aanbod is vaak: te complex, traag, groot en bevat veel functionaliteiten die ik niet gebruik. Nu heb ik precies wat ik nodig heb met mijn eigen syntax, werkwijze en de HTML en PHP blijft gescheiden. De structuur met framework, code, templates en assets is nu ook geheel naar mijn wens.

Het idee was in eerste instantie dan ook om alleen variabelen in een .phtml bestand af te kunnen drukken, dit is inmiddels uitgebreid met een aantal functies.

Ik kom nu op een lastig punt waar ik al lang mee bezig ben en eigenlijk niet uit kom. Mijn wens is om een set resultaten af te kunnen drukken.


	
	public function setLoop ($sKey, $aValues)
	{
		if (is_string($sKey) && is_array($aValues))
		{
			$this->aLoop[] = $sKey;
			$this->aLoopVar[$sKey] = $aValues;
		}
		else
		{
			errors::setError('De eigenschappen voor de functie setLoop zijn niet correct.');
		}
	}

	public function regexLoop ()
	{
		preg_replace_callback ('/(\[loop:(\w+)\])(.*?)(\[\/loop:(\w+)\])/i', array($this, 'replaceLoop'), $this->sContent);
	}
	
	public function replaceLoop ($matches)
	{
		if (in_array($matches[2], $this->aLoop))
		{
			$this->aLoopSubstr[$matches[2]] = $matches[3];		
			$this->sContent = str_replace ($matches[0], '<?php for ($i = 0; $i < count($this->aLoopVar[\'test\'][\'id\']); $i++) 
															   {
																	print(preg_replace("/(\[loopvar:(.*?)\])/", $this->aLoopVar[\'test\'][\'id\'][$i], $this->aLoopSubstr[\'test\']));
															   } 
														 ?>', $this->sContent); 
		}
		else
		{
			errors::setError('De loop: ' . $matches[2] . ' is niet bekend.');
		}
}


test.php

<?php
error_reporting(E_ALL);
include ('../config.php');
include (FRAMEWORK . 'autoload.php');

// Verbinding maken
$sql = new MySQL('SQL.ini');

// Bestand inladen
$tpl = new parser(HTML . 'test.html');


// Vars, blocks, loops
$tpl->setVar('pagina_titel', 'Kluswerk.NL');
$tpl->setVar('url', ROOT);

$tpl->setBlock('menu');
$tpl->setVar('gebruiker', 'Bas');
$tpl->setVar('is_admin', true);
$aEen = array(1, 2, 3, 4 ,5, 6);
$aTwee = array('eerste titel', 'tweede titel', 'derde titel', 'vierde titel', 'vijfde titel', 'vierde titel', 'vijfde titel');
$tpl->setLoop('test', array('id' => $aEen, 'titel' => $aTwee));

$tpl->parse();
?>


test.html


<html>

<head>
<title>{{pagina_titel}}</title>
</head>

Welkom {{gebruiker}}, <br /><br />

[block:menu]Beginpagina | Over mij | Contact<br /><br />[/block:menu]

[if:istrue:is_admin]Bas je bent een admin!<br /><br />[/endif:istrue:is_admin]

[loop:test]De id: [loopvar:id] met de titel [loopvar:titel]!<br /><hr>[/loop:test]<br /><br />


[if:isset:foutieve_prijs]{{foutieve_prijs}}[/endif:isset:foutieve_prijs]

[block:footer]Copyright 2017.[/block:footer]
</html>


en het resultaat.


Welkom Bas, 

Beginpagina | Over mij | Contact

Bas je bent een admin!

De id: 1 met de titel 1!
De id: 2 met de titel 2!
De id: 3 met de titel 3!
De id: 4 met de titel 4!
De id: 5 met de titel 5!
De id: 6 met de titel 6!


Ik heb al ontzettend veel manieren geprobeerd om de variabelen in de loop op te slaan etc. dat deze niet wordt overschreven, maar het is mij nog niet gelukt.

ik gebruik nu: $this->aLoopVar[\'test\'][\'id\'][$i] omdat er anders helemaal geen resultaat is.
Thomas van den Heuvel op 04/02/2018 01:57:13

... maar je zult dan toch een beetje moeten schipperen want de logica ("PHP") en presentatie ("HTML") zijn onlosmakelijk met elkaar verbonden in dynamische websites ...

En toch wil je het af en toe 100% los trekken. Ik heb een website die we als een soort white label aanbieden, waarbij de klant zelf de volledige opmaak mag doen, en die wil ik dus echt geen PHP in handen geven.

Rob Doemaarwat op 04/02/2018 11:18:56
En toch wil je het af en toe 100% los trekken. Ik heb een website die we als een soort white label aanbieden, waarbij de klant zelf de volledige opmaak mag doen, en die wil ik dus echt geen PHP in handen geven.

En daarvoor betaal je een prijs. Het hangt er natuurlijk ook vanaf wat je wilt doen moet je applicatie.

Ben ik toch benieuwd in hoeverre de klant de opmaak dan zelf kan verzorgen. Biedt je sjablonen aan? En een WYSIWYG-editor en dat soort zaken? Op een of andere manier moet nog steeds vastliggen hoe (en welke) data aan templates gekoppeld is. Daar kom je simpelweg niet omheen.
Je kan prima een debugmodus maken die aangeeft wat er in je script ge-assigned is. Eventueel kan je het zelfs documenteren, maar doe dat niet te laat. In Smarty is hier zelfs in voorzien. (Zorg wel zelf voor een switch).

Ik zelf gebruik ook templates (via Smarty) en ik vind het als enkel developer ideaal als je aan een update werkt met een verbeterde gebruiksinterface in de website.
Maar als je een groot project hebt kan je op een gegeven moment niet meer zonder gescheiden lagen. Uiteindelijk is het MVC-pattern de beste opzet voor een applicatie.
- Ariën - op 04/02/2018 17:03:18
Uiteindelijk is het MVC-pattern de beste opzet voor een applicatie.

Dit is zoiets als zeggen dat een hamer altijd het beste gereedschap is, ongeacht de klus. Sorry, maar dat is simpelweg niet het geval. Als dat zo zou zijn, waarom is dan niet alles al MVC?

Het maakt tot op zekere hoogte niet uit hoe je code er uitziet om iets voor elkaar te krijgen. Wat er -wat mij betreft- wel toe doet is hoe je met een bepaalde aanpak tot een bepaald resultaat komt, en ook vooral waarom juist die aanpak geoorloofd zou zijn. En met hoeveel gemak je dingen kunt maken en aanpassen, want het praktische aspect uit het oog verliezen om maar van methode X gebruik te kunnen maken... dan sla je de plank ook mis, dan doe je iets om de vorm, en niet om een specifieke reden. Iets met deegrollers en poepgaten.

Maar op voorhand zeggen dat één aanpak altijd volstaat is onzin.
Thomas van den Heuvel op 04/02/2018 16:46:57

Ben ik toch benieuwd in hoeverre de klant de opmaak dan zelf kan verzorgen.

"De klant" is meestal "de webdesigner van de klant" die voldoende verstand van zaken heeft om een layout in HTML op te bouwen (en evt. lacunes met javascript en een paar asynchrone calls op te vullen). Wij vertellen 'm uiteraard welke waarden er beschikbaar zijn, en hoe ie die in het template kan krijgen.

Thomas van den Heuvel op 04/02/2018 16:46:57

En daarvoor betaal je een prijs.

Ik maak meestal websites die heel erg op "data" leunen. In mijn ervaring gaat een groot deel van de render tijd van een pagina vooral in het ophalen van data zitten. Dat de template parser dan een paar ms meer nodig heeft boeit me niet zo.
Ik doelde meer op abstractie + overhead in ontwikkeling daardoor en niet zozeer op snelheid.
Bas,

reinventing the wheel?

Zonde van je tijd man :=/ In minder tijd kun jij de basics van OOP leren én één van de populaire PHP frameworks voldoende onder de knie krijgen zodat je daarna op een juiste wijze van start kunt met hetgeen dat je uiteindelijk wilt bereiken. Vergelijk dat programmeren met het bouwen van een (groot) gebouw. Ga je een gebouw bouwen in je eentje en wil je alles zelf maken en niets kant en klaars kopen en gebruiken dan komt dat gebouw er in geen 80 jaar en is jouw leven voorbij. Je moet ook wel meters willen maken of er simpelweg helemaal niet aan gaan beginnen.

In iedergeval is het argument "ik beheers nog geen OOP" mijns inziens het slechtste argument om dan maar verder te blijven rommelen. Tip: Op youtube staat een heleboel dat je achterover leunend kunt bekijken met een zak chips op de bank die je vaak toch een duwtje in de goede richting kunnen geven. (let wel op of de filmpjes een beetje recent zijn en wellicht ten overvloede: chips zijn natuurlijk niet zo gezond :p)
Veel interessante posts.

Ik zal de huidige situatie toelichten. Ik heb 13 responsive pagina's, er komen nog een aantal bij, maar het zijn allemaal templates die slechts als doorgeefluik fungeren. Als ik naar de componenten kijk dan hebben we het over menu's, teksten, lijsten, afbeeldingen, maps en voor de rapporten en mails heb ik twee populaire classes.

Op de lijsten na kan ik tot nu toe alles afhandelen met de door mij ontwikkelde parser. Zodra ik while-loops vanuit de HTML kan aansturen kan ik alles gescheiden houden. Zodoende heb ik zo min mogelijk framework, maar net voldoende om precies te realiseren wat ik nu en hoogstwaarschijnlijk in de toekomst nodig heb. Dit heeft dan ook nog steeds mijn voorkeur.

Mocht er in de toekomst een hybride app toegevoegd worden (klein beetje native en de rest react) kan ik volgens mij gewoon een front-end koppelen aan mijn huidige structuur en de PHP code hergebruiken.

Ik weet dat ik een lid ben en geen betalende klant, maar als iemand mij in de juiste richting wil helpen, kan ik de ingeslagen koers voort blijven zetten.

Volgens mij ga je hier al verkeerd:

<?php
$aEen = array(1, 2, 3, 4 ,5, 6);
$aTwee = array('eerste titel', 'tweede titel', 'derde titel', 'vierde titel', 'vijfde titel', 'vierde titel', 'vijfde titel');
?>

Dit zou beter kunnen zijn:
<?php
$arr = array(
array(
'id' => 1,
'title' => 'eerste titel'
),
array(
'id' => 2,
'title' => 'tweede titel'
)
);
?>

Dit is namelijk ook de manier hoe het uit je database komt; altijd een rij tegelijk. Bovendien kun je de hele array in één loop doorlopen zonder super ingewikkeld te hoeven doen. Het is daarnaast ook verweg de meest gebruikte methode. Merk op dat de buitenste array numeriek is en de binnenste associatief. Een numerieke array loop je door met een foreach. Een associatieve array lijkt meer op een object waarin je de elementen van een naam voorziet.


[size=xsmall]Toevoeging op 06/02/2018 10:19:50:[/size]

<?php
foreach($arr as $row) {
echo 'Id: ' . $row['id'] . ', Titel: ' . $row['title'] . "<br>\n";
}
?>
Hoi Frank,

Bedankt voor je reactie. En dan dus met een replace [loopvar:id] vervangen voor $row['\\\1'] ?

En ik zou dus moeten achterhalen welke key bij welke index hoort om deze rechtstreeks aan te kunnen spreken ? [loopvar:(.*?)\] levert uiteraard geen nummer op.

Reageren