Tiny is a system for maintaining HTML documents with a common structure. Tiny takes a template containing shared markup and placeholders, and merges it with source files to produce finished documents, typically static web pages.

Tiny is named after Tiny Clanger from the British stop-motion animation.

Download (version 1.0)

Page shortcuts

When to use Tiny

A typical website contains a number of pages with different content but the same header, navigation menu and footer. In the simplest case, when creating the pages you will copy the HTML for these common elements and paste it manually into each. The problem is that the elements often change over time, for example when a new page is added to the navigation menu. As the site grows, updating the common elements across all its pages becomes more time-consuming and potentially more error-prone.

A common solution is to use a content management system (CMS) like Wordpress, but this carries its own drawbacks: First, it requires a server that supports a scripting language like PHP or Perl. Second, the CMS will likely need regular maintenance to keep it secure. Finally, you can’t test the site offline on your computer without running a local copy of the server software.

A different approach is the templating capabilities of Dreamweaver, which works locally on your computer and so avoids the server-related drawbacks just mentioned. Unfortunately, you need unsightly template markup in the code, which remains in the live version of the site. And of course you need a Dreamweaver license.

Tiny is another templating system that runs locally on your computer. Designed with simplicity and elegance in mind, it has a strictly limited feature set: it assumes that the variable elements of a page are limited to its title, meta description, links to stylesheets and scripts, and one contiguous block of content. Tiny stands alone from your chosen HTML editor, instead being a command-line application that processes ‘source files’ and templates to produce the finished documents (which contain no evidence that Tiny compiled them).

If you manage a static – or mostly static – website in which numerous pages share common markup either side of their content, you might want to give Tiny a try.

Running Tiny

Tiny is a command line PHP script and requires PHP 5.4 or higher. This means that recent versions of OS X and many Linux distributions can run it without further software or configuration. Windows users may refer to the PHP documentation.

Usage: tiny.php -s source_directory -o output_directory

Newly-outputted files will overwrite existing files in the output directory with the same names.

Line endings in outputted files will be those native to the platform (Windows or Unix-like) on which Tiny is run, regardless of the kind of line endings in the source files.

Lookup file

A file named "lookup.txt" may exist in the source directory. The lookup file associates a friendly name with the URI of each script and stylesheet that source files may use; source files then refer to these resources via their friendly names. Scripts and stylesheets are declared like in these examples:

script slideshow: js/slideshow.js
script jQuery: //code.jquery.com/jquery-1.11.3.min.js
stylesheet mobile: /css/mobile.css
stylesheet Noto Serif: https://fonts.googleapis.com/css?family=Noto+Serif

Each declaration must be on its own line beginning script or stylesheet followed by a space, then the friendly name, then a colon and finally the URI.

Note: Friendly names can include spaces. In fact, any character except the comma, colon and square brackets is allowed. Names are case-sensitive.

If a stylesheet needs a media attribute it is declared like this:

stylesheet desktop [(min-width: 360px)]: /css/desktop.css

The value for the media attribute must be in square brackets after the friendly name. It cannot itself include square brackets. In this example the parentheses are part of the media query itself.

Note: Tiny does not actually understand or attempt to validate URIs or media attribute values; it merely copies them as-is into output files.

Source files

Source files must be named with a double extension where the first part is "tiny", e.g. family.tiny.html. Tiny will attempt to process all files in the source directory that are named this way.

Note: Tiny does not look inside subdirectories. If you want to process files in subdirectories, you will have to run Tiny separately on each subdirectory.


There are two parts to a source file: the directives and the content. For example:

template: main.template.html
title: Family
description: Meet each of the Clangers.
scripts: jQuery, slideshow
stylesheets: Noto Serif, mobile, desktop

<img src="images/mother.jpg" alt="Mother clanger dispensing soup">
<p>Five members of the Clanger family are featured...

The template directive tells Tiny which template file to merge this source file with. This must be a filename only, not a full path (there is no need for a path as templates must be in the same directory as the source files).

The remaining directives title, description, scripts and stylesheets tell Tiny how to fill in the correspondingly-named placeholders in that template. Each directive must be on its own line that begins with its name followed by a colon and then its value. The scripts and stylesheets directives each accept a comma-separated list as their value. There must be no empty lines between directives.

After the directives, an empty line indicates the start of the content (HTML). Everything from this point onwards is copied as-is into the {{content}} placeholder in the template.


Templates should be in the same directory as the source files. By convention a template’s filename should have a double extension where the first part is "template", e.g. main.template.html. Tiny will merge each source file with the template whose filename is given in its template directive.


A typical template might look like this. Placeholders are in double braces:

<!DOCTYPE html>
<html lang="en-GB">
<meta charset="utf-8">
<ul id="menu">
  <a href="/">Home</a>
  <a href="family.html">Family</a>
<div id="footer">All rights reserved.</div>

Templates may contain the following placeholders. Each is optional, and must appear no more than once:

Tiny fills these placeholders from source files as follows:


The value of the title directive is copied into an HTML title element:



The value of the description directive is copied into the content attribute of an HTML meta description tag:

<meta name="description" content="Meet each of the Clangers.">


Each friendly name in the scripts directive is resolved to a URI via the lookup file, and this URI copied into the src attribute of an HTML script element:

<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="js/slideshow.js"></script>

The order in which the scripts are named in the directive is preserved.


Each friendly name in the stylesheets directive is resolved to a URI via the lookup file, and this URI copied into the href attribute of an HTML link element whose rel attribute is set to "stylesheet":

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Serif">
<link rel="stylesheet" href="/css/mobile.css">

If a stylesheet declaration in the lookup file specifies a value for the media attribute (in square brackets after its friendly name) it is included as you would expect:

<link rel="stylesheet" media="(min-width: 360px)" href="/css/desktop.css">

The order in which the stylesheets are named in the directive is preserved.


The content from the source file is inserted as-is.


Any feedback on Tiny is welcome. Please find contact details on my home page.