You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.1 KiB

This is a Static Site Generator.

In many cases a CMS doesn't need to generate each page again and again for each request. This is an attempt to generate Static HTML from Twig Templates.


  • git clone
  • composer install --no-dev
  • cp settings.php.dist settings.php


Edit settings.php and change BASE_PATH accordingly. Depending on your webserver, you can change REDIRECT_METHOD to one of the following:


This will change the way, the user is redirected from altSlugs (see section "Advanced page features") to the primary URL of a page. REDIRECT_METHOD_HTACCESS obviously will only work with Apache. REDIRECT_METHOD_PHP obviously will only work with a PHP-capable webserver. REDIRECT_METHOD_HTML will generate HTML files that redirect the user via <meta> tags and JS. REDIRECT_METHOD_SYMLINK will just symlink the file so basically no redirect will happen.

Depending on your webserver, you can change CONTENTTYPE_OVERRIDE_METHOD to one of the following:


This will change the way, the HTTP headers of pages are overridden. This is only required for example for RSS Feeds etc. where you want a different HTTP Header than the ones guessed by the webserver. again: HEADER_OVERRIDE_METHOD_HTACCESS obviously will only work with Apache. HEADER_OVERRIDE_METHOD_PHP obviously will only work with a PHP-capable webserver.

Set IMAGE_RESIZE_METHOD_* to define the scaling method for resizing images:

  • IMAGE_RESIZE_METHOD_NONE disables image resizing. useful if you don't want to change all templates
  • IMAGE_RESIZE_METHOD_WIDTH resizes the image to the specified width and keeps the aspect ratio
  • IMAGE_RESIZE_METHOD_HEIGHT resizes the image to the specified height and keeps the aspect ratio
  • IMAGE_RESIZE_METHOD_BEST resizes the image to best fit inside the given dimensions. (format: "$width,$height" or [$width, $height] in PHP7)

there are some more constants that can be set but usually this is not required.



run ./index.php --help for a brief list of commands:

  --run            render and switch to new version
  --no-switch      render and don't switch to new version
  --switchonly     don't render and only switch to new version (use after --no-switch)
  --rollback       switch to previous version
  --switch-to VER  switch to version VER
  --list-versions  list available versions
  --cleanup N      delete old versions but keep the latest N

./index.php --run will generate a folder structure, render all templates and place the HTML into the appropriate folder. by default the latest generated files will be accessible via the symlink versions/current. Your webserver should use that symlink as webroot.

example output (my blog now also runs this)


every time you run ./index.php --run, a new version will be created in the versions-folder. you can list them with ./index.php --list-versions to see what version is currently active.

you can switch versions with ./index.php --switch-to or ./index.php --switchonly.

You can use ./index.php --no-switch to generate the new templates but not switch them to current. Instead a symlink next will be created. use this to preview the new site for example at a different subdomain before switching it to production.

In case something goes wrong, you can use ./index.php --rollback to switch to the previous version. Note: only one rollback at a time is supported. to switch further, use ./index.php --switch-to ...

Creating pages

rendering is done by just parsing all files under templates/THEME/pages/*.twig with twig. the url is inferred from the file name of the template. templates/THEME/pages/post1.twig will be available at the URL /post1.

you can use sub-folders inside of templates/THEME/pages/ if you like. they don't change the behaviour in any way.

Advanced page features

if a ini-file with the same name as the template exists, it is read. example file:

slug = "faq"
enabled = 1

0 = "Content-Type: text/plain"

0 = "help"

headline = "FAQ & Help"
  • slug: this will be the URL
  • enabled: if not true, the page won't be rendered
  • [altSlugs]: list of alternative URLs. Users will be redirected to the primary slug
  • [variables]: those variables will be available in the template

see example templates for more details how to use twig template extension, blocks and variables to re-use templates.

special twig functions

use the special twig function getPageContent($slug, $block = 'entry') to get rendered page contents. This can be used to embed single blocks of a page somewhere else.

use the special twig function getPageMeta($path, $sort, $limit, $desc) to get a list of page metadata from their ini files. This can be used to create a listing of pages for example with title, link etc. use $path to limit the list to only those templates inside a specific template folder. use $sort to sort the pages by a specific item in their ini files. use $limit to limit the amount of pages to fetch. use $desc = false to sort them ascending instead of decending.

use the special twig function imageresize($image, $size) to get resized images. define the constants IMAGE_RESIZE_METHOD_$size and IMAGE_SIZE_$size accordingly

advanced settings

define('DIR_MODE', 0755) permissions of newly created folders. define('OUTPUT_DIR', __DIR__ . '/versions') the folder where to put the rendered pages. no trailing slash. define('BASE_PATH', 'http://localhost/') the base path used to generate absolute URLs in templates and redirects. don't forget the trailing slash. define('THEME', 'example') the name of the theme to use. define('STATIC_FOLDER', 'static') the name of the folder where static files like css are copied to.

ghost import

see import.php and modify according to your needs