Permalink
Browse files

added git project

  • Loading branch information...
1 parent 31f2cfa commit 3b0fb9cf7facb4333fe26230bfad8af232600db5 @jasonlong committed Sep 28, 2012
View
@@ -1,4 +1,5 @@
## Overview
+
I've made this repo public so that it might help others learn from how it is put together. And better yet, maybe someone will let me know about things that could be improved (though I have a list of improvements to make already). Please feel free to download the code or fork it for your own spelunking, but please don't copy it wholesale as if you built it.
The site is built on Stacey (<http://staceyapp.com>). This is a great little CMS that doesn't require a backend database. All of the content and assets are stored in directories. It's a perfect system for lightweight portfolio sites.
@@ -9,12 +10,12 @@ A few of the things you may find nifty:
* Page content fades in once TypeKit fonts load (to avoid "flash of unstyled content").
* Pseudo-parallax effect for the background while scrolling.
-* Animated portfolio section - lots 'o animation and AJAX via MooTools.
+* Animated portfolio section - lots 'o animation and AJAX via MooTools.
* Animated contact form (3D transform for flipping the form in WebKit).
* Modernizr for detecting browser capabilities (ie. supplying fallback effect for 3D transforms).
* Contact form uses inline validation via MooTools.
* Contact form spam detection with Akismet
-* -webkit-transitions for subtle hover state transitions
+* -webkit-transitions for subtle hover state transitions
* Sass for generating CSS (I use the sass-watch script).
* hCard microformat for contact info.
* Capistrano used for simple deployment.
@@ -23,5 +24,5 @@ A few of the things you may find nifty:
* Add HTML5 History API for portfolio navigation (see <http://html5demos.com/history>)
* Create mobile version.
-* Create larger pool of entries for Play section and pull 4 random ones.
+* Create larger pool of entries for Play section and pull 4 random ones.
* Refactor giant/fugly JS functions
View
No changes.
View
0 app/asset-types/asset.inc.php 100644 → 100755
No changes.
View
0 app/asset-types/html.inc.php 100644 → 100755
No changes.
View
0 app/asset-types/image.inc.php 100644 → 100755
No changes.
View
23 app/asset-types/page.inc.php 100644 → 100755
@@ -6,6 +6,7 @@
var $file_path;
var $template_name;
var $template_file;
+ var $template_type;
var $data;
var $all_pages;
@@ -16,6 +17,7 @@ function __construct($url) {
$this->template_name = self::template_name($this->file_path);
$this->template_file = self::template_file($this->template_name);
+ $this->template_type = self::template_type($this->template_file);
# create/set all content variables
PageData::create($this);
@@ -29,7 +31,19 @@ function __construct($url) {
}
function parse_template() {
- return TemplateParser::parse($this->data, file_get_contents($this->template_file));
+ $data = TemplateParser::parse($this->data, file_get_contents($this->template_file));
+
+ # post-parse JSON
+ if (strtolower($this->template_type) == 'json') {
+ # minfy it
+ $data = json_minify($data);
+ # strip any trailing commas
+ # (run it twice to get partial matches)
+ $data = preg_replace('/([}\]"]),([}\]])/', '$1$2', $data);
+ $data = preg_replace('/([}\]"]),([}\]])/', '$1$2', $data);
+ }
+
+ return $data;
}
# magic variable assignment
@@ -38,10 +52,15 @@ function __set($name, $value) {
$this->data[$prefix.strtolower($name)] = $value;
}
+ static function template_type($template_file) {
+ preg_match('/\.([\w\d]+?)$/', $template_file, $ext);
+ return isset($ext[1]) ? $ext[1] : false;
+ }
+
static function template_name($file_path) {
$txts = array_keys(Helpers::list_files($file_path, '/\.txt$/'));
# return first matched .txt file
- return (!empty($txts)) ? preg_replace('/\.txt$/', '', $txts[0]) : false;
+ return (!empty($txts)) ? preg_replace('/([^.]*\.)?([^.]*)\.txt$/', '\\2', $txts[0]) : false;
}
static function template_file($template_name) {
View
0 app/asset-types/video.inc.php 100644 → 100755
No changes.
View
4 app/cache.inc.php 100644 → 100755
@@ -39,7 +39,7 @@ function create($route) {
ob_start();
echo $page->parse_template();
# if cache folder is writable, write to it
- if(is_writable('./app/_cache')) $this->write_cache();
+ if(is_writable('./app/_cache') && !$page->data['@bypass_cache']) $this->write_cache();
else if ($this->is_commentable()) echo "\n".$this->comment_tags['begin'].' Stacey('.Stacey::$version.'). '.$this->comment_tags['end'];
# end buffer
ob_end_flush();
@@ -56,7 +56,7 @@ function expired() {
function get_current_hash() {
preg_match('/Stacey.*: (.+?)\s/', file_get_contents($this->cachefile), $matches);
- return $matches[1];
+ return isset($matches[1]) ? $matches[1] : false;
}
function write_cache() {
View
7 app/helpers.inc.php 100644 → 100755
@@ -53,15 +53,18 @@ static function has_children($dir) {
static function file_cache($dir = false) {
if(!self::$file_cache) {
# build file cache
- self::build_file_cache();
+ self::build_file_cache('./content');
+ self::build_file_cache('./templates');
}
if($dir && !self::$file_cache[$dir]) return array();
return $dir ? self::$file_cache[$dir] : self::$file_cache;
}
static function build_file_cache($dir = '.') {
# build file cache
- foreach(glob($dir.'/*') as $path) {
+ $files = glob($dir.'/*');
+ $files = is_array($files) ? $files : array();
+ foreach($files as $path) {
$file = basename($path);
if(substr($file, 0, 1) == "." || $file == "_cache") continue;
if(is_dir($path)) self::build_file_cache($path);
View
9 app/page-data.inc.php 100644 → 100755
@@ -107,7 +107,7 @@ static function create_vars($page) {
# @permalink
$page->permalink = Helpers::modrewrite_parse($page->url_path.'/');
# @slug
- $split_url = explode("/", $page->url_path);
+ $split_url = explode("/", $page->url_path);
$page->slug = $split_url[count($split_url) - 1];
# @page_name
$page->page_name = ucfirst(preg_replace('/[-_](.)/e', "' '.strtoupper('\\1')", $page->data['@slug']));
@@ -142,6 +142,10 @@ static function create_vars($page) {
$page->is_last = $page->data['@index'] == $page->data['@siblings_count'];
# @is_first
$page->is_first = $page->data['@index'] == 1;
+
+ # @cache_page
+ $page->bypass_cache = isset($page->data['@bypass_cache']) ? $page->data['@bypass_cache'] : false;
+
}
static function create_collections($page) {
@@ -190,6 +194,9 @@ static function create_textfile_vars($page) {
# include shared variables for each page
$shared = (file_exists('./content/_shared.txt')) ? file_get_contents('./content/_shared.txt') : '';
+ # strip any $n matches from the text, as this will mess with any preg_replaces
+ # they get put back in after the template has finished being parsed
+ $text = preg_replace('/\$(\d+)/', "\x02$1", $text);
# remove UTF-8 BOM and marker character in input, if present
$merged_text = preg_replace('/^\xEF\xBB\xBF|\x1A/', '', array($shared, $text));
@@ -0,0 +1,57 @@
+<?php
+
+/*! JSON.minify()
+ v0.1 (c) Kyle Simpson
+ MIT License
+*/
+
+function json_minify($json) {
+ $tokenizer = "/\"|(\/\*)|(\*\/)|(\/\/)|\n|\r/";
+ $in_string = false;
+ $in_multiline_comment = false;
+ $in_singleline_comment = false;
+ $tmp; $tmp2; $new_str = array(); $ns = 0; $from = 0; $lc; $rc; $lastIndex = 0;
+
+ while (preg_match($tokenizer,$json,$tmp,PREG_OFFSET_CAPTURE,$lastIndex)) {
+ $tmp = $tmp[0];
+ $lastIndex = $tmp[1] + strlen($tmp[0]);
+ $lc = substr($json,0,$lastIndex - strlen($tmp[0]));
+ $rc = substr($json,$lastIndex);
+ if (!$in_multiline_comment && !$in_singleline_comment) {
+ $tmp2 = substr($lc,$from);
+ if (!$in_string) {
+ $tmp2 = preg_replace("/(\n|\r|\s)*/","",$tmp2);
+ }
+ $new_str[] = $tmp2;
+ }
+ $from = $lastIndex;
+
+ if ($tmp[0] == "\"" && !$in_multiline_comment && !$in_singleline_comment) {
+ preg_match("/(\\\\)*$/",$lc,$tmp2);
+ if (!$in_string || !$tmp2 || (strlen($tmp2[0]) % 2) == 0) { // start of string with ", or unescaped " character found to end string
+ $in_string = !$in_string;
+ }
+ $from--; // include " character in next catch
+ $rc = substr($json,$from);
+ }
+ else if ($tmp[0] == "/*" && !$in_string && !$in_multiline_comment && !$in_singleline_comment) {
+ $in_multiline_comment = true;
+ }
+ else if ($tmp[0] == "*/" && !$in_string && $in_multiline_comment && !$in_singleline_comment) {
+ $in_multiline_comment = false;
+ }
+ else if ($tmp[0] == "//" && !$in_string && !$in_multiline_comment && !$in_singleline_comment) {
+ $in_singleline_comment = true;
+ }
+ else if (($tmp[0] == "\n" || $tmp[0] == "\r") && !$in_string && !$in_multiline_comment && $in_singleline_comment) {
+ $in_singleline_comment = false;
+ }
+ else if (!$in_multiline_comment && !$in_singleline_comment && !(preg_match("/\n|\r|\s/",$tmp[0]))) {
+ $new_str[] = $tmp[0];
+ }
+ }
+ $new_str[] = $rc;
+ return implode("",$new_str);
+}
+
+?>
@@ -1767,7 +1767,7 @@ function teardown() {
### HTML Block Parser ###
# Tags that are always treated as block tags:
- var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend';
+ var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|aside|audio|figure|footer|header|hgroup|nav|section|video';
# Tags treated as block tags only if the opening tag is alone on it's line:
var $context_block_tags_re = 'script|noscript|math|ins|del';
View
@@ -20,7 +20,14 @@ static function get_partial_template($name) {
foreach(self::$partials as $partial) {
if(preg_match('/([^\/]+?)\.[\w]+?$/', $partial, $file_name)) {
- if($file_name[1] == $name) return file_get_contents($partial);
+ //if($file_name[1] == $name) return file_get_contents($partial);
+ if($file_name[1] == $name) {
+ ob_start();
+ include $partial;
+ $ob_contents = ob_get_contents();
+ ob_end_clean();
+ return $ob_contents;
+ }
}
}
return 'Partial \''.$name.'\' not found';
@@ -80,6 +87,8 @@ static function parse($data, $template) {
# we've finished parsing, so return any remaining @ symbols
$template = str_replace("\x01", '@', $template);
+ # put back any $ characters
+ $template = str_replace("\x02", '$', $template);
return $template;
}
@@ -124,15 +133,25 @@ static function parse_foreach($data, $template) {
preg_match('/([\S\s]*?)foreach[\s]+?([\$\@].+?)\s+?do\s+?([\S\s]+?)endforeach([\S\s]*)$/', $template, $template_parts);
# run the replacements on the pre-"foreach" part of the partial
$template = self::parse($data, $template_parts[1]);
-
+ # allow loop limiting
+ if(preg_match('/\[\d*:\d*\]$/', $template_parts[2])) {
+ preg_match('/([\$\@].+?)\[(\d*):(\d*)\]$/', $template_parts[2], $matches);
+ $template_parts[2] = $matches[1];
+ $start_limit = empty($matches[2]) ? 0 : $matches[2];
+ if (!empty($matches[3])) $end_limit = $matches[3];
+ }
# traverse one level deeper into the data hierachy
$pages = (isset($data[$template_parts[2]]) && is_array($data[$template_parts[2]]) && !empty($data[$template_parts[2]])) ? $data[$template_parts[2]] : false;
+ # slice down the data array if required
+ if(is_array($pages) && isset($start_limit)) {
+ $pages = array_slice($pages, $start_limit, $end_limit);
+ }
+
# check for any nested matches
$template_parts = self::test_nested_matches($template_parts, 'foreach[\s]+?[\$\@].+?\s+?do\s+?', 'endforeach');
if($pages) {
-
foreach($pages as $data_item) {
# transform data_item into its appropriate Object
$data_object =& AssetFactory::get($data_item);
View
@@ -2,7 +2,7 @@
Class Stacey {
- static $version = '2.2.2';
+ static $version = '2.3.0';
var $route;
@@ -0,0 +1,3 @@
+title: Black Ant Media
+
+page_description: Porfolio of Jason Long
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,5 @@
+title: Git
+-
+services: Logo Design / UI Design / HTML / CSS / Javascript
+-
+description: I created an updated identity and web presence for the Git version control system. Working with a small team from GitHub, we created a new site that houses documentation, downloads, screencasts, and the entire Pro Git book. The logo and all of the other graphical assets I created are Creative Commons-licensed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,3 @@
+title: Black Ant Media
+
+page_description: Porfolio of Jason Long
View
@@ -0,0 +1,3 @@
+title: Black Ant Media
+
+page_description: Porfolio of Jason Long
Oops, something went wrong.

0 comments on commit 3b0fb9c

Please sign in to comment.