Skip to content

Instantly share code, notes, and snippets.

@kolber
Created November 13, 2009 01:59
Show Gist options
  • Save kolber/233519 to your computer and use it in GitHub Desktop.
Save kolber/233519 to your computer and use it in GitHub Desktop.
<?php
Class Page {
var $template;
var $partials;
#
# This faked data will be dynamically created (by searching through and parsing the /content folder) and stored within the Page class
#
var $data = array(
'/$false/' => false,
'/$true/' => true,
'/$pages/' => array(
array(
'/$name/' => 'About',
'/$url/' => './about-me/',
'/$children/' => false
),
array(
'/$name/' => 'Contact',
'/$url/' => './contact/',
'/$children/' => false
)
),
'/$category_list/' => array(
array(
'/$name/' => 'Projects',
'/$url/' => './projects/',
'/$children/' => array(
array(
'/$name/' => 'Project 1',
'/$url/' => './projects/project-1',
'/$children/' => false
),
array(
'/$name/' => 'Project 2',
'/$url/' => './projects/project-2',
'/$children/' => array(
array(
'/$name/' => 'Project 2 Movies',
'/$url/' => './projects/project-2/movies/',
'/$children/' => array(
array(
'/$name/' => 'Distant child',
'/$url/' => './projects/project-2/movies/long-lost-child'
),
array(
'/$name/' => 'Help, I am alive too!',
'/$url/' => './projects/project-2/movies/im-alive/'
)
)
),
array(
'/$name/' => 'Project 2 Flash Animations',
'/$url/' => './projects/project-2/swfs/',
'/$children/' => array(
array(
'/$name/' => 'Project 2 Flash Animation 1',
'/$url/' => './projects/project-2/swfs/swf1.swf',
'/$children/' => false
)
)
)
)
)
)
),
array(
'/$name/' => 'Blog',
'/$url/' => './blog/',
'/$children/' => array(
array(
'/$name/' => 'Entry 1',
'/$url/' => './blog/entry-1',
'/$children/' => false
)
)
)
)
);
function __construct() {
# store fake templates
$this->template = $GLOBALS['template'];
# store fake partials
$this->partials = $GLOBALS['partials'];
$this->render();
}
static function content_vars($content) {
$replacement_pairs = array();
# extract key/values from content file
preg_match_all('/[\w\d_-]+?:[\S\s]*?\n\n/', $content, $matches);
foreach($matches[0] as $match) {
$colon_split = explode(':', $match);
$replacement_pairs['/@'.$colon_split[0].'/'] = trim($colon_split[1]);
}
return $replacement_pairs;
}
function render() {
#
# This section fakes stacey's content file parser
#
# pull out each key/value pair from the content file and combine with the Faked page data
$data = array_merge($this->data, $this->content_vars($GLOBALS['content_file']."\n\n"));
# replace standard content variables
$parsed_content = Partial::parse($data, $this->template);
# render final output
echo $parsed_content;
}
}
Class Partial {
static function get_partial_template($name) {
return (isset($GLOBALS['partials'][$name])) ? $GLOBALS['partials'][$name] : '\'/templates/partials/'.$name.'.html\' not found';
// return (file_exists('../templates/partials'.$name.'.html')) ? file_get_contents('../templates/partials'.$name.'.html') : '\'/templates/partials/'.$name.'.html\' not found';
}
static function parse($data, $template) {
$template = Partial::parse_if($data, $template);
$template = Partial::parse_foreach($data, $template);
$template = Partial::parse_includes($data, $template);
$template = Partial::parse_vars($data, $template);
return $template;
}
static function parse_if($data, $template) {
# match any inner if statements
preg_match('/([\S\s]*?)if\s+?(\$.+?)\?\s+?do([\S\s]+?)endif([\S\s]*)$/', $template, $template_parts);
if(!empty($template_parts)) {
# Run the replacements on the pre-"if" part of the partial
$template = Partial::parse($data, $template_parts[1]);
# If the condition is true
if(isset($data['/'.$template_parts[2].'/']) && ($data['/'.$template_parts[2].'/'])) {
# Parse the block inside the if statement
$template .= Partial::parse($data, $template_parts[3]);
}
# Run the replacements on the post-"if" part of the partial
$template .= Partial::parse($data, $template_parts[4]);
}
return $template;
}
static function parse_foreach($data, $template) {
# Split out the partial into the parts Before, Inside, and After the foreach loop
preg_match('/([\S\s]*?)foreach[\s]+?(\$.+?)[\s]+?do([\S\s]+)end([\S\s]*)$/', $template, $template_parts);
if(!empty($template_parts)) {
# Run the replacements on the pre-"foreach" part of the partial
$template = Partial::parse($data, $template_parts[1]);
# Traverse one level deeper into the data hierachy
$pages = $data['/'.$template_parts[2].'/'];
if ($pages) {
foreach ($pages as $data_item) {
# Recursively parse the inside part of the foreach loop
$template .= Partial::parse($data_item, $template_parts[3]);
}
}
# Run the replacements on the post-"foreach" part of the partial
$template .= Partial::parse($data, $template_parts[4]);
}
return $template;
}
static function parse_includes($data, $template) {
# Split out the partial into the parts Before, Inside, and After the :include
preg_match('/([\S\s]*?):([\w\d-_]+?)(\.html)?\b([\S\s]*)$/', $template, $template_parts);
###### TODO: There is no protection against endless loops due to circular inclusions
if (!empty($template_parts)) {
# Run the replacements on the pre-":include" part of the partial
$template = Partial::parse($data, $template_parts[1]);
# Parse the included template
$inner_template = Partial::get_partial_template($template_parts[2]);
$template .= Partial::parse($data, $inner_template);
# Run the replacements on the post-":include" part of the partial
$template .= Partial::parse($data, $template_parts[4]);
}
return $template;
}
static function parse_vars($data, $template) {
# Split out the partial into the parts Before, Inside, and After the @var
preg_match('/([\S\s]*?)([\@\$][\w\d-_]+?)\b([\S\s]*)$/', $template, $template_parts);
if (!empty($template_parts)) {
# Run the replacements on the pre-"@var" part of the partial
$template = Partial::parse($data, $template_parts[1]);
# Replace the @var
$var = $data['/'.$template_parts[2].'/'];
if ($var && is_string($var)) {
$template .= $var;
}
# Run the replacements on the post-"@var" part of the partial
$template .= Partial::parse($data, $template_parts[3]);
}
return $template;
}
}
# ----------------------------------------------------------
#
#
# Faked Content file
#
#
$content_file = <<<EOS
title: Stacey, new partials (proof of concept)
EOS;
#
#
# Faked Template
#
#
$template = <<<EOS
<html>
<head>
<title>@title</title>
</head>
<body>
<h1>@title</h1>
<div id="container">
<hr>
:pages
<hr>
:category_list
<hr>
:non_existant_partial
<hr>
if \$true? do
:footer.html
endif
</div>
</body>
</html>
EOS;
#
#
# Faked Partials
#
#
$pages_partial_html = <<<EOS
<ol id="wrapper">
foreach \$pages do
<li>:link</li>
end
</ol>
EOS;
$categories_partial_html = <<<EOS
<ol id="wrapper">
foreach \$category_list do
:link
:children
end
</ol>
EOS;
$footer_partial_html = <<<EOS
<div id="footer">
if \$category_list? do
<p>Footer.</p>
endif
if \$images? do
<p>show images here</p>
endif
</div>
EOS;
$link_partial_html = <<<EOS
<a class="page-link" href="\$url">\$name</a>
EOS;
$children_partial_html = <<<EOS
if \$children? do
<ol class="children" title="Children of \$url">
foreach \$children do
<li>
:link
:children
</li>
end
</ol>
endif
EOS;
#
# This variable will be created by looping through each file within /templates/partials
#
$partials = array(
'pages' => $pages_partial_html,
'category_list' => $categories_partial_html,
'footer' => $footer_partial_html,
'children' => $children_partial_html,
'link' => $link_partial_html
);
#
#
# Init
#
#
$p = new Page;
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment