#12 - form live preview

This commit was merged in pull request #14.
This commit is contained in:
Martin Slachta
2026-06-14 14:13:37 +02:00
parent 0fc0addf47
commit 2890a9b993
8 changed files with 375 additions and 32 deletions
+32 -10
View File
@@ -49,18 +49,27 @@ class RsvTemplateEngine {
/**
* Lists a template's problems without rendering it (empty = valid): empty
* interpolations, unregistered custom elements, and attributes an element
* does not declare.
* interpolations, references to unknown symbols, unregistered custom
* elements, and attributes an element does not declare.
*
* @param list<string>|null $symbols When given, the roots an interpolation may
* reference; a path rooted outside the set is reported as unknown. Null
* skips the reference check (any path is accepted).
* @return list<string>
*/
public function validate(string $source): array {
public function validate(string $source, ?array $symbols = null): array {
$errors = [];
if (preg_match_all('/{{\s*([^}]*?)\s*}}/', $source, $matches)) {
foreach ($matches[1] as $path) {
if (trim($path) === '') {
$expr = trim($path);
if ($expr === '') {
$errors[] = 'Empty interpolation: {{ }}';
continue;
}
$root = $this->tokens($expr)[0] ?? null;
if ($symbols !== null && $root !== null && !in_array($root, $symbols, true)) {
$errors[] = "Unknown reference: {{ {$expr} }}";
}
}
}
@@ -148,14 +157,9 @@ class RsvTemplateEngine {
* @param array<string, mixed> $data
*/
private function resolve(string $path, array $data): mixed {
$tokens = preg_split('/[\.\[\]]+/', $path, -1, PREG_SPLIT_NO_EMPTY) ?: [];
$current = $data;
foreach ($tokens as $token) {
if ($token === '$') {
continue; // root sigil
}
$token = trim($token, "'\""); // strip bracket-notation quotes
foreach ($this->tokens($path) as $token) {
if (!is_array($current) || !array_key_exists($token, $current)) {
return null;
}
@@ -165,6 +169,24 @@ class RsvTemplateEngine {
return $current;
}
/**
* Splits a JSON Path into its key tokens, dropping the root sigil and
* bracket-notation quotes — e.g. "$.items[0]" yields ['items', '0'].
*
* @return list<string>
*/
private function tokens(string $path): array {
$raw = preg_split('/[\.\[\]]+/', $path, -1, PREG_SPLIT_NO_EMPTY) ?: [];
$tokens = [];
foreach ($raw as $token) {
if ($token === '$') {
continue; // root sigil
}
$tokens[] = trim($token, "'\""); // strip bracket-notation quotes
}
return $tokens;
}
// -------------------------------------------------------------------------
// DOM helpers
// -------------------------------------------------------------------------