Skip to content

Instantly share code, notes, and snippets.

@speedmax
Created February 11, 2009 07:47
Show Gist options
  • Save speedmax/61903 to your computer and use it in GitHub Desktop.
Save speedmax/61903 to your computer and use it in GitHub Desktop.
h2o code generation concept, 4 and 5 are executable code
<h1>{{ person.name }}</h1>
{% block content %}
<small>block:{{ block.name }}, level: {{ block.depth }} ?></small>
(i am {{ block.age }} years old)
{% endblock %}
<ul>
{% for hobby in person.hobbies %}
<li>{{ hobby|capitalize }}</li>
{% endfor %}
</ul>
{% extends 'template.html' %}
{% block content %}
<small>block:{{ block.name }}, level: {{ block.depth }} ?></small>
(says hello from sub template)
{{ block.super }}
{% endblock %}
{% extends 'child_template.html' %}
{% block content %}
<small>block:{{ block.name }}, level: {{ block.depth }} ?></small>
(says hello from sub sub template)
{{ block.super }}
{% endblock %}
<?php
include 'lib.php';
$person = array('name'=>'taylor', 'age'=>18, 'hobbies'=>array('watch tv','swimming'));
$c = new Context(compact('person'));
?>
<h1><?= $c['person.name'] ?></h1>
<? // Content block
function block_content_1($c) {?>
<small>block: <?= $c['block.name']?>, level: <?= $c['block.depth'] ?></small>
(i am <?= $c['person.age'] ?> years old)
<?}
function block_content_2($c) {?>
<small>block: <?= $c['block.name']?>, level: <?= $c['block.depth'] ?></small>
(says hello from sub template)
<?= $c['block.super'] ?>
<?}
function block_content_3($c) {?>
<small>block: <?= $c['block.name']?>, level: <?= $c['block.depth'] ?></small>
(says hello from sub sub template)
<?= $c['block.super'] ?>
<?}
?>
<?= Block::register('content', 3, $c) ?>
<h3>i'd like to</h3>
<ul>
<? foreach((array)$c['person.hobbies'] as $hobby):
$c->push(compact('hobby'));
?>
<li><?= ucwords($c['hobby']) ?></li>
<?
$c->pop();
endforeach ?>
</li>
<?php
class Context extends ArrayObject {
function __construct($scope = array()) {
$this->scopes = array($scope);
}
function resolve($path) {
$parts = explode('.', $path);
$target = $this[array_shift($parts)];
foreach($parts as $part) {
if (is_array($target) && isset($target[$part]))
$target = $target[$part];
elseif (is_object($target) && property_exists($target, $part))
$target = $target->$part;
elseif (is_object($target) && method_exists($target, $part))
$target = $target->$part();
else return null;
}
return $target;
}
function pop() {
array_shift($this->scopes);
}
function push($stack = array()) {
array_unshift($this->scopes, $stack);
}
function offsetGet($key) {
if (strpos($key, '.') !== false)
return $this->resolve($key);
foreach ($this->scopes as &$layer) {
if (isset($layer[$key]))
return $layer[$key];
}
}
function offsetExists($key) {
return $this->offsetGet($key) !== null;
}
function offsetSet($key, $value) {
$this->scopes[0][$key] = $value;
}
}
class Block {
var $name, $depth, $super;
var $context;
function __construct($name, $depth, $context) {
$this->depth = $depth;
$this->name = $name;
$this->context = $context;
}
function __toString() {
$callback = "block_{$this->name}_{$this->depth}";
$this->context->push(array('block'=>$this));
$callback($this->context);
$this->context->pop();
return '';
}
static function register($name, $depth, $c) {
$blocks = array();
for ($i=0; $i < $depth; $i++) {
$blocks[$i] = $block =& new Block($name, $i+1, $c);
if ($i) {
$block->super =& $blocks[$i-1];
}
}
return end($blocks);
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment