Le dipendenze implicite sono cattive, specialmente se il tuo motore di template non si lamenterà delle variabili mancanti. Credo che sarebbe vantaggioso per ogni frammento di modello sapere quali variabili ha bisogno e rifiutare di essere renderizzato o istanziato con argomenti sbagliati.
Ecco un esempio in cui la mancanza di scoping introdurrà difficoltà:
$academic_staff_template = "
<div>
<h4>{{ title }} {{ name }}</h4>
{{ bio }}
</div>
";
$lecturer = new HtmlBuilder([], $academic_staff_template);
$lecture_template = "
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>Lecture {{ title }}</h1>
{{ description }}
{{ lecturer }}
</body>
</html>
";
$vars = [
"title" => "Archaeology 101",
"description" => "...",
"lecturer" => $lecturer,
"name" => 'Henry Walton "Indiana" Jones, Jr.',
"title" => "Dr.",
"bio" => "...",
];
$lecture = new HtmlBuilder($vars, $lexture_template);
Entrambi i modelli usano una variabile title
, ma usano lo stesso nome per indicare qualcosa di completamente diverso. Il tuo progetto attuale produrrebbe questo output renderizzato:
<html>
<head>
<title>Dr.</title>
</head>
<body>
<h1>Lecture Dr.</h1>
...
<div>
<h4>Henry Walton "Indiana" Jones, Jr.</h4>
...
</div>
</body>
</html>
A volte, è estremamente utile includere un altro modello senza inserire un nuovo scope variabile. Ad esempio, {% include "snippet/footer" %}
potrebbe essere una direttiva utile per caricare uno snippet. Ma se cerchi di creare modelli incapsulati e liberamente accoppiati , questo si sta verificando direttamente in scontri con lo spazio dei nomi e tutti i tipi di problemi.
Ecco un'idea: quando analizzi un modello, prendi nota di tutte le variabili richieste. Tale modello analizzato può essere visualizzato in due modi:
- Tramite l'API:
$result = $engine->parse($source)->render(["var1" => "value1"])
. Il metodo render
genera un'eccezione se non vengono fornite tutte le variabili necessarie.
- All'interno del linguaggio del modello: se
block
è associato a un oggetto modello analizzato, la sintassi come {{ block var1: "value" var2: someVariable }}
potrebbe rendere il modello. Nessuna variabile tranne quelle passate esplicitamente sarebbe disponibile all'interno del blocco. Se gli argomenti specificati non corrispondono agli argomenti richiesti da block
, verrebbe generato un errore.
Poiché alcuni dati appartengono naturalmente insieme, sarebbe fantastico offrire l'accesso agli array all'interno del tuo linguaggio template. Quindi potremmo passare un singolo dizionario con informazioni sul docente al modello dello staff accademico. Ecco come progetterei quell'interfaccia:
$lecturer_template = $engine->parse("
<div>
<h4>{{ person.title }} {{ person.name }}</h4>
{{ person.bio }}
</div>
");
$page_template = $engine->parse("
<html>
<head>
<title>{{ course.title }}</title>
</head>
<body>
<h1>Lecture {{ course.title }}</h1>
{{ course.description }}
{{ lecturer person: course.lecturer }}
</body>
</html>
");
$course = [
"title" => "Archaeology 101",
"description" => "...",
"lecturer" => [
"name" => "Henry Walton \"Indiana\" Jones, Jr.",
"title" => "Dr.",
"bio" => "...",
],
];
$result = $page_template->render(["course" => $course, "lecturer" => $lecturer_template]);