Skip to content

Commit

Permalink
Move template loader example to examples.md
Browse files Browse the repository at this point in the history
  • Loading branch information
jbboehr committed Nov 26, 2022
1 parent 7b6fcab commit 01c0426
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 73 deletions.
74 changes: 1 addition & 73 deletions README.md
Expand Up @@ -109,6 +109,7 @@ Well, 6000 dollars, after taxes.
```

See also: [template loader example](examples.md)

## Credits

Expand All @@ -120,76 +121,3 @@ Well, 6000 dollars, after taxes.
## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

## Examples

You can adapt this Mustache_Template_Loader class or use it as an
example of how to interface with whatever framework you use. The MustacheAST
type for example can serialized/unserialized to APCU or other cache.

```
class Mustache_Template_Loader {
public $partials = [];
public $partial_pathname_resolver = false;
public $mustache_instance = false;
/**
* Loads and renders a template from a path.
*
* @param string $tmplpath The input template filesystem path.
* @param mixed $data The data argument to Mustache::render.
* @param callable $callback Resolves a partial name to its filesystem path.
*
* @return false|string The string output, or false on failure
*/
public static function load_and_render($tmplpath, $data, $callback) {
$loader = new Mustache_Template_Loader();
$loader->mustache_instance = new \Mustache();
$loader->partial_pathname_resolver = $callback;
$template_string = file_get_contents($tmplpath);
$template_ast = $loader->mustache_instance->parse($template_string);
$template_ast_array = $template_ast->toArray();
$loader->resolve_partials($template_ast_array);
return $loader->mustache_instance->render($template_ast, $data, $loader->partials);
}
public function resolve_partials($ast_array) {
if (($ast_array['type'] ?? null) === 512) {
// The libmustache src/node.hpp has enum Type TypePartial = 512
$partial_name = $ast_array['data'];
$partial_ast = $this->partials[$partial_name] ?? null;
if ($partial_ast !== null) {
// this check prevents the performing of extra work
// and by corollary protects against indefinite recursion.
return;
}
$this->partials[$partial_name] = "";
$partial_pathname = ($this->partial_pathname_resolver)($partial_name);
$partial_string = file_get_contents($partial_pathname);
$partial_ast = $this->mustache_instance->parse($partial_string);
$this->partials[$partial_name] = $partial_ast;
$this->resolve_partials($partial_ast->toArray());
} else {
// For simplicity the AST node types are ignored here.
foreach ($ast_array as $ast_array_value) {
if (is_array($ast_array_value)) {
$this->resolve_partials($ast_array_value);
}
}
}
}
}
```
An example use of this class:

```
function template_pathname($partial_name) {
return '/usr/local/lib/templates/' . $partial_name . '.mustache';
}
echo Mustache_Template_Loader::load_and_render(
template_pathname('topview'),
$data,
'template_pathname'
);
```
74 changes: 74 additions & 0 deletions examples.md
@@ -0,0 +1,74 @@

## Examples

You can adapt this Mustache_Template_Loader class or use it as an
example of how to interface with whatever framework you use. The MustacheAST
type for example can serialized/unserialized to APCU or other cache.

```php
class Mustache_Template_Loader {
public $partials = [];
public $partial_pathname_resolver = false;
public $mustache_instance = false;

/**
* Loads and renders a template from a path.
*
* @param string $tmplpath The input template filesystem path.
* @param mixed $data The data argument to Mustache::render.
* @param callable $callback Resolves a partial name to its filesystem path.
*
* @return false|string The string output, or false on failure
*/
public static function load_and_render($tmplpath, $data, $callback) {
$loader = new Mustache_Template_Loader();
$loader->mustache_instance = new \Mustache();
$loader->partial_pathname_resolver = $callback;
$template_string = file_get_contents($tmplpath);
$template_ast = $loader->mustache_instance->parse($template_string);
$template_ast_array = $template_ast->toArray();
$loader->resolve_partials($template_ast_array);
return $loader->mustache_instance->render($template_ast, $data, $loader->partials);
}

public function resolve_partials($ast_array) {
if (($ast_array['type'] ?? null) === 512) {
// The libmustache src/node.hpp has enum Type TypePartial = 512
$partial_name = $ast_array['data'];
$partial_ast = $this->partials[$partial_name] ?? null;
if ($partial_ast !== null) {
// this check prevents the performing of extra work
// and by corollary protects against indefinite recursion.
return;
}
$this->partials[$partial_name] = "";
$partial_pathname = ($this->partial_pathname_resolver)($partial_name);
$partial_string = file_get_contents($partial_pathname);
$partial_ast = $this->mustache_instance->parse($partial_string);
$this->partials[$partial_name] = $partial_ast;
$this->resolve_partials($partial_ast->toArray());
} else {
// For simplicity the AST node types are ignored here.
foreach ($ast_array as $ast_array_value) {
if (is_array($ast_array_value)) {
$this->resolve_partials($ast_array_value);
}
}
}
}
}
```

An example use of this class:

```php
function template_pathname($partial_name) {
return '/usr/local/lib/templates/' . $partial_name . '.mustache';
}

echo Mustache_Template_Loader::load_and_render(
template_pathname('topview'),
$data,
'template_pathname'
);
```

0 comments on commit 01c0426

Please sign in to comment.