Skip to content

Instantly share code, notes, and snippets.

@xergio
Created March 24, 2012 23:16
Show Gist options
  • Save xergio/2188970 to your computer and use it in GitHub Desktop.
Save xergio/2188970 to your computer and use it in GitHub Desktop.
A PHP implementation to parse django template vars
<?php
/*
Sergio Álvarez Muñoz
xergio@gmail.com
https://sergio.am
Basado en el sistema de templates de Django.
Snipper adaptado de http://effbot.org/zone/django-simple-template.htm
*/
define("TEMPLATE_STRING_IF_INVALID", "");
function render($template, $context) {
$tokens = preg_split("#({{|}})#", $template, -1, PREG_SPLIT_DELIM_CAPTURE);
$data = array();
$jump = 0;
foreach ($tokens as $i => $token) {
if ($jump-- > 0) continue;
if ($token == "{{") { # variable
$data[] = variable($tokens[$i+1], $context);
if ($tokens[$i+2] != "}}")
throw new Exception("missing variable terminator");
$jump = 2;
} else {
$data[] = $token; # literal
}
}
return implode("", $data);
}
function variable($name, $context) {
$name = trim($name);
$obj = $context;
if (strpos($name, "|") !== false)
list($name, $filters) = explode("|", $name, 2);
foreach (explode(".", $name) as $item) {
if (is_array($obj) and array_key_exists($item, $obj)) {
$obj = $obj[$item]; # dictionary member
} else if (is_object($obj)) {
if (property_exists($obj, $item)) {
$obj = $obj->$item; # or attribute
} else if (method_exists($obj, $item)) {
$obj = $obj->$item();
}
} else {
$obj = TEMPLATE_STRING_IF_INVALID;
break;
}
}
if (isset($filters)) {
if (function_exists($filters)) {
$obj = call_user_func($filters, $obj);
}
}
return $obj;
}
$test = <<<TEST
<h1>{{ section.title }}</h1>
<h2>
<a href="{{ story.get_absolute_url }}">
{{ story.headline|strtoupper }}
</a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
TEST;
class FakeSection {
public $title = "trololo";
}
class FakeStory {
function __construct($headline, $tease) {
$this->headline = $headline;
$this->tease = $tease;
}
function get_absolute_url() {
return "Absolute/Url";
}
}
$input = array(
"section" => new FakeSection(),
"story" => new FakeStory("Headline!", "Tease... brrrr")
);
print_r(render($test, $input));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment