- Paste is a lightweight "CMS" built around static files and folders instead of a database.
- Each HTML file represents a page in the menu, each folder represents a section, to infinite depth.
- Mustache is used for logic-less templating including partials.
- Variables and templating cascade down through the site heirarchy.
- Configuration is defined within the HTML source, like so:
<!--
@template: master
@partial: project
@title: The Page Title
@visible: TRUE // visible in menu
@label: Menu Label (optional)
-->
- simple routing with user-definable routes and closures
- Mustache for ultra dumb templating
- flexible templates and cascading page partials
- configuration via simple inline syntax
- takes some cues from Stacey App.
- use latest PHP tech, e.g. Composer
- PHP 5.3+
- Apache mod_rewrite
- Mustache.php (installed automatically by Composer)
The fastest way is to clone the demo site and modify to taste! Be sure to run composer update
to install dependencies.
Demo Site: https://github.com/paste/paste-demo
Use Composer. Add paste/paste
to your project's composer.json
:
{
"require": {
"paste/paste": "dev-master"
}
}
Create an index.php
file for the front router:
(or copy from the demo site)
<?php
// composer autoload
require 'vendor/autoload.php';
use Paste\Paste;
// configuration
$config = array(
// optionally specify a 'base_url' if serving Paste from a subdirectory, i.e. RewriteBase
// 'base_url' => '/paste-demo',
// relative path to content directory
// 'content_dir' => 'content',
// relative path to template directory
// 'template_dir' => 'templates',
// relative path to cache directory
// 'cache_dir' => 'cache',
);
// load config and parse content directory
$paste = new Paste($config);
// (optional) user defined routing
// 'route regex' => any valid callback
// matched tokens from the regex will be passed as parameters, with $paste instance first
$paste->add_route('blog/([0-9]{4})/([0-9]{2})/([0-9]{2})/([A-Za-z0-9-_]+)', function($paste, $year, $month, $day, $name) {
// ignore date and run normal content request
return $paste->render_url("blog/$name");
});
// init routing and run
$paste->run();
Create the content
, templates
, cache
directories in your web root. The cache
folder must be writeable by Apache. Your web root should end up looking something like this:
/cache/
/content/
index.html
/templates/
template.stache
/vendor/
index.php
composer.json
.htaccess
Add the root content index file, content/index.html
:
<!-- @title: Hello World -->
<!-- @template: template -->
<h3>Hello, world!</h3>
Add the first template, e.g. templates/template.stache
:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{title}}</title>
</head>
<body>
{{{content}}}
</body>
</html>
Create an .htaccess
file to enable URL rewriting:
(or copy from the demo site)
# don't list directories
Options -Indexes
# Turn on URL rewriting
RewriteEngine On
# Installation directory -- same as your 'base_url'
RewriteBase /
# Protect dot files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Protect application and system files from being viewed
RewriteRule ^(?:vendor|content|templates|cache)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
# use utf-8 encoding for anything served text/plain or text/html
AddDefaultCharset utf-8
# force utf-8 for a number of file formats
AddCharset utf-8 .html .css .js .xml .json .rss
Now visit your Paste site in a web browser and take in the magic!
allow a rewrite base that is not root, i.e. allow running Paste from a subdirectoryclasses seem arbitrary, combine Paste & Content?make it completely OO, not sure why so much static
render content with Mustache string loader to allow referencing partials and contextadd a shortcut to hide pages like _ underscore prefix in the filenamemake example site more generic, add dummy text and illustrative CSS for menu heirarchywrite new description and a quick usage guide w/ screenshotssingle template(), rest is partials()move static content stuff into Pasterefactor Page libPage Constructor -- change factory to Page::from_path()update Page->is_current() and Page->is_parentconsolidate nav stuff to next() and prev(), remove unusedchange page->parents to something like parent_pathssimplify find and find_all, etc.render menu() separately to remove invisible pagesremove section in favor of parent
use Mustache filesystem loader for partials and cachemake Menu mustache partial resursive for infinite depth -- fix CSSmore unique syntax for page/section varsproper cascading templatesredo the section control as suggested in Page->factory? noreturn Paste to all static classCombine Content into PageCombine Controller & ContentCombine Page & Template classeschange mustache templates to just .stachejust link to tumblr instead of using Tumblr blog driverconsider only loading structure on demand (e.g. menu()), and then only loading page varsdoes a file based site really need a file cache? -- use memcache if anything. benchmark cache vs. no cacheuse namespacing, make autoloader PSR-0 compatible and package it for composerPaste::route() syntax for user defined routesseparate core and a sample site for this repo, move personal portfolio stuff to separate reposimplify as much as possible. too much code for what it's supposed to be