Last active
November 6, 2019 10:19
-
-
Save Potherca/94c0ba1449a2ee57aafddf961f3ebe5d to your computer and use it in GitHub Desktop.
A minimal implementation of Mustache in PHP. Supports escaped and HTML Variables, Comments, Sections and Inverted Section. Does not support Lists, Callbacks, Partials or Delimiter setting.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* In Mustache syntax, values are represented by "tags". | |
* | |
* Tags are indicated by double braces (a.k.a. curly brackets): {{name}} | |
* | |
* To check if a value is available use a "section". A section is a tag that is | |
* prefixed with a pound `#` character. The closing tag is prefixed with a | |
* slash `/`. For example, to only show "name" when it is available: | |
* | |
* {{#name}} | |
* <p>{{name}}</p> | |
* {{/name}} | |
* | |
* To show content when a value is NOT available, use an inverted section. An | |
* inverted section is a tag prefixed with a caret `^`. The closing tag is | |
* prefixed with a slash `/`. For example, to show content when "name" is not | |
* available: | |
* | |
* {{^name}} | |
* <p>No name available!</p> | |
* {{/name}} | |
* | |
* All values are HTML escaped by default. To have unescaped HTML, use triple | |
* braces: {{{name}}} | |
* | |
* To add comments, prefix a tag with an exclamation mark `!` (comments may | |
* contain newlines): {{! this is a comment }} | |
* | |
* @author Potherca <potherca@gmail.com> | |
* @copyright 2016 Potherca | |
* @license GPLv3+ | |
* @version 0.4.0 | |
* | |
* @see https://gist.github.com/Potherca/94c0ba1449a2ee57aafddf961f3ebe5d/ | |
*/ | |
/** | |
* A minimal implementation of Mustache in PHP. | |
* | |
* Supports escaped and HTML Variables, Comments, Sections and Inverted Section. | |
* Does not support Lists, Callbacks, Partials or Delimiter setting. | |
* | |
* @param string $template | |
* @param array $context | |
* | |
* @return string | |
*/ | |
function mini_mustache($template, array $context = []) | |
{ | |
$pattern = '@({{)(?<SECTION_TYPE>#|\^)(?P<SECTION_NAME>[a-zA-Z\-\_\.]+)(}})(?P<SECTION_CONTENT>.*?)({{/\3}})@sm'; | |
$template = preg_replace_callback($pattern, function (array $matches) use ($context) { | |
$result = ''; | |
$key = $matches['SECTION_NAME']; | |
if ($matches['SECTION_TYPE'] === '^') { | |
// Inverted Section, will be rendered if the key doesn't exist, is false, or is an empty list | |
if (!array_key_exists($key, $context) || empty($context[$key])) { | |
$result = $matches['SECTION_CONTENT']; | |
} | |
} elseif ($matches['SECTION_TYPE'] === '#') { | |
// Section, will be rendered if the key exists and has a value of true or is an non-empty list | |
if (array_key_exists($key, $context) && !empty($context[$key])) { | |
$result = $matches['SECTION_CONTENT']; | |
} | |
} else { | |
throw new \UnexpectedValueException('Unknown section type in template.'); | |
} | |
return $result; | |
}, $template); | |
$pattern = '/{{\!\s?(?P<COMMENT>.+)\s?}}|{{{\s?(?P<HTML_RAW>[a-zA-Z\-\_\.]+)\s?}}}|{{\s?(?P<HTML_ENCODE>[a-zA-Z\-\_\.]+)\s?}}/m'; | |
return preg_replace_callback($pattern, function (array $matches) use ($context) { | |
if ($matches['COMMENT'] !== '') { | |
$result = ''; | |
} elseif ($matches['HTML_RAW'] !== '') { | |
$encode = false; | |
$key = $matches['HTML_RAW']; | |
} elseif ($matches['HTML_ENCODE'] !== '') { | |
$encode = true; | |
$key = $matches['HTML_ENCODE']; | |
} else { | |
throw new \UnexpectedValueException('Unknown tag type in template.'); | |
} | |
if (!isset($result) && isset($key)) { | |
$result = $key; | |
if (array_key_exists($key, $context)) { | |
$result = $context[$key]; | |
if (isset($encode) && (bool) $encode === true) { | |
$result = htmlentities($result, ENT_HTML5 | ENT_QUOTES); | |
} | |
} | |
} | |
return $result; | |
}, $template); | |
} | |
/*EOF*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment