changeset 249:f1e8ed3ea141

Merge code changes.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 19 Feb 2015 23:35:31 -0800
parents afc1d2c60854 (diff) 3f740928043a (current diff)
children f250e3c486e4
files
diffstat 56 files changed, 1131 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Feb 19 23:34:53 2015 -0800
+++ b/.hgignore	Thu Feb 19 23:35:31 2015 -0800
@@ -6,6 +6,10 @@
 build/messages/_cache
 build/messages/_counter
 dist
+docs/_cache
+docs/_counter
+docs/bower_components
+docs/node_modules
 piecrust.egg-info
 piecrust/__version__.py
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/assets/css/piecrust.less	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,285 @@
+// Imports
+// Core variables and mixins
+@import "../../bower_components/bootstrap/less/variables.less";
+@import "../../bower_components/bootstrap/less/mixins.less";
+
+// Reset and dependencies
+@import "../../bower_components/bootstrap/less/normalize.less";
+@import "../../bower_components/bootstrap/less/print.less";
+@import "../../bower_components/bootstrap/less/glyphicons.less";
+
+// Core CSS
+@import "../../bower_components/bootstrap/less/scaffolding.less";
+@import "../../bower_components/bootstrap/less/type.less";
+@import "../../bower_components/bootstrap/less/code.less";
+@import "../../bower_components/bootstrap/less/grid.less";
+@import "../../bower_components/bootstrap/less/forms.less";
+@import "../../bower_components/bootstrap/less/buttons.less";
+
+// Components
+@import "../../bower_components/bootstrap/less/component-animations.less";
+@import "../../bower_components/bootstrap/less/navs.less";
+@import "../../bower_components/bootstrap/less/navbar.less";
+
+// Utility classes
+@import "../../bower_components/bootstrap/less/utilities.less";
+@import "../../bower_components/bootstrap/less/responsive-utilities.less";
+
+
+// Variables
+@font-size-base:          17px;
+@font-family-base:        @font-family-serif;
+
+
+// Dividers
+.pc-divider-img(@offset-x, @offset-y) {
+    .hidden-xs();
+    content: " ";
+    background-image: url("/img/dividers.png");
+    background-repeat: no-repeat;
+    background-position: -@offset-x -@offset-y;
+    display: inline-block;
+    width: 100px;
+    height: 50px;
+}
+.pc-divider(@offset) {
+    &::before {
+        .pc-divider-img(0, @offset);
+        margin-right: 0.5em;
+    }
+    &::after {
+        .pc-divider-img(100px, @offset);
+        margin-left: 0.5em;
+    }
+}
+
+.pc-divider1() {
+    .pc-divider(0);
+}
+
+.pc-divider1-white() {
+    .pc-divider(50px);
+}
+
+.pc-divider2() {
+    .pc-divider(100px);
+}
+
+.pc-divider3() {
+    .pc-divider(150px);
+}
+
+
+// Icons
+@pc-icon-width: 128px;
+
+
+// Decorators
+.pc-decorator(@img-name, @margin-left) {
+    margin-left: @pc-icon-width;
+    &::before {
+        content: " ";
+        background-image: url(@img-name);
+        background-repeat: no-repeat;
+        display: block;
+        float: left;
+        width: 128px;
+        height: 92px;
+        margin-left: -(@pc-icon-width + @margin-left);
+    }
+}
+
+.pc-banner(@img-name) {
+    background-image: url(@img-name);
+    background-repeat: no-repeat;
+    background-position: center center;
+    background-size: cover;
+}
+
+.pc-banner-header(@img-name) {
+    .pc-banner(@img-name);
+    padding: 3em 0;
+    margin-bottom: 3em;
+    text-align: center;
+    color: black;
+}
+
+// Customizations
+.navbar {
+    margin-bottom: 0;
+}
+a.navbar-brand {
+    font-family: Lobster, serif;
+}
+
+h1 {
+    font-family: Lobster, serif;
+    font-size: 2em;
+    margin-top: 0;
+    margin-bottom: 0.375em;
+    text-shadow: #fff 0 0 1em, #fff 0 0 0.1em;
+}
+h1.site-title {
+    font-size: 5em;
+    text-align: center;
+}
+@media (min-width: @screen-sm-min) {
+    h1 {
+        font-size: 3em;
+    }
+}
+@media (min-width: @screen-md-min) {
+    h1 {
+        font-size: 4em;
+    }
+}
+
+h2 {
+    font-family: Lobster, serif;
+    font-size: 2.2em;
+}
+
+blockquote {
+    font-size: @font-size-base;
+    border-left: 5px solid @brand-info;
+}
+@media (min-width: @screen-sm-min) {
+    blockquote {
+        .pc-decorator('/img/cake.png', 5px + @line-height-computed);
+    }
+}
+
+header.page-title h1 {
+    .pc-divider(150px);
+    text-align: center;
+    margin: 0.5em auto 1em;
+}
+
+footer {
+    .container;
+    font-size: 0.8em;
+    text-align: center;
+    margin: 2em;
+}
+
+
+// Splash-page
+header.splash {
+    .pc-banner("/img/header2-bg.jpg");
+    color: black;
+}
+.splash {
+    h1 {
+        .text-hide();
+    }
+
+    h2 {
+        .pc-divider2();
+        margin: 1em 0;
+        text-align: center;
+    }
+
+    .splash-logo {
+        background-image: url('/img/logo.png');
+        background-repeat: no-repeat;
+        background-position: center center;
+        background-size: contain;
+        height: 275px;
+    }
+    @media (min-width: @screen-sm-min) {
+        .splash-logo {
+            height: 325px;
+        }
+    }
+    @media (min-width: @screen-md-min) {
+        .splash-logo {
+            height: 375px;
+        }
+    }
+
+    .splash-main {
+        font-size: 1.1em;
+        margin: 1em 0.5em 0 0.5em;
+        padding-bottom: 2em;
+
+        p {
+            margin: 0;
+            text-shadow: #fff 0 0 1em, #fff 0 0 0.1em;
+        }
+    }
+    @media (min-width: @screen-sm-min) {
+        .splash-main {
+            font-size: 1.3em;
+            margin: 1em 2em 0 2em;
+        }
+    }
+    @media (min-width: @screen-md-min) {
+        .splash-main {
+            font-size: 1.5em;
+            width: 50%;
+            margin: 1em auto 0 auto;
+        }
+    }
+
+    .splash-icon {
+        display: block;
+        margin: 0 auto;
+    }
+}
+.splash.splash-chalkboard {
+    background: url("/img/chalkboard-bg.jpg");
+    color: white;
+    padding: 0.25em 0 3em 0;
+    margin: 0;
+
+    h2 {
+        .pc-divider1-white();
+    }
+}
+
+
+// Getting-Started
+header.tutorial {
+    .pc-banner-header("/img/header5-bg.jpg");
+}
+
+
+// Documentation
+header.documentation {
+    .pc-banner-header("/img/header10-bg.jpg");
+}
+
+.pc-docnav() {
+    list-style-type: none;
+    padding: 0;
+}
+
+ul.doc-level1 {
+    .pc-docnav();
+
+    &>li {
+        margin-bottom: 1em;
+    }
+    &>li>a {
+        font-size: 1.1em;
+        font-weight: bold;
+    }
+}
+
+ul.doc-level2 {
+    .pc-docnav();
+}
+
+
+// Code
+header.code {
+    .pc-banner-header("/img/header7-bg.jpg");
+}
+
+
+// Support
+header.support {
+    .pc-banner-header("/img/header9-bg.jpg");
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/assets/humans.txt	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,14 @@
+# humanstxt.org/
+# The humans responsible & technology colophon
+
+# AUTHORS
+
+Ludovic Chabant -- @ludovicchabant
+
+# TECHNOLOGY
+
+PieCrust -- http://bolt80.com/piecrust
+
+# THANKS
+
+
Binary file docs/assets/img/cake-white.png has changed
Binary file docs/assets/img/cake.png has changed
Binary file docs/assets/img/chalkboard-bg.jpg has changed
Binary file docs/assets/img/chef-hat-white.png has changed
Binary file docs/assets/img/chef-hat.png has changed
Binary file docs/assets/img/dividers.png has changed
Binary file docs/assets/img/header1-bg.jpg has changed
Binary file docs/assets/img/header10-bg.jpg has changed
Binary file docs/assets/img/header2-bg.jpg has changed
Binary file docs/assets/img/header3-bg.jpg has changed
Binary file docs/assets/img/header4-bg.jpg has changed
Binary file docs/assets/img/header5-bg.jpg has changed
Binary file docs/assets/img/header6-bg.jpg has changed
Binary file docs/assets/img/header7-bg.jpg has changed
Binary file docs/assets/img/header8-bg.jpg has changed
Binary file docs/assets/img/header9-bg.jpg has changed
Binary file docs/assets/img/logo.png has changed
Binary file docs/assets/img/roller-white.png has changed
Binary file docs/assets/img/roller.png has changed
Binary file docs/assets/img/stripes_bg.png has changed
Binary file docs/assets/img/whisk-white.png has changed
Binary file docs/assets/img/whisk.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/assets/js/piecrust.js.concat	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,7 @@
+path_mode: absolute
+files:
+  - bower_components/jquery/dist/jquery.js
+  - bower_components/bootstrap/js/transition.js
+  - bower_components/bootstrap/js/collapse.js
+  - bower_components/bootstrap/js/scrollspy.js
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/assets/robots.txt	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,6 @@
+# www.robotstxt.org/
+
+# Allow crawling of all content
+User-agent: *
+Disallow:
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/config.yml	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,51 @@
+# Basic stuff.
+site:
+    title: PieCrust
+    author: Ludovic Chabant
+    tagline: Freshly baked sites & documents since 2006
+    description: A static website generator and flat-file CMS
+    pretty_urls: true
+    sources:
+        docs:
+            type: ordered
+            data_endpoint: site.docs
+            default_layout: doc
+    routes:
+        -
+            url: /docs/%path:slug%
+            source: docs
+            func: docurl(slug)
+
+baker:
+    assets_dirs:
+        assets:
+            # Ignore stuff that will get concatenated into the main JS file.
+            ignore: js/piecrust
+
+smartypants:
+    enable: true
+
+# This is 2015, come on Markdown.
+markdown:
+    extensions: abbr, fenced_code, footnotes, smart_strong
+
+# Need Foundation for CSS/JS. Install with Bower.
+sass:
+    load_paths:
+        - bower_components/foundation/scss
+
+# Using the Sass compiler directly now, but here's how it would look
+# like if we were using the whole Compass machinery instead.
+compass:
+    enable: false
+    options: --css-dir %out_dir%/css --generated-images-path %out_dir%/img
+
+# Config variants.
+variants:
+    # Enable compressors when baking the docs for publishing.
+    dist:
+        baker:
+            assets_dirs:
+                assets:
+                    processors: all
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/00__index.md	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,27 @@
+---
+title: Documentation
+layout: doc
+---
+
+Using PieCrust is mostly a matter of editing text files and, sometimes, running
+commands in a terminal. Make sure you go through the [Getting Started][1] page,
+if only to install PieCrust on your system.
+
+ [1]: {{pcurl('getting-started')}}
+
+
+Here are some common pages most people will want to read:
+
+
+### Creating websites
+
+* You can follow the [tutorial][2] for creating a simple blog website.
+* The are pages explaining how a [website is organized on disk][3], and how to
+  [configure it][4].
+
+
+ [2]: {{docurl('tutorial/your-first-blog')}}
+ [3]: {{docurl('general/creating-websites')}}
+ [4]: {{docurl('general/website-config')}}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/01_tutorial.md	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,12 @@
+---
+title: Tutorial
+---
+
+This PieCrust tutorial will walk you through the process of creating a new
+website, writing content for it, customizing its appearance, and publishing it
+somewhere.
+
+{% for part in family.children %}
+* [{{part.title}}]({{part.url}})
+{% endfor %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/01_tutorial/01_your-first-blog.md	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,215 @@
+---
+title: "Part 1: Your First Blog"
+---
+
+This tutorial walks you through the creation of your first PieCrust website: a
+simple blog.
+
+> Whenever you see something like this:
+>
+>     $ chef blah --something
+>
+> It means you need to run that command (starting with `chef`) in a terminal or
+> command prompt. Text that doesn't start with the dollar sign is the expected
+> output of the command.
+
+We'll assume you already have installed PieCrust on your system. If not, the
+installation steps are documented in the ["Getting Started"][1] page.
+
+Let's also verify you have an up-to-date version of PieCrust.
+
+    $ chef --version
+    {{piecrust.version}}
+
+If your version is older, you'll want to update PieCrust:
+
+    $ pip install piecrust -U
+
+If your version is newer, you're probably looking at old docs! You should be
+able to find newer docs at the [official PieCrust website][2].
+
+
+## Create the website
+
+Creating the website can be done with a simple command:
+
+    $ chef init myblog
+
+This will create a directory called `myblog` in the current directory, and
+initialize a PieCrust website in it. If you go inside and look at the contents,
+however, you'll be surprised to find that there's not much:
+
+    $ cd mblog
+    $ ls
+    config.yml
+
+There's just a `config.yml` file! But that's the file that differentiates a
+random directory with a PieCrust website. PieCrust expects a file named like
+that at the root of a website.
+
+> Because PieCrust websites are all files (mostly text), they fit really nicely
+> in a source control repository. This makes it so much easier to backup and
+> rollback than with a website running on an SQL database, like Wordpress.
+>
+> It's recommended that you create such a repository right now. If you want to
+> use Git, you would type:
+>
+>     $ git init .
+>     $ git add .
+>     $ git commit -m "Initial empty blog."
+>
+> If you want to use Mercurial, you would type the same commands, but replace
+> `git` with `hg`. For other source control systems, please check the
+> documentation.
+>
+> And of course don't forget to commit your changes as you go!
+
+
+## Preview the website
+
+At this point, you only have an empty website, but we can still preview it in
+the browser! Type:
+
+    $ chef serve
+    * Running on http://localhost:8080/
+
+It should tell you it's started a web server at the address
+`http://localhost:8080`. If you type that in your browser's address bar, you
+should see PieCrust's welcome and boilerplate page.
+
+You may notice that the `serve` command is still running. That's because the
+server is still running, which is what you want. You can stop the server by
+hitting `CTRL+C` at any time, but that means the preview won't work anymore. And
+because we still have some work to do, obviously, you'll want to open a new
+terminal or command prompt in order to type new commands.
+
+Now let's add some stuff!
+
+
+## Add some posts
+
+To add posts, you just have to create a text file in the correct place with the
+correct name. By default, PieCrust expects posts in the `posts/` directory,
+with a name like so: `YYYY-MM-DD_title-of-the-post.md`.
+
+If you're like me, you probably don't know what today's date is, however. And
+there's also the risk of a typo... so let's instead use the `prepare` command:
+
+    $ chef prepare post my-first-post
+    Creating page: posts/2015-02-19_my-first-post.md
+
+There, it tells you the path of the file it created. Open that file now in your
+favorite text editor. You should see something like this:
+
+    ---
+    title: My First Post
+    time: '08:21:49'
+    ---
+    
+    This is a brand new page.
+
+Refresh your browser, and you should see that post instead of the welcome page.
+Edit the post's text (under the second `---` line), and refresh your browser.
+
+Now let's add another post. Run the `prepare` command again:
+
+    $ chef prepare post my-second-post
+    Creating page: posts/2015-02-19_my-second-post.md
+
+Refresh your browser, and you can see how your blog's homepage is starting to
+shape up as expected, with a reverse-chronological list of your posts. That's
+because the default *theme* for new PieCrust websites defines a page template
+for the home page that does exactly that. This can totally be overriden, of
+course, but it works well as an out-of-the-box experience.
+
+If you want to change the title of a post, you can edit the `title:` part in the
+posts' configuration header (which is what we call that part between the 2 `---`
+lines). However, the URL of the post will still have `my-first-post` or
+`my-second-post` in it. If you want to change that, you'd have to rename the
+file itself.
+
+> The configuration header is written in [YAML][]. It's usually fairly
+> straightforward, but the first hurdle you may run into is if you want to set a
+> title to something with characters like `'` or `:` in them. In this case,
+> you'll have to add double-quotes (`"`) around the whole thing.
+>
+> If you're using a decent text editor with syntax highlighting, it should know
+> about the YAML syntax and tell you that something's wrong.
+
+Similarly, if you want to change the date of a post, you'd have to rename the
+file. The time of the post is in the configuration header, though, so you can
+tweak that in the text file.
+
+To know more about the different settings you can change in a page's
+configuration header, check out the [page configuration reference][pageconfref].
+
+
+## Configuring the website
+
+This is all fine and dandy, but the big title at the top of the home page still
+says "_My New Website_", and that's not very personal. Let's configure that.
+
+Open the `config.yml` file. It's also written in [YAML][], like the posts'
+configuration headers. You can change the `site/title` setting easily:
+
+    site:
+        title: "Ludovic's Blog"
+
+> Note how, for the rest of this tutorial (and the rest of the documentation!)
+> we'll refer to nested configuration settings using *slash* separators. So the
+> `site/title` setting refers to the `title` setting inside the `site` setting,
+> as shown in the snippet above.
+
+Refresh your browser, and lo and behold, the new title should be there.
+
+There are plenty of other things you can configure in the `config.yml` file. For
+example, say you don't like the default URL format for posts. That can be
+adjusted with the `site/post_url` setting. By default, it is:
+
+    site:
+        post_url: "%year%/%month%/%day%/%slug%
+
+The post URL format is defined using some keywords surrounded by percent signs,
+as you can see above. The `%year%`, `%month%` and `%day%` keywords should be
+self-explanatory -- and they map directly to the post's filename, which, if you
+remember, contains the post's date.
+
+The `%slug%` keyword maps to the post's "*slug*", which is the [part of the URL
+that has human-readable words][slug]. In PieCrust's case, it comes from the
+part of the filename that comes after the date ("*my-first-post* and
+*my-second-post* in this tutorial).
+
+If, say, your blog has a low chance of slug collision, or has a low post
+frequency, and you want to have more minimal URLs, you can change it to:
+
+    site:
+        post_url: "%year%/%slug%"
+
+Refresh your browser, and you should see that the posts' URLs are now conforming
+to the new format.
+
+> If your browser was currently displaying a post at the old URL, you will
+> suddenly get a "_page not found_" error! That's OK, it's because the post is
+> now at the new, shorter URL. Just go back to the root URL, `localhost:8080`.
+
+See the [site configuration reference][siteconfref] for more information about
+all the settings you can change.
+
+
+## Next steps
+
+At this point you have a moderately function blog, but it's far from looking
+good yet. In the [second part of this tutorial][part2] we'll look at customizing
+your website's appearance by editing layouts and templates, and writing CSS
+stylesheets and using PieCrust's built-in asset pipeline.
+
+
+
+[1]: {{pcurl('getting-started')}}
+[2]: {{piecrust.url}}
+[yaml]: https://en.wikipedia.org/wiki/YAML
+[slug]: http://en.wikipedia.org/wiki/Semantic_URL#Slug
+[pageconfref]: {{pcurl('docs/reference/page-config')}}
+[siteconfref]: {{pcurl('docs/reference/site-config')}}
+[part2]: {{pcurl('docs/tutorial/making-things-pretty')}}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/pages/_index.md	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,109 @@
+---
+title: PieCrust
+layout: splash
+---
+
+---slogan---
+
+Baking fresh websites & documents since 2006
+
+
+---main---
+
+**PieCrust** is a static website generator and flat-file CMS. No complex setup,
+databases, or administrative panels -- it's all text files. Simple, beautiful,
+and yummy.
+
+*[CMS]: Content Management System
+
+
+---simple---
+
+### Store in the cellar
+
+Because all your site's content and configuration is stored in simple text
+files, it fits nicely in a revision control system like Git or Mercurial. It's
+not only more practical, but also safer!
+
+
+---bake---
+
+### Serve on the counter
+
+Although it can run a flat-file CMS, **PieCrust** is designed as a static
+website generator. This means it can "bake" your website into simple HTML files
+that you can publish with a minimum of resources on your server. A sudden spike
+of visitors can't crash your MySQL database when you don't need one!
+
+
+---ingr---
+
+### Familiar ingredients
+
+**PieCrust** uses all the ingredients you already like, such as Markdown and
+Textile for formatting, or Jinja2 and Mustache for templating.
+
+
+---oven---
+
+### Fully functioning oven
+
+**PieCrust** comes out-of-the-box with an asset processing pipeline, capable of
+handling most of your files -- Less/Sass processing, CSS and JS
+minification, concatenation, and more.
+
+
+---cooks---
+
+### Several cooks in the kitchen
+
+If you're dealing with advanced scenarios, **PieCrust** will gladly interoperate
+with other tools like Grunt, Compass, Bower, and many more.
+
+
+---fast---
+
+### Super-fast service
+
+Because **PieCrust** is also designed as a lightweight (flat-file) CMS, it can
+render your pages in less than a few milliseconds in most cases. It means that
+previewing or generating your website is super fast!
+
+
+---carte---
+
+### A La Carte Content
+
+**PieCrust** comes with a powerful system of page sources, routes, and taxonomies.
+This means you can completely customize how you want to author your content, and
+how it gets exposed.
+
+
+---entrees---
+
+### Multiple entrées
+
+Your pages are not limited to one piece of content that you place in the center
+of your layout. You can define other “text segments” like a page-specific menu
+or sidebar text that you can insert in different places in the layout.
+
+
+---startnow---
+
+## Get Started Now
+
+You can follow the detailed instructions on the [Getting Started][1]
+page, or, if you're already experienced in the culinary arts:
+
+    virtualenv pcenv
+    <activate pcenv>
+    pip install piecrust
+    chef init mynewwebsite
+    cd mynewwebsite
+    chef prepare post my-first-post
+    chef serve
+    chef bake
+
+
+ [1]: {{pcurl('getting-started')}}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/pages/code.md	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,5 @@
+---
+title: Code
+header_class: code
+---
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/pages/getting-started.md	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,167 @@
+---
+title: Getting Started
+header_class: tutorial
+---
+
+This quick tutorial will show you how to create a simple blog with PieCrust.
+
+> If you're already an experienced cook, here's the rundown:
+>
+>     virtualenv pcenv
+>     <activate pcenv>
+>     pip install piecrust
+>     chef init mywebsite
+>     cd mywebsite
+>     chef prepare post my-first-post
+>     chef serve
+>     chef bake
+
+
+## Installation
+
+The first step is obviously to get PieCrust installed on your machine.
+
+You'll need Python 3.4 at least for this. Note that it can live side by side
+with Python 2.x. On Windows or MacOSX, you can use the [official Python
+installer][1]. On main Linux distros, you can use your system's package manager
+to install it. If you're on a more obscure system, or if you want to use
+alternative means like Homebrew or something, you probably don't need help for
+this!
+
+Now we can start running in a command line. On MacOSX, that's the Terminal app,
+and on Windows that's the Command Prompt.
+
+
+### Global installation
+
+Python 3 comes with a [package manager][2] called `pip`, with which you can install,
+update, and uninstall Python programs like PieCrust. Just run:
+
+    pip install piecrust
+
+This will install PieCrust globally on your system. You may want to install it
+using a *virtual environment* instead, though. See the next section for that.
+
+> #### Permission Errors
+>
+> If you get some permission errors, you may have to run that command as an
+> administrator. That would be `sudo pip install piecrust` on MacOSX and Linux, or
+> running the Command Prompt as an Administrator on Windows.
+
+You should now have PieCrust installed! You can check that it works by typing:
+
+    chef --version
+
+If everything's fine it should print `{{piecrust.version}}` (the latest
+version as of this writing).
+
+
+### Using virtual environements
+
+Although very straightforward, the previous section installs PieCrust globally
+on your system. This may be OK, but could also cause problems if you have other
+Python software that share dependencies with PieCrust, but with different
+versions.  And then there's the issue of installing PieCrust in environments in
+which you don't have administrator access.
+
+Thankfully, `pip` supports a whole variety of scenarios, and [another
+utility][3], called `virtualenv` enables even more of them.
+
+* If you don't have it yet, install `virtualenv` with `pip install
+  virtualenv`, or check with your administrators to have it. Most web hosts
+  provide it.
+* Run `virtualenv pcenv`. This will create a directory called `pcenv` that
+  contains a whole new Python environment, separate from your system's Python
+  environment.
+* Activate that environment with `sh pcenv/bin/activate.sh` (on Linux or
+  MacOSX) or `pcenv\Scripts\activate` (on Windows). The new environment will
+  now be active for as long as your current command prompt is active.
+* Now install PieCrust with `pip install piecrust`. This will install it in
+  that environment, leaving your system's Python clean of any of PieCrust's
+  dependencies.
+
+
+## Create an empty website
+
+The `chef` command is the main PieCrust utility. You can read about it on the
+[command-line overview][cmdline] page. The first thing to do is to ask it to
+create a basic website structure:
+
+    chef init mywebsite
+
+This should create a directory called `mywebsite`. There should be a
+`config.yml` file in there. Get into that directory:
+
+    cd mywebsite
+
+Once you're inside a website's root directory, the `chef` command will be able
+to do a lot of different things.
+
+
+## Create new content
+
+Let's start by creating a new page:
+
+    chef prepare page about-me
+
+It will tell you that it just created a file named `pages/about-me.md`. Go ahead
+and edit that in your favorite text editor, and write some text, or change the
+title that was defined for you in the header part. For more information on
+writing content, see the documentation about [creating pages][cnt].
+
+Now let's write a blog post:
+
+    chef prepare post my-new-blog
+
+It will again tell you about the file it just created. This time it's in the
+`posts` folder, and has a name that follows some date/title kind of naming
+convention. You don't have to use `chef prepare` to create content for your
+website, but for things like blog posts it's a lot easier to let it insert
+today's date in the filename.
+
+
+## Preview content
+
+Time to preview what we just did! Simply type:
+
+    chef serve
+
+Open your favorite web browser and navigate to the URL that `chef` is listening
+on, which by default is `localhost:8080`. You should see some placeholder text
+along with today's blog post that you just created, with a simple barebones theme.
+
+> #### Alternate port
+>
+> If you already have some other things running on port 8080, you can tell
+> PieCrust to use a different one with the `-p` option.
+
+The `about-me` page isn't shown because you're looking at the index page, but
+you would see it if you navigated to `localhost:8080/about-me`.
+
+
+## Bake and publish
+
+Now it's time to bake this new site and publish it somewhere. There are many
+ways to do that, as shown in the documentation about [baking][bake], but here's
+a quick way. Run:
+
+    chef bake
+
+This will bake the website into static files, stored under the `_counter`
+directory. At this point, you can upload all the contents of that directory to
+your web server. When that's done, you should be able to see the exact same
+website being served from there.
+
+
+That's it! This is an extremely quick tour of PieCrust. Read the
+[documentation][doc] to learn more.
+
+
+[1]: https://www.python.org/downloads/
+[2]: https://pip.pypa.io/en/latest/
+[3]: https://virtualenv.pypa.io/en/latest/
+[doc]: {{pcurl('docs')}}
+[cmdline]: {{pcurl('docs/general/command-line-overview')}}
+[cnt]: {{pcurl('docs/content/creating-pages')}}
+[bake]: {{pcurl('docs/publish')}}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/pages/support.md	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,6 @@
+---
+title: Support
+header_class: support
+---
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/raw/attribution.md	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,38 @@
+
+# Photos
+
+* [Pie crust][img1] by [Robert Couse Baker][1]
+* [Home made apple pie][img2] by [Robert S. Donovan][2]
+* [Thanksgiving prep begins][img3] by [Dennis Wilkinson][3]
+* [Summer peach cake][img4] by [William Andrus][4]
+* [Of love and cooking dough][img5] by [Sarah R][5]
+* [Rollin'][img6]
+* [Cherry pie][img7] by [Ginny][7]
+* [Apple pie][img8]
+
+
+  [img1]: https://www.flickr.com/photos/29233640@N07/6063510527
+  [1]: https://www.flickr.com/photos/29233640@N07/
+
+  [img2]: https://www.flickr.com/photos/booleansplit/3036470963
+  [2]: https://www.flickr.com/photos/booleansplit/
+
+  [img3]: https://www.flickr.com/photos/djwtwo/8206822777
+  [3]: https://www.flickr.com/photos/djwtwo/
+
+  [img4]: https://www.flickr.com/photos/wandrus/6118430479
+  [4]: https://www.flickr.com/photos/wandrus
+
+  [img5]: https://www.flickr.com/photos/reid-bee/4847750025
+  [5]: https://www.flickr.com/photos/reid-bee
+
+  [img6]: https://www.flickr.com/photos/reid-bee/4847750797/in/photostream/
+
+  [img7]: https://www.flickr.com/photos/ginnerobot/3684979334
+
+  [img8]: https://www.flickr.com/photos/djwtwo/15581303453
+
+  [img9]: https://www.flickr.com/photos/clemsherpa/15757740526
+
+  [img10]: https://www.flickr.com/photos/benimoto/2109973292
+
Binary file docs/raw/cake.pxm has changed
Binary file docs/raw/chef-hat.pxm has changed
Binary file docs/raw/dividers.pxm has changed
Binary file docs/raw/header1-bg.pxm has changed
Binary file docs/raw/header10-bg.pxm has changed
Binary file docs/raw/header2-bg.pxm has changed
Binary file docs/raw/header3-bg.pxm has changed
Binary file docs/raw/header4-bg.pxm has changed
Binary file docs/raw/header5-bg.pxm has changed
Binary file docs/raw/header6-bg.pxm has changed
Binary file docs/raw/header7-bg.pxm has changed
Binary file docs/raw/header8-bg.pxm has changed
Binary file docs/raw/header9-bg.pxm has changed
Binary file docs/raw/logo.pxm has changed
Binary file docs/raw/tools.pxm has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/templates/default.html	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,61 @@
+{% import "google.html" as google %}
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <meta name="author" content="Ludovic Chabant">
+    <meta name="generator" content="PieCrust {{ piecrust.version }}" />
+    <meta name="description" content="PieCrust, a simple website engine and static website generator" />
+
+    <title>{% if page.title %}{{ page.title }} &mdash; {% endif %}PieCrust</title>
+    {{ google.webfonts('Lobster') }}
+    <link rel="stylesheet" href="{{ site.root }}css/piecrust.css" type="text/css" />
+    <!--[if lt IE 9]>
+    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
+    <![endif]-->
+</head>
+<body data-spy="scroll">
+    <div id="wrapper">
+        <nav class="navbar navbar-default" role="navigation">
+            <div class="container">
+                <div class="navbar-header">
+                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#piecrust-menu">
+                        <span class="sr-only">Toggle navigation</span>
+                        <span class="icon-bar"></span>
+                        <span class="icon-bar"></span>
+                        <span class="icon-bar"></span>
+                    </button>
+                    <a class="navbar-brand" href="{{site.root}}">PieCrust</a>
+                </div>
+                <div class="collapse navbar-collapse" id="piecrust-menu">
+                    <ul class="nav navbar-nav navbar-right">
+                        <li><a href="{{ pcurl('getting-started') }}">Getting Started</a></li>
+                        <li><a href="{{ pcurl('docs') }}">Documentation</a></li>
+                        <li><a href="{{ pcurl('code') }}">Code</a></li>
+                        <li><a href="{{ pcurl('support') }}">Support</a></li>
+                    </ul>
+                </div>
+            </div>
+        </nav>
+        {% block header %}
+        <header{% if page.header_class %} class="{{page.header_class}}"{% endif %}>
+            <h1>{{ page.title }}</h1>
+        </header>
+        {% endblock %}
+        {% block content %}
+        <section class="container" id="content">
+        {{ content|raw }}
+        </section>
+        {% endblock %}
+        <footer>
+            <p>&copy;2014 &mdash; {{ piecrust.branding|raw }}</p>
+        </footer>
+    </div>
+    {{ piecrust.debug_info|raw }}
+    <script src="{{ site.root }}js/piecrust.js"></script>
+    {% if baker.is_baking %}
+    {{ google.analytics("UA-3426592-10") }}
+    {% endif %}
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/templates/doc.html	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,33 @@
+{% extends "default.html" %}
+
+{% block header %}
+<header class="documentation">
+    <h1>{{ page.title }}</h1>
+</header>
+{% endblock %}
+
+{% block content %}
+<div class="container">
+    <section class="col-md-8">
+    {{ content|raw }}
+    </section>
+    <aside class="col-md-4">
+        <ul class="doc-level1">
+        {% for p in family.root %}
+        {% if p.is_dir and p.is_page %}
+            <li><a href="{{p.url}}">{{p.title}}</a>
+                <ul class="doc-level2">
+                {% for p2 in p.children %}
+                    <li><a href="{{p2.url}}">{{p2.title}}</a></li>
+                {% endfor %}
+                </ul>
+            </li>
+        {% elif not p.is_dir and p.order %}
+            <li><a href="{{p.url}}">{{p.title}}</a></li>
+        {% endif %}
+        {% endfor %}
+        </ul>
+    </aside>
+</div>
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/templates/google.html	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,32 @@
+{% macro webfonts(fontnames) %}
+<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family={{ fontnames }}">
+{% endmacro %}
+
+{% macro analytics(siteId) %}
+<script type="text/javascript">
+
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', '{{ siteId }}']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+
+</script>
+{% endmacro %}
+
+{% macro adsense(client, name, slot, width, height) %}
+  <script type="text/javascript"><!--
+      google_ad_client = "{{ client }}";
+      /* {{ name }} */
+      google_ad_slot = "{{ slot }}";
+      google_ad_width = {{ width }};
+      google_ad_height = {{ height }};
+      //-->
+  </script>
+  <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+  </script>
+{% endmacro %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/templates/splash.html	Thu Feb 19 23:35:31 2015 -0800
@@ -0,0 +1,56 @@
+{% extends "default.html" %}
+
+{% block header %}
+<header class="splash">
+    <h1>PieCurst</h1>
+    <div class="splash-logo">
+    </div>
+    <div class="splash-main">
+        {{main|safe}}
+    </div>
+</header>
+{% endblock %}
+
+{% block content %}
+<section class="splash splash-chalkboard">
+    <div class="container">
+        <h2>Chef's Features</h2>
+        <div class="row">
+            <div class="col-sm-6 col-md-4">
+                <img class="splash-icon" src="/img/cake-white.png" />
+                {{simple|safe}}
+            </div>
+            <div class="col-sm-6 col-md-4">
+                <img class="splash-icon hidden-xs" src="/img/chef-hat-white.png" />
+                {{bake|safe}}
+            </div>
+            <div class="clearfix visible-sm-block"></div>
+            <div class="col-sm-6 col-md-4">
+                <img class="splash-icon hidden-sm" src="/img/whisk-white.png" />
+                {{ingr|safe}}
+            </div>
+            <div class="clearfix visible-md-block visible-lg-block"></div>
+            <div class="col-sm-6 col-md-4">
+                {{oven|safe}}
+            </div>
+            <div class="clearfix visible-sm-block"></div>
+            <div class="col-sm-6 col-md-4">
+                <img class="splash-icon visible-xs" src="/img/chef-hat-white.png" />
+                {{fast|safe}}
+            </div>
+            <div class="col-sm-6 col-md-4">
+                {{carte|safe}}
+            </div>
+        </div>
+    </div>
+</section>
+<section class="splash splash-board">
+    <div class="container">
+        <div class="row">
+            <div class="col-xs-12 col-md-8 col-md-offset-2">
+                {{startnow|safe}}
+            </div>
+        </div>
+    </div>
+</section>
+{% endblock %}
--- a/piecrust/sources/posts.py	Thu Feb 19 23:34:53 2015 -0800
+++ b/piecrust/sources/posts.py	Thu Feb 19 23:35:31 2015 -0800
@@ -53,9 +53,9 @@
                 ext = self.default_auto_format
 
         replacements = {
-                'year': '%04d' % year,
-                'month': '%02d' % month,
-                'day': '%02d' % day,
+                'year': '%04d' % year if year is not None else None,
+                'month': '%02d' % month if month is not None else None,
+                'day': '%02d' % day if day is not None else None,
                 'slug': slug,
                 'ext': ext
                 }