Created
November 8, 2013 12:06
-
-
Save evansolomon/7370101 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
/* | |
Example usage: | |
$template = new Medium_Template( 'Hi, I am {{name|html}}.' ); | |
echo $template->compile( array( 'name' => '<b>Evan</b>' ) ); | |
// Hi, I am <b>Evan</b>. | |
echo $template->compile( array( 'name' => 'someone else' ) ); | |
// Hi, I am someone else. | |
*/ | |
/** | |
* A *very* simple mustache-style template utility. | |
*/ | |
class Medium_Template { | |
/** | |
* Create a template instance with an (uncompiled) template string. Templates | |
* are a very basic version of mustache-style, plus an optional pipe-delimited | |
* escape callback. Escape callbacks are prefixed with esc_ by default. | |
*/ | |
function __construct( $template ) { | |
$this->template = $template; | |
$this->pattern = '/\{{2}(.+?)\}{2}/'; | |
$this->esc_delimiter = '|'; | |
} | |
/** | |
* Return the compiled output of the template with the given data. Missing fields | |
* are interpretted as empty strings. | |
*/ | |
function compile( $data ) { | |
$tokens = $this->get_tokens(); | |
return $this->replace( $tokens, $data ); | |
} | |
/** | |
* Get a list of replacement tokens without the surrounding identifiers. | |
*/ | |
function get_tokens() { | |
preg_match_all( $this->pattern, $this->template, $matches ); | |
return $matches[1]; | |
} | |
/** | |
* Replace each token with its underlying data. Escape the data with its | |
* optional callback. | |
*/ | |
function replace( $tokens, $data ) { | |
$template = $this->template; | |
foreach ( $tokens as $token ) { | |
$target = $this->wrap_token( $token ); | |
$token_parts = $this->parse_token( $token ); | |
$escape = $token_parts['escape']; | |
if ( isset( $data[ $token_parts['name'] ] ) ) { | |
$input = $data[ $token_parts['name'] ]; | |
} else { | |
$input = ''; | |
} | |
$replacement = $this->maybe_escape( $input, $escape ); | |
$template = str_replace( $target, $replacement, $template ); | |
} | |
return $template; | |
} | |
/** | |
* Convert a token to a replacement string. | |
*/ | |
function wrap_token( $token ) { | |
return '{{' . $token . '}}'; | |
} | |
/** | |
* Split a token into its name and optional escape callback. | |
*/ | |
function parse_token( $token ) { | |
$data = array(); | |
$parts = array_map( 'trim', explode( $this->esc_delimiter, $token ) ); | |
$data['name'] = $parts[0]; | |
$data['escape'] = count( $parts ) > 1 ? $parts[1] : false; | |
return $data; | |
} | |
/** | |
* Escape data with a callback only when the callback is valid. | |
*/ | |
function maybe_escape( $data, $callback ) { | |
$callback = "esc_{$callback}"; | |
if ( ! is_callable( $callback ) ) { | |
return $data; | |
} | |
return call_user_func( $callback, $data ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment