From ba7875f1dc89e3544cb812547f11e0df40fc98e7 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Fri, 2 Apr 2010 10:40:13 -0400 Subject: [PATCH] more work, about to mess w/ blueprint --- Rakefile | 16 +++++- config/trivial.inc | 3 + content/dynamic.inc | 1 + lib/trivial.php | 124 ++++++++++++++++++++++++++++++++++------- readme.md | 5 ++ styles/application.css | 7 --- views/application.inc | 1 + 7 files changed, 130 insertions(+), 27 deletions(-) create mode 100644 config/trivial.inc create mode 100644 content/dynamic.inc diff --git a/Rakefile b/Rakefile index 93ed09f..1bcf635 100644 --- a/Rakefile +++ b/Rakefile @@ -1,8 +1,9 @@ require 'rubygems' require 'rake' require 'echoe' +require 'fileutils' -Echoe.new('trivial', '0.0.5') do |p| +Echoe.new('trivial', '0.0.6') do |p| p.summary = "Ultra-lightweight website framework for PHP" p.description = <<-EOT For those who are using PHP to build their sites and want a very simple framework @@ -16,3 +17,16 @@ Echoe.new('trivial', '0.0.5') do |p| p.email = "john@coswelproductions.com" p.url = "http://github.com/johnbintz/trivial" end + +namespace :blueprint do + desc "Include the latest Blueprint CSS files" + task :download do + FileUtils.rm_r 'blueprint' if File.directory? 'blueprint' + FileUtils.mkdir 'blueprint' + Dir.chdir 'blueprint' + system 'git clone git://github.com/joshuaclayton/blueprint-css.git' + FileUtils.cp_r File.join('blueprint-css', 'blueprint'), File.join('..', 'styles') + Dir.chdir '..' + FileUtils.rm_r 'blueprint' + end +end diff --git a/config/trivial.inc b/config/trivial.inc new file mode 100644 index 0000000..b07fec3 --- /dev/null +++ b/config/trivial.inc @@ -0,0 +1,3 @@ + diff --git a/lib/trivial.php b/lib/trivial.php index ba7ecf2..6e63e1f 100644 --- a/lib/trivial.php +++ b/lib/trivial.php @@ -1,15 +1,39 @@ array(), 'styles' => array()); + +// If the environment is anything but production, errors will be rendered in the page. +$trivial_env = 'development'; + +if (($config = fe_check('config/trivial.inc')) !== false) { + include($config); +} + +$trim = str_replace(realpath($_SERVER['DOCUMENT_ROOT']), '', realpath($root_dir)); + +$requested = preg_replace('#/$#', '/index.html', $_SERVER['REDIRECT_URL']); +$requested = preg_replace("#${trim}/(.*)\.[^\.]+\$#", '\1', $requested); + +/** + * Check the root path for the requested file. + * @param string $path The path to look for. + * @return string The path to the file on the filesystem, or false if not found. + */ function fe_check($path) { global $root_dir; if (file_exists($full_path = ($root_dir . '/' . $path))) { @@ -19,6 +43,13 @@ function fe_check($path) { } } +/** + * Load a partial file. + * Partials live in the views directory and are prefixed with an underscore (ex: section/_a_partial.inc). + * @param string $name The name of the partial without the leading underscore (ex: section/a_partial). + * @param array $local A hash of variables to include into the local scope of the partial. + * @return string The partial's result. + */ function partial($name, $local = array()) { $name = preg_replace('#/([^/]+)$', '/_\1', $name); if (($path = fe_check('views/' . $name . '.inc')) !== false) { @@ -27,30 +58,62 @@ function partial($name, $local = array()) { include($path); return ob_get_clean(); } else { - trigger_error("No partial named ${name} found!"); + render_error("No partial named ${name} found!"); } } -$root_dir = realpath(dirname(__FILE__) . '/../'); - -$trim = str_replace(realpath($_SERVER['DOCUMENT_ROOT']), '', realpath($root_dir)); - -$requested = preg_replace('#/$#', '/index.html', $_SERVER['REDIRECT_URL']); -$requested = preg_replace("#${trim}/(.*)\.[^\.]+\$#", '\1', $requested); +/** + * Handle a rendering error. + * If the environment is 'production', the error is only logged. If it's anything else, it's printed + * on the screen. Regardless, an HTTP 500 error is returned and processing stops. + * @param string $error The error message to display. + */ +function render_error($error) { + global $trivial_env; + if ($trivial_env == 'production') { + error_log($error); + } else { + echo "
${error}
"; + } + header('HTTP/1.1 500 Internal Server Error'); + exit(1); +} +/** + * Render style link tags. + */ function styles() { - return head_component(func_get_args(), 'styles/%s.css', ''); + return head_component('styles', func_get_args(), 'styles/%s.css', ''); } +/** + * Render script tags. + */ function scripts() { - return head_component(func_get_args(), 'scripts/%s.js', ''); + return head_component('scripts', func_get_args(), 'scripts/%s.js', ''); } -function head_component($additional, $search, $format) { - global $requested; +/** + * Render head compoments. + * @param string $what The type of component to render. $global_head is searched for a matching key and values for that key are merged into the list of styles. + * @param array $additional An array of additional components to display. + * @param string $search The search pattern to use for each component, run through sprintf() with the first %s being replaced with the component name. + * @param string $format The output format of the HTML tag to bring in the content. + * @return string The HTML for all found components. + */ +function head_component($what, $additional, $search, $format) { + global $requested, $global_head; $output = array(); - foreach (array_merge(array('application', $requested), $additional) as $file) { + + $components = array_merge(array('application', $requested), $additional); + if (is_array($global_head[$what])) { + $components = array_merge($components, $global_head[$what]); + } + + sort($components); + + foreach ($components as $file) { if (fe_check(sprintf($search, $file)) !== false) { $output[] = sprintf($format, $file); } @@ -58,31 +121,54 @@ function head_component($additional, $search, $format) { return implode("\n", $output); } -$content = null; -if (($content_file = fe_check('content/' . $requested . '.html')) !== false) { - $content = file_get_contents($content_file); +/** + * Get the code to embed the Blueprint CSS framework. + * You should be starting with Blueprint and working your way from there, if only for the CSS reset & IE fixes alone. + * @return string The HTML for Blueprint. + */ +function blueprint() { + } +// Search for files in the content directory, starting with .inc files (which will be include()d), then .html files (which will be file_get_content()sed) +$content = null; +if (($content_file = fe_check('content/' . $requested . '.inc')) !== false) { + ob_start(); + include($content_file); + $content = ob_get_clean(); +} else { + if (($content_file = fe_check('content/' . $requested . '.html')) !== false) { + $content = file_get_contents($content_file); + } +} + +// Look for an action for the request. If it's found, execute it. Remember, $content contains the result of the above operation, if something was found. foreach (array('application', $requested) as $action) { if (($action_file = fe_check('actions/' . $action . '.inc')) !== false) { include($action_file); } } +// Look for a view with the same name as the request. If it's found, include() it, wrapping the include() in an output buffer block. if (($view_file = fe_check('views/' . $requested . '.inc')) !== false) { ob_start(); include($view_file); $content = ob_get_clean(); } +// We should have content by this point. If not, raise an error. if (is_null($content)) { - trigger_error("No content generated for ${requested}! Did you create a content, action, or view file for this request?"); + render_error("No content generated for ${requested}! Did you create a content, action, or view file for this request?"); } +// We should have a layout, too. If not, raise an error. if (($layout_file = fe_check('views/' . $layout . '.inc')) !== false) { ob_start(); include($layout_file); $content = ob_get_clean(); +} else { + render_error("Layout not found: ${layout}"); } +// We're done! echo $content; diff --git a/readme.md b/readme.md index c8e5238..b8cd95c 100644 --- a/readme.md +++ b/readme.md @@ -35,3 +35,8 @@ does the following (for the examples, the request was for `about_us/contact.html ## Styles and scripts Styles and scripts can be searched for in a structured way. The included `views/application.inc` gives an example as to how this works. + +## Notes + +Trivial includes the reset.css and typography.css files from the [Blueprint CSS Framework](http://blueprintcss.org/). +They're automatically included in the default application.css file. diff --git a/styles/application.css b/styles/application.css index 9da9c19..e69de29 100644 --- a/styles/application.css +++ b/styles/application.css @@ -1,7 +0,0 @@ -* { - font-family: helvetica, arial -} - -body { - background-color: #eee -} diff --git a/views/application.inc b/views/application.inc index afe6e79..4393f7c 100644 --- a/views/application.inc +++ b/views/application.inc @@ -1,6 +1,7 @@ My Application +