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
+