Poole

Create simple websites fast, now.

Poole is an easy to use Markdown driven static website generator. You write
the content of your pages in Markdown and Poole creates a nice and simple site
with a navigation menu. You don't need to learn a template or preprocessing
engine.

Though Poole is made for simple sites, it has basic support for content
generation by embedding Python code in page source files. This is a dirty merge
of content and logic but for simple sites it's a pragmatic way to get things
done fast and easy -- if you know Python you're ready to start.

Done. You've just created a website! Browse http://localhost:8080/ and watch
the example pages which have been created during initialization.

To write your own pages, use the example pages in the input folder as a
starting point.

Run poole.py --build whenever you've made some changes in the input folder.

How It Works

Poole takes files from a project's input directory and copies them to the
output directory. In this process files ending with md, mkd, mdown or
markdown get converted to HTML using the project's page.html as a skeleton.

Additionally Poole expands any macros used in a page. Don't care about that for
now ..

When running poole.py --build in a Poole project, an input directory like
this:

|- input
|- index.md
|- news.mkd
|- foo.mdown
|- images
|- bar.png

will result in an output folder like that:

|- output
|- index.html
|- news.html
|- foo.html
|- images
|- bar.png

Page Layout

Every Poole page is based on the skeleton file page.html. Hence adjusting the
site layout means adjusting page.html and extending or replacing its CCS file
input/poole.css.

The only thing you should keep in page.html are the embedded
{{__content__}} and {{__encoding__}} expressions. Below is an almost
minimal page.html file. It does not look nice but it's a clean starting point
to build your own layout from scratch.

Content Generation

Poole allows you to embed Python code in your pages to generate content:

input/some-page.md:

Here is normal text in *markdown* flavor.{%print"hello poole"%}Did you know? The sum of 2 and 2 is {{2+2}}.

This example demonstrates 2 ways to embed Python code, either as statements or
as expressions:

Everything between {% and %} are statements and whatever is printed
to stdout during their execution is going to be part of the final HTML
page.

Everything between {{ and }} are expressions and their evaluation is
going to be part of the final page.

TIP: Instead of the outer curly brackets { and } you can also use
<!-- and --> to prevent syntax highlighting markdown editors from getting
confused by the Python code.

TIP: To print the code surrounding tags literally, simply escape the
opening tag with a backslash.

Outsource complex or frequently used code

To keep embedded code short and compact or to reuse it in several pages, it can
be outsourced into a file called macros.py in a project's root folder (where
the page.html file is located). Every public attribute in macros.py is
available within embedded Python code blocks:

Working with pages

Next to stuff defined in macros.py the objects page and pages are
available in embedded Python code. The first one is a dictionary describing the
page in which the code is embedded. The second one is a list of all pages in
the project.

The following attributes are always set in a page dictionary:

title: The page's title, by default its filename without extension
(setting alternatives is described in the next section).

That way you can also set a page's title explicitly, instead of using the file
name. Other useful attributes to set are description and keywords, which
get used by the default page.html file to set HTML meta tags. Here it comes
in handy to set default page attributes in the macros.py file:

macros.py:

page = { "description": "some stuff", "keywords": "stuff" }

That way you can safely use the description and keywords attributes without
bothering if they are really defined in every page.

Accessing page objects in the macros module

The objects pages and page are also available within macros.py. That
means you can define them as dummys and reference them in macros.py. Poole
updates them when loading the macros module.

Options and paths

Similarly to page and pages the following objects are available within
embedded Python code and within the macros module:

options: The command line arguments given to Poole as parsed by
Python's optparse module. For instance the base URL can be
retrieved by options.base_url.

project: Path to the project's root directory.

input: Path to the project's input directory.

output: Path to the project's output directory.

Character encodings

In case you use non-ASCII characters, check the encoding options of Poole. In
most cases working with non-ASCII strings should work straight forward if the
options are set properly (default is UTF-8).

However, be aware that page variables defined within page source files and
derived from a page's file name internally are handled as Python unicode
objects. That means if you want to refer to non-ASCII page variable names and
values form within embedded Python code or from macros.py, make sure to use
unicode strings to reference them.

Howtos

Navigation menu

Have a look into the page.html file in a freshly initialized Poole project.

List of blog posts

If you want to write some blog posts, you probably would like to have a page
listing all or the latest blog posts. This is easy if you set certain page
attributes in every blog post page:

TIP: Instead of setting the post title and date as page attributes, you can
encode them in the page's file name using a structure like
page-title.YYYY-MM-DD.post-title.md. For instance for the file name
blog.2010-03-01.This_is_your_brain_on_mongs.md Poole would automatically set
the page attributes which has been set manually in the example above.

To see this example in action, have a look into the example pages in a freshly
initialized Poole project.

Google sitemap file

To generate a Google sitemap.xml file, put this into the project's macros.py
file:

You probably want to adjust the default values for changefreq and priority.

Info: Every function in macros.py whose name starts with
hook_preconvert_ or hook_postconvert_ is executed exactly once per project
build -- either before or after converting pages from markdown to HTML. In
post-convert hooks the HTML content of a page (yet without header and footer)
can be accessed with page.html. This is useful to generate full-content RSS
feeds.

RSS feed for blog posts

To generate an RSS feed for blog posts put this into the project's macros.py
file and adjust for your site: