Skip to content
aromanovich edited this page Feb 2, 2013 · 6 revisions

Введение

Carcade — генератор статических сайтов, написанный на Питоне.

В качестве шаблонизатора используется Jinja2 (с интегрированными webassets и i18n); данные страниц (далее — контекст страницы) задаются с помощью Markdown и YAML.

В отличии от большинства аналогичных библиотек, так или иначе ориентированных на создание блогов, Carcade предоставляет гибкий (хоть и несколько «низкоуровневый») интерфейс, позволяющий создавать сайты со сложной структурой.

Статический сайт можно рассматривать как дерево. Основная идея Carcade заключается в том, чтобы в шаблонах предоставить возможность доступа к дереву, содержащему контексты всех страниц сайта. Например, для того, чтобы отобразить главное меню на любой странице сайта, достаточно иметь список контекстов страниц первого уровня; для того, чтобы образить страницу /blog/ со ссылками на запиcи блога (/blog/<id>/), достаточно иметь список контекстов «детей» страницы /blog/, и так далее.

Определения

Дерево сайта это упорядоченное дерево, узлы которого проименованы и, за исключением корня, соответствуют страницам сайта.

Каждый узел дерева имеет ключ. Ключ это строка, которая отражает путь от корня до данного узла. Например:

.                          Ключ:
├── about                  about
└── blog                   blog
    ├── 1                  blog/1
    │   └── example        blog/1/example
    └── 2                  blog/2

Процесс построения сайта

  1. Carcade создаёт дерево сайта, в точности отражающее структуру директории pages. Каждый узел получает имя, совпадающее с названием его директории, а также контекст — словарь с данными, полученными из файлов этой директории.
    Вначале обрабатываются Markdown-файлы (<name>.md), и результат обработки попадает в контекст под ключом <name>. Далее обрабатываются YAML-файлы (<name>.yaml), содержащие словари, и данные из них записываются поверх данных, полученных из Markdown-файлов.

  2. Если задан порядок узлов, дерево сортируется. Если заданы настройки пагинации, в дерево вставляются специальные узлы, соответствующие страницам.

  3. Содержимое директории static копируется в www. Дерево обходится сверху вниз и в каждом узле происходит следующее:

    1. определяется root-relative URL, по которому должен быть доступен узел
    2. определяется шаблон, с помощью которого должен быть отображен контекст
    3. контекст узла отображается в шаблоне, результат сохраняется в www/<root-relative-URL>/index.html

Контекст шаблона всегда содержит следующие переменные:

  • NAME: имя страницы;
  • PATH: путь до узла в дереве в формате <first-lvl-name>/<second-lvl-name>/<leaf-name>. Так, например, если узел — первого уровня, PATH совпадает с NAME;
  • LANGUAGE: язык страницы;
  • CHILDREN: список контекстов детей;
  • PARENT: контекст родителя;
  • SIBLINGS: список контекстов узлов-«братьев» (узлов, имеющих того же родителя). Включает также и текущий контекст;
  • PREV_SIBLING: контекст предыдущего «брата»;
  • NEXT_SIBLING: контекст следующего «брата»;
  • ROOT: контекст корня дерева. Корень дерева не соответствует никакой странице сайта, и потому единственное непустое поле в его контексте — CHILDREN.

Пример:

Положим, исходная директория выглядит следующим образом:

.
├── layouts
│   ├── _base.html
│   └── page.html
├── pages
│   ├── four
│   │   └── content.md
│   ├── one
│   │   ├── a
│   │   │   └── content.md
│   │   ├── b
│   │   │   └── content.md
│   │   ├── c
│   │   │   └── content.md
│   │   ├── d
│   │   │   └── content.md
│   │   ├── e
│   │   │   └── content.md
│   │   ├── f
│   │   │   └── content.md
│   │   ├── g
│   │   │   └── content.md
│   │   └── content.md
│   ├── three
│   │   └── content.md
│   └── two
│       └── content.md
├── static
│   ├── css
│   │   └── reset.css
│   ├── img
│   │   └── logo.png
│   └── favicon.ico
├── translations
└── carcade_settings.py

Содержимое carcade_settings.py:

from collections import defaultdict
from webassets import Bundle

DEFAULT_PAGE = 'one'
LAYOUTS = defaultdict(lambda: 'page.html', {})
BUNDLES = {
    'css': Bundle('./css/reset.css', output='./gen/styles.css'),
}
ORDERING = {
    '*': ['one', 'two', 'three', 'four'],
    'one/*': 'alphabetically',
}
PAGINATION = {
    'one/*': 3,
}
PAGE_NAME = 'page%i'

###Шаг 1 Дерево читается из директории pages:
###Шаг 2 После чего оно сортируется:

И подвергается пагинации:
###Шаг 3 Для каждого узла определяется URL, по которому он должен быть доступен, его содержимое отображается с помощью заданного шаблона и результат записывается в соответствующую директорию.

Результат выглядит так:

www
├── css
│   └── reset.css
├── four
│   └── index.html
├── img
│   └── logo.png
├── one
│   ├── a
│   │   └── index.html
│   ├── b
│   │   └── index.html
│   ├── c
│   │   └── index.html
│   ├── d
│   │   └── index.html
│   ├── e
│   │   └── index.html
│   ├── f
│   │   └── index.html
│   ├── g
│   │   └── index.html
│   ├── page2
│   │   └── index.html
│   ├── page3
│   │   └── index.html
│   └── index.html
├── three
│   └── index.html
├── two
│   └── index.html
├── favicon.ico
└── index.html
Clone this wiki locally