Fork me on Bitbucket

Tacot

_images/tacot.jpg

Générer simplement des sites statiques.

But et fonctionnalités

Ce projet est né de la demande suivante sur la mailing-list Python French : « Un générateur de site statique mais plus “bas niveau” que blogofile, pelican, sphinx ? ».

Tacot permet de générer très simplement des sites statiques (génération de fichiers .html) à partir de fichiers templates écrits en Mako.

Quelle est l’utilité par rapport à l’écriture de simples fichiers .html ?

Avec Tacot vous pouvez mettre en place facilement des parties communes dans vos pages (exemples: entête, bas de page, navigation) sans avoir à dupliquer ces sections dans tous les fichiers du site.

Il existe de nombreux générateurs de site statique en Python, comme Sphinx, pelican... pourquoi réinventer la roue ?

Tacot n’est pas une réinvention de la roue… lorsque j’ai effectué ma recherche, je n’ai rien trouvé qui corresponde à mon besoin basique. Je n’ai pas besoin de parsing de ReStructredText, je ne souhaite pas gérer des billets de blog, je ne souhaite pas réaliser une documentation, je ne souhaite pas utiliser un système de thème…

Je veux simplement convertir de simples fichiers templates en html… et ça je n’ai pas trouvé.

Installation

$ pip install tacot

Exemple rapide

Téléchargez l’archive demo1.tar.gz dans un dossier demo1.

$ mkdir demos; cd demos
$ curl -o demo1.tar.gz http://packages.python.org/tacot/en/_static/demo1.tar.gz
$ tar xfz demo1.tar.gz
$ cd demo1

Voici le contenu de l’archive :

$ tree
.
├── earth.html
├── includes
│   ├── layout.html
│   └── navigation.html
├── index.html
├── jupiter.html
├── mars.html
├── mercury.html
├── neptune.html
├── pluto.html
├── saturn.html
├── styles.css
├── uranus.html
└── venus.html

Génération du site :

$ tacot
Please wait, tacot process 11 files :

jupiter.html
pluto.html
neptune.html
styles.css
index.html
saturn.html
uranus.html
earth.html
mars.html
venus.html
mercury.html

Après cela, le site généré se trouve dans le dossier _build :

$ ls _build/ -1
earth.html
index.html
jupiter.html
mars.html
mercury.html
neptune.html
pluto.html
saturn.html
styles.css
uranus.html
venus.html

Vous pouvez le consulter en faisant pointer votre navigateur web vers ce dossier :

$ firefox _build

Utilisation

$ tacot --help
tacot - a tool to generate a static web site, with Mako templates.

Usage:
    tacot [<path> --output=<output> -v -m=<manifest> --autoreload --assets=<assets>]
    tacot --version


Options:
    <path>              Path where to find the content files. By default
                        it is the current folder.
    -h, --help          Show this screen.
    --version
    -o=<output>, --output=<output>
                        Where to output the generated files. If not specified,
                        a directory will be created, named "_build" in the
                        current path (default: _build).
    -m=<manifest>, --manifest=<manifest>
                        Manifest config file (default: <path>/.manifest).
    -r, --autoreload    Relaunch tacot each time a modification occurs on the
                        content files
    --assets=<assets>   Assets config file (default: <path>/.assets.yaml).
    -v, --verbose       Enable verbose mode


Documentation : http://pythonhosted.org/tacot/

Example:

    $ tacot src -o _build -v

Par défaut, Tacot traite les fichiers du dossier courant et place de résultat dans le dossier _build du dossier courant.

Vous pouvez changer ce comportement, par exemple :

$ tacot -o /var/www/demo/ /tmp/demo1

Ici, les templates sont dans /tmp/demo1 et le site est généré dans /var/www/demo/.

Fichier .manifest

Le fichier .manifest permet de définir la liste des fichiers à traiter. Par défaut il contient la configuration suivante :

global-include *
prune _build/
prune includes/
exclude .manifest .assets.yaml .bowerrc bower.json

Les dossiers _build et includes sont ignorés.

La syntaxe du fichier .manifest est identique à celle du fichier MANIFEST.in des packages Python : documentation « The MANIFEST.in template »

Option --autoreload

L’option --autoreload permet de relancer la génération du site automatiquement à chaque fois qu’un changement a lieu dans l’arborescence des fichiers sources :

$ tacot --autoreload

CTRL-C permet d’arrêter le script.

Templates

Moteur de template

Le moteur de template utilisé est Mako.

Fichiers interprétés par le moteur de template ?

Tous les fichiers qui ont une extension .html (ou .html.mako) sont interprétés par le moteur de template.

Si vous n’utilisez aucune fonction du moteur de template dans vos fichiers .html, alors les fichiers seront simplement copiés dans le dossier destination sans aucune transformation.

Variables disponibles dans les templates

Tacot expose deux variables dans les templates, root_path et current_page :

  • root_path : est une fonction qui permet de générer une url relative vers la racine du site, en fonction de la page courante
  • current_page : permet de connaître l’url de la page courante, utile pour sélectionner des éléments dans une navigation

Exemples

Dans le fichier /saturn/index.html j’utilise la fonction root_path comme ceci :

<a href="${root_path("/")}">Accueil</a>

La fonction root_path retournera “../”.

Ceci est surtout utile dans les pages d’includes, par exemple pour une navigation :

<ul>
    <li><a href="${ root_path("/mercury.html") }">Mercury</li>
    <li><a href="${ root_path("/venus.html") }">Venus</li>
    <li><a href="${ root_path("/earth.html") }">Earth</li>
    <li><a href="${ root_path("/mars.html") }">Mars</li>
    <li><a href="${ root_path("jupiter/") }">Jupiter</li>
    <li><a href="${ root_path("saturn/") }">Saturn</li>
    <li><a href="${ root_path("/uranus.html") }">Uranus</li>
    <li><a href="${ root_path("/neptune.html") }">Neptune</li>
    <li><a href="${ root_path("/pluto.html") }">Pluto</li>
</ul>

Ici, les pages “Jupiter” et “Saturn” sont dans des sous dossiers. Toutes les pages contiennent un include de la navigation… les liens présents dans cette navigation seront tous relatifs à la page courante.

La variable current_page renvoie l’url de la page courante :

% if current_page == 'saturn/index.html':
<p>Je suis dans la page "Saturn"</p>
% endif

Variables globales

Vous pouvez définir des variables globales comme ceci (par exemple dans votre fichier layout) :

<%

g.project = u"My project"
g.author = u"Stéphane Klein"

%>

Ensuite, vous pouvez utiliser ces variables dans tous vos templates :

<h1>${g.project}</h1>

Tips

Fichier “layout” classique

Dans includes/layout.html :

<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">

    <title><%block name="title"/></title>
    <link rel="stylesheet" href="${root_path('css/styles.css')}" type="text/css" media="screen" charset="utf-8" />
</head>
<body>
    <div class="sidebar">
        <%include file="navigation.html" />
    </div><!-- sidebar -->
    <div class="content">
        ${self.body()}
    </div><!-- content -->
</body>
</html>

Fichier “navigation” classique

Dans includes/navigation.html :

<%def name="item(url, label)">
% if current_page == url:
<span>${label}</span>
% else:
<a href="${root_path(url)}">${label}</a>
% endif
</%def>
<ul>
    <li>${item("index.html", "Solar system")}</li>
    <li>${item("mercury.html", "Mercury")}</li>
    <li>${item("venus.html", "Venus")}</li>
    <li>${item("earth.html", "Earth")}</li>
    <li>${item("mars.html", "Mars")}</li>
    <li>${item("jupiter.html", "Jupiter")}</li>
    <li>${item("saturn.html", "Saturn")}</li>
    <li>${item("uranus.html", "Uranus")}</li>
    <li>${item("neptune.html", "Neptune")}</li>
    <li>${item("pluto.html", "Pluto")}</li>
</ul>

Page qui utilise le fichier “layout”

Par exemple pour index.html :

<%inherit file="includes/layout.html"/>

<%block name="title">Accueil</%block>

<h1>Accueil</h1>

<p>Foo bar…</p>

Assets

Depuis la version 0.3.0, Tacot incorpore un système de gestion des web assets (css, javascript…).

Par défaut, Tacot recherche un fichier de configuration des assets nommé .assets.yaml.

Exemple de fichier .assets.yaml :

directory: static
url: /static
debug: False
updater: timestamp
bundles:
    main_js:
        filters: jsmin
        output: build/main.js
        contents:
            - components/jquery/jquery.js
            - components/sass-bootstrap/js/bootstrap-tooltip.js
            - components/sass-bootstrap/js/bootstrap-affix.js
            - components/sass-bootstrap/js/bootstrap-alert.js
            - components/sass-bootstrap/js/bootstrap-button.js
            - components/sass-bootstrap/js/bootstrap-collapse.js
            - components/sass-bootstrap/js/bootstrap-dropdown.js
            - components/sass-bootstrap/js/bootstrap-modal.js
            - components/sass-bootstrap/js/bootstrap-popover.js
            - components/sass-bootstrap/js/bootstrap-tab.js
            - components/sass-bootstrap/js/bootstrap-typeahead.js

    main_css:
        filters:
            - scss
            - cssrewrite
        output: build/main.css
        contents:
            - components/sass-bootstrap/lib/bootstrap.scss
            - css/main.scss

Sous de capot, la gestion des assets de Tacot est basé sur webassets.

Exemple d’intégration dans un fichier layout.html :

<html>
<head>
    % for url in assets['main_css'].urls():
        <link rel="stylesheet" href="${root_path(url)}" type="text/css" media="screen" charset="utf-8" />
    % endfor
    % for url in assets['main_js'].urls():
        <script src="${root_path(url)}" type="text/javascript" charset="utf-8"></script>
    % endfor
</head>
<body>
    ${self.body()}
</body>
</html>

FAQ

Avez vous des exemples d’usage de Tacot ?

Pour le moment il n’existe aucun exemple en ligne de site réalisé avec Tacot. Par contre, je compte utiliser Tacot pour :

  • réaliser des mockup d’application ou de site web
  • réaliser de petits sites de contenu

Comment héberger / publier le site généré ?

Pour héberger un site généré par Tacot, rien de plus simple, il suffit de transférer le contenu du dossier généré (par défaut nommé _build) et de le déposer dans un dossier d’un simple serveur web.

Ici, pas de base de données, pas de langage php, python,… le serveur web doit uniquement gérer des simples fichiers statiques.

Comment ajouter le support de commentaire ?

Il est possible de mettre en place un système de commentaire en utilisant des services en ligne comme Disqus.

Comment ajouter un moteur de recherche ?

Sphinx intègre un moteur de recheche basé uniquement sur le langage Javascript coté client. Je pense qu’il doit être possible de mettre en place un système plus ou moins identique avec un site généré par Tacot.

Pour le moment je n’ai pas plus étudié le sujet.

Contributions

Vous pouvez récupérer le code source du projet via cette commande (c’est un dépôt Mercurial) :

$ hg clone http://bitbucket.org/harobed/tacot

Vous pouvez forker le projet, indiquer les problèmes, proposer des patchs via le compte Bitbucket du projet Tacot.

License

This is the MIT license: http://www.opensource.org/licenses/mit-license.php

Copyright (c) 2011-2012 Stéphane Klein.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Fork me on Bitbucket