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

Введение

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

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

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

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

Структура проекта

Каталог с Carcade-сайтом должен содержать:

  • Каталог layouts, содержащий Jinja2-шаблоны;
  • Каталог pages, содержащий каталоги (возможно, вложенные) с данными страниц — Markdown- и YAML-файлами;
  • Каталог static;
  • Файл carcade_settings.py с настройками.

Команды

  • carcade init
  • carcade build
  • carcade runserver

Определения

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

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

.                          Ключ:
├── 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 копируется в целевую директорию. Для каждой страницы в дереве:

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

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

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

Также в шаблоне доступна функция url_for(path), которая принимает ключ страницы и возвращает её root-relative URL.

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

.
├── 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 Результат выглядит так:

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

Работающие примеры можно увидеть здесь: https://github.com/aromanovich/carcade-examples

API

Формат carcade_settings.py

TODO