-
Notifications
You must be signed in to change notification settings - Fork 2
Home
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
-
Carcade создаёт дерево сайта, в точности отражающее структуру директории
pages
. Каждый узел получает имя, совпадающее с названием его директории, а также контекст — словарь с данными, полученными из файлов этой директории.
Вначале обрабатываются Markdown-файлы (<name>.md
), и результат обработки попадает в контекст под ключом<name>
. Далее обрабатываются YAML-файлы (<name>.yaml
), содержащие словари, и данные из них записываются поверх данных, полученных из Markdown-файлов. -
Если задан порядок узлов, дерево сортируется. Если заданы настройки пагинации, в дерево вставляются специальные узлы, соответствующие страницам.
-
Содержимое директории
static
копируется вwww
. Дерево обходится сверху вниз и в каждом узле происходит следующее:- определяется root-relative URL, по которому должен быть доступен узел
- определяется шаблон, с помощью которого должен быть отображен контекст
- контекст узла отображается в шаблоне, результат сохраняется в
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