Created
November 20, 2009 03:00
-
-
Save kolber/239250 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 | |
Class Helpers { | |
static function sort_by_length($a,$b){ | |
if($a == $b) return 0; | |
return (strlen($a) > strlen($b) ? -1 : 1); | |
} | |
static function file_path_to_url($file_path) { | |
return preg_replace(array('/\d+?\./', '/\.\.\/content(\/)?/'), '', $file_path); | |
} | |
static function url_to_file_path($url) { | |
$file_path = '../content'; | |
// Split the url and recursively unclean the parts into folder names | |
$url_parts = explode('/', $url); | |
foreach($url_parts as $u) { | |
// Look for a folder at the current $path | |
$matches = Helpers::list_files($file_path, '/^\d+?\.'.$u.'$/', true); | |
// No matches means a bad url | |
if (empty($matches)) return false; | |
else $file_path .= '/'.$matches[0]; | |
} | |
return $file_path; | |
} | |
static function has_children($dir) { | |
// check if this folder contains inner folders - if it does, then it is a category | |
$inner_folders = Helpers::list_files($dir, '/.*/', true); | |
return !empty($inner_folders); | |
} | |
static function list_files($dir, $regex, $folders_only = false) { | |
if(!is_dir($dir)) return array(); | |
$glob = ($folders_only) ? glob($dir."/*", GLOB_ONLYDIR) : glob($dir."/*"); | |
if(!$glob) return array(); | |
// loop through each glob result and push it to $dirs if it matches the passed regexp | |
$files = array(); | |
foreach($glob as $file) { | |
// strip out just the filename | |
preg_match('/\/([^\/]+?)$/', $file, $slug); | |
if(preg_match($regex, $slug[1])) $files[] = $slug[1]; | |
} | |
// sort list in reverse-numeric order | |
rsort($files, SORT_NUMERIC); | |
return $files; | |
} | |
} | |
Class Page { | |
var $url; | |
var $slug; | |
var $parent_path; | |
var $file_path; | |
var $content_file; | |
var $data; | |
function __construct($url) { | |
$this->url = $url; | |
$this->file_path = Helpers::url_to_file_path($url); | |
# if file doesn't exist, throw a 404 exception | |
if(!file_exists($this->file_path)) throw new Exception('404. Page does not exist.'); | |
$this->content_file = $this->content_file(); | |
# | |
$split_url = explode("/", $url); | |
$this->slug = $split_url[count($split_url) - 1]; | |
# $this->parent_slug = (count($split_url) > 1) ? $split_url[count($split_url) - 2] : false; | |
array_pop($split_url); | |
$this->parent_path = implode("/", $split_url); | |
# create content data from content file | |
ContentData::create($this); | |
# if not called from the root document, don't create additional template_data | |
if($this->caller()) return; | |
# | |
TemplateData::create($this); | |
# recursively sort data arrays by length | |
# uksort($template_data, array('Helpers', 'sort_by_length')); | |
echo '<pre>'; | |
var_dump($this->data); | |
echo '</pre><br>---<br>'; | |
} | |
function __call($name, $arguments) { | |
if(preg_match('/set(.*)/', $name, $name)) { | |
# convert multiple words to underscores -- a function call of setCategoryList will create the array index $category_list | |
$var_name = strtolower(preg_replace('/(?<=.)([A-Z])/', '_\1', $name[1])); | |
# save into cash_data array | |
$this->data['/$'.$var_name.'/'] = $arguments[0]; | |
} | |
} | |
# magic variable assignment method | |
function __set($name, $value) { | |
$this->data['/@'.$name.'/'] = $value; | |
} | |
function caller() { | |
$backtrace = debug_backtrace(); | |
return isset($backtrace[3]['class']) ? $backtrace[3]['class'] : false; | |
} | |
function content_file() { | |
$txts = Helpers::list_files($this->file_path, '/\.txt$/'); | |
return (!empty($txts)) ? preg_replace('/\.txt$/', '', $txts[0]) : false; | |
} | |
} | |
Class ContentData { | |
static function preparse($text) { | |
$patterns = array( | |
// replace inline colons | |
'/(?<=\n)([a-z0-9_-]+?):(?!\/)/', | |
'/:/', | |
'/\\\x01/', | |
// replace inline dashes | |
'/(?<=\n)-/', | |
'/-/', | |
'/\\\x02/', | |
// automatically link http:// websites | |
'/(?<![">])\bhttp:\/\/([\S]+\.[\S]*\.?[A-Za-z0-9]{2,4})/', | |
// automatically link email addresses | |
'/(?<![;>])\b([A-Za-z0-9.-]+)@([A-Za-z0-9.-]+\.[A-Za-z]{2,4})/', | |
// convert lists | |
'/\n?-(.+?)(?=\n)/', | |
'/(<li>.*<\/li>)/', | |
// replace doubled lis | |
'/<\/li><\/li>/', | |
// replace headings h1. h2. etc | |
'/h([0-5])\.\s?(.*)/', | |
// wrap multi-line text in paragraphs | |
'/([^\n]+?)(?=\n)/', | |
'/<p>(.+):(.+)<\/p>/', | |
'/: (.+)(?=\n<p>)/', | |
// replace any keys that got wrapped in ps | |
'/(<p>)([a-z0-9_-]+):(<\/p>)/', | |
// replace any headings that got wrapped in ps | |
'/<p>(<h[0-5]>.*<\/h[0-5]>)<\/p>/' | |
); | |
$replacements = array( | |
// replace inline colons | |
'$1\\x01', | |
':', | |
':', | |
// replace inline dashes | |
'\\x02', | |
'-', | |
'-', | |
// automatically link http:// websites | |
'<a href="http://$1">http://$1</a>', | |
// automatically link email addresses | |
'<a href="mailto:$1@$2">$1@$2</a>', | |
// convert lists | |
'<li>$1</li>', | |
'<ul>$1</ul>', | |
// replace doubled lis | |
'</li>', | |
// replace headings h1. h2. etc | |
'<h$1>$2</h$1>', | |
// wrap multi-line text in paragraphs | |
'<p>$1</p>', | |
'$1:$2', | |
':<p>$1</p>', | |
// replace any keys that got wrapped in ps | |
'$2:', | |
'$1' | |
); | |
$parsed_text = preg_replace($patterns, $replacements, $text); | |
return $parsed_text; | |
} | |
static function create($page) { | |
## store contents of content file (if it exists, otherwise, pass back an empty string) | |
$content_file_path = $page->file_path.'/'.$page->content_file.'.txt'; | |
$text = (file_exists($content_file_path)) ? file_get_contents($content_file_path) : ''; | |
# include shared variables for each page | |
$shared = (file_exists('../content/_shared.txt')) ? file_get_contents('../content/_shared.txt') : ''; | |
# run preparsing rules to clean up content files (the newlines are added to ensure the first and last rules have their double-newlines to match on) | |
$parsed_text = self::preparse("\n\n".$text."\n\n".$shared."\n\n"); | |
# pull out each key/value pair from the content file | |
preg_match_all('/[\w\d_-]+?:[\S\s]*?\n\n/', $text, $matches); | |
foreach($matches[0] as $match) { | |
$colon_split = explode(':', $match); | |
# store page variables within Page::data | |
$page->$colon_split[0] = trim($colon_split[1]); | |
} | |
# set page name, url and thumbnail | |
$page->setName(ucfirst(preg_replace('/[-_](.)/e', "' '.strtoupper('\\1')", $page->slug))); | |
$page->setUrlPath($page->url); | |
# thumbnail | |
} | |
} | |
Class TemplateData { | |
static $navigation_tree; | |
static function extract_files() { | |
} | |
static function extract_pages() { | |
$pages = array(); | |
foreach(NavigationTree::$nested_tree as &$page) if(!$page['/$children/']) $pages[] =& $page; | |
return $pages; | |
} | |
static function extract_categories() { | |
$categories = array(); | |
foreach(NavigationTree::$nested_tree as &$page) if($page['/$children/']) $categories[] =& $page; | |
return $categories; | |
} | |
static function extract_siblings($pages) { | |
$siblings = array(); | |
foreach($pages as $key => &$page) $siblings[$key] =& $page; | |
return $siblings; | |
} | |
static function extract_closest_siblings($siblings, $file_path) { | |
# store keys as array | |
$keys = array_keys($siblings); | |
$keyIndexes = array_flip($keys); | |
$neighbors = array(); | |
# previous sibling | |
if (isset($keys[$keyIndexes[$file_path] - 1])) $neighbors[] = $siblings[$keys[$keyIndexes[$file_path] - 1]]; | |
else $neighbors[] = $siblings[$keys[count($keys) - 1]]; | |
# next sibling | |
if (isset($keys[$keyIndexes[$file_path] + 1])) $neighbors[] = $siblings[$keys[$keyIndexes[$file_path] + 1]]; | |
else $neighbors[] = $siblings[$keys[0]]; | |
return $neighbors; | |
} | |
static function create($page) { | |
# build navigation tree | |
NavigationTree::build(); | |
# $navigation | |
$page->setNavigation(NavigationTree::$nested_tree); | |
# $pages | |
$page->setPages(self::extract_pages()); | |
# $categories | |
$page->setCategories(self::extract_categories()); | |
# $folder_name? | |
### These values are not being passed by reference (which effect memory usage unless the array item it is referencing changes after these reference are created) | |
# $parent | |
if($page->parent_path) $parent_reference = NavigationTree::$flat_tree[Helpers::url_to_file_path($page->parent_path)]; | |
else $parent_reference = false; | |
$page->setParent($parent_reference); | |
# $children | |
$children_reference = (isset(NavigationTree::$flat_tree[Helpers::url_to_file_path($page->slug)]['/$children/'])) ? NavigationTree::$flat_tree[Helpers::url_to_file_path($page->slug)]['/$children/'] : false; | |
$page->setChildren($children_reference); | |
# $siblings | |
$siblings = ($parent_reference) ? $parent_reference['/$children/'] : self::extract_siblings(NavigationTree::$nested_tree); | |
$page->setSiblings($siblings); | |
# $next_sibling / $previous_sibling | |
$neighbors = self::extract_closest_siblings($siblings, $page->file_path); | |
$page->setPreviousSibling($neighbors[0]); | |
$page->setNextSibling($neighbors[1]); | |
### | |
# $images | |
# $video | |
# $media | |
# $.swf | |
# $.doc | |
# etc. | |
} | |
} | |
Class NavigationTree { | |
static $flat_tree; | |
static $nested_tree; | |
static $replaced_data; | |
static function build($dir = '../content') { | |
# create both a nested tree and a flat tree at the same time | |
self::$nested_tree = self::nested_tree($dir); | |
return self::$nested_tree; | |
} | |
static function nested_tree($dir) { | |
$files = array(); | |
foreach(Helpers::list_files($dir, '/.+/', true) as $file) { | |
# fill flat file array | |
$page = new Page(Helpers::file_path_to_url($dir.'/'.$file)); | |
self::$flat_tree[$dir.'/'.$file] = $page->data; | |
# store reference to flat tree array item | |
$reference =& self::$flat_tree[$dir.'/'.$file]; | |
$files[$dir.'/'.$file] = &$reference; | |
# recurse through any children | |
$files[$dir.'/'.$file]['/$children/'] = (Helpers::has_children($dir.'/'.$file)) ? self::nested_tree($dir.'/'.$file) : false; | |
} | |
return $files; | |
} | |
} | |
Class Stacey { | |
static $version = '1.1'; | |
function __construct($get) { | |
# $page = new Page('about'); | |
# $page = new Page('projects'); | |
# $page = new Page('projects/project-name-10'); | |
$page = new Page('projects/movie-project-2/sub-movie-project'); | |
# $page = new Page('projects/movie-project-2/2008'); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment