Дата: 2025-11-10
Версия: 1.0.0
Цель: Концепции из Drupal, WordPress, Django и других продвинутых систем
1. VIEWS (Представления) - создание списков без кода
2. TAXONOMIES (Таксономии) - классификация контента
3. MENUS (Меню) - навигация
4. BLOCKS/REGIONS (Блоки) - области контента
5. CONTENT TYPES (Типы контента) - шаблоны сущностей
6. MEDIA LIBRARY (Медиатека) - управление файлами
7. REVISIONS (Ревизии) - версионирование
8. COMMENTS (Комментарии) - обсуждения
9. SEARCH & FACETS (Поиск) - полнотекстовый поиск
10. ALIASES/SLUGS (ЧПУ) - красивые URL
11. REDIRECTS (Перенаправления) - 301/302
12. SEO METADATA (SEO) - мета-теги
13. CACHE STRATEGIES (Кэширование) - производительность
14. QUEUES (Очереди) - фоновые задачи
15. ACTIVITY LOG (Журнал) - история действий
Views - самая мощная фича Drupal. Позволяет создавать списки/отчёты/галереи БЕЗ кода через UI.
View = Query Builder + Display + Filters + Sorting + Formatting
# views/recent_deals.view.cifra
view:
id: recent_deals
name: "Недавние сделки"
description: "Список сделок за последние 30 дней"
# БАЗА ДАННЫХ (что показываем)
base_entity: Deal
# FIELDS (какие поля показываем)
fields:
- field: title
label: "Название сделки"
sortable: true
searchable: true
- field: amount
label: "Сумма"
sortable: true
format: currency
- field: contact.full_name
label: "Контакт"
relationship: contact
link: true
link_path: /contacts/{contact.id}
- field: stage
label: "Этап"
format: badge
badge_colors:
lead: gray
proposal: blue
won: green
lost: red
- field: created_at
label: "Создана"
sortable: true
format: date_ago # "3 дня назад"
# FILTERS (фильтры)
filters:
# Exposed фильтры (видны пользователю)
- field: stage
type: select
label: "Этап"
options: auto # Берём из enum
exposed: true
multiple: true
- field: assigned_to
type: entity_reference
label: "Менеджер"
entity: User
exposed: true
- field: created_at
type: date_range
label: "Дата создания"
exposed: true
# Скрытые фильтры (применяются всегда)
- field: deleted_at
operator: is_null
exposed: false
# SORT (сортировка по умолчанию)
sorts:
- field: created_at
direction: DESC
# RELATIONSHIPS (связи с другими entity)
relationships:
- id: contact
entity: Contact
field: contact_id
required: false # LEFT JOIN
- id: company
entity: Company
through: contact # Через contact
field: company_id
# PAGINATION
pagination:
type: pager
items_per_page: 50
expose_items_per_page: true
options: [25, 50, 100]
# DISPLAYS (как отображаем)
displays:
# Отображение как таблица
- id: table
type: table
enabled: true
path: /admin/deals
menu:
type: normal
title: "Сделки"
parent: admin
# Отображение как REST API
- id: rest_export
type: rest_export
enabled: true
path: /api/views/recent-deals
format: json
authentication: jwt
# Отображение как RSS
- id: feed
type: feed
enabled: true
path: /deals/feed.xml
format: rss
title_field: title
description_field: description
# Отображение как блок (можно встраивать)
- id: block
type: block
enabled: true
items_to_display: 5
use_more_link: true
more_link_path: /admin/deals
# CONTEXTUAL FILTERS (фильтры из URL)
contextual_filters:
- field: assigned_to
default_value: current_user
when_empty: show_all
# AGGREGATION (агрегация)
aggregation:
enabled: true
group_by: [stage]
aggregates:
- field: amount
function: sum
label: "Общая сумма"
# ACCESS (права доступа)
access:
permission: view_deals
role: [sales_manager, sales_rep]
# CACHING (кэширование)
cache:
type: time
duration: 300 # 5 минут
# views/deals_with_tasks.view.cifra
view:
id: deals_with_tasks
name: "Сделки с задачами"
base_entity: Deal
# Связь с задачами
relationships:
- id: tasks
entity: Task
field: deal_id
type: reverse # Обратная связь (Task → Deal)
required: false
fields:
- field: title
label: "Сделка"
- field: tasks.title
label: "Задача"
relationship: tasks
- field: tasks.status
label: "Статус задачи"
relationship: tasks
# Показать только сделки, у которых есть открытые задачи
filters:
- field: tasks.status
relationship: tasks
operator: in
value: [open, in_progress]
# Группировка по сделкам
aggregation:
enabled: true
group_by: [id, title]
aggregates:
- field: tasks.id
function: count
label: "Количество задач"
Taxonomy - система классификации контента. Позволяет организовывать контент по категориям, тегам и т.д.
Vocabulary (Словарь)
└─ Terms (Термины)
└─ Child Terms (Дочерние термины)
# taxonomies/taxonomies.cifra
taxonomies:
# Таксономия 1: Категории продуктов (иерархическая)
- id: product_categories
name: "Категории продуктов"
type: hierarchical # Может иметь вложенность
description: "Классификация продуктов по категориям"
# Настройки
settings:
multiple: false # Продукт может быть только в одной категории
required: true # Обязательно выбрать категорию
max_depth: 3 # Максимум 3 уровня вложенности
# Поля термина (дополнительные данные)
term_fields:
- icon:
type: image
label: "Иконка категории"
- description:
type: text
label: "Описание"
- featured:
type: boolean
label: "Показывать на главной"
default: false
- seo_title:
type: string
label: "SEO заголовок"
- seo_description:
type: text
label: "SEO описание"
# Предустановленные термины
terms:
- id: electronics
name: "Электроника"
weight: 0
children:
- id: computers
name: "Компьютеры"
children:
- id: laptops
name: "Ноутбуки"
- id: desktops
name: "Настольные ПК"
- id: phones
name: "Телефоны"
children:
- id: smartphones
name: "Смартфоны"
- id: feature_phones
name: "Кнопочные телефоны"
- id: clothing
name: "Одежда"
weight: 1
children:
- id: mens
name: "Мужская"
- id: womens
name: "Женская"
- id: kids
name: "Детская"
# Таксономия 2: Теги (плоская структура)
- id: tags
name: "Теги"
type: flat # Без иерархии
description: "Ключевые слова для контента"
settings:
multiple: true # Можно выбрать много тегов
required: false
allow_create: true # Пользователь может создавать новые теги
term_fields:
- color:
type: color
label: "Цвет тега"
default: "#3B82F6"
# Таксономия 3: Статусы (custom taxonomy)
- id: deal_statuses
name: "Статусы сделок"
type: flat
settings:
multiple: false
required: true
allow_create: false # Только предустановленные
term_fields:
- color:
type: color
label: "Цвет"
- icon:
type: string
label: "Иконка"
- weight:
type: integer
label: "Порядок"
default: 0
terms:
- {id: lead, name: "Лид", color: "#gray", icon: "user-plus", weight: 0}
- {id: qualification, name: "Квалификация", color: "#blue", weight: 1}
- {id: proposal, name: "Предложение", color: "#yellow", weight: 2}
- {id: negotiation, name: "Переговоры", color: "#orange", weight: 3}
- {id: won, name: "Выиграна", color: "#green", icon: "check", weight: 4}
- {id: lost, name: "Проиграна", color: "#red", icon: "x", weight: 5}
# Привязка таксономий к entities
entities:
Product:
fields:
# Связь с иерархической таксономией
category:
type: taxonomy_term
vocabulary: product_categories
required: true
# Связь с тегами (множественная)
tags:
type: taxonomy_term
vocabulary: tags
multiple: true
widget: autocomplete
BlogPost:
fields:
categories:
type: taxonomy_term
vocabulary: blog_categories
multiple: true
widget: checkboxes
tags:
type: taxonomy_term
vocabulary: tags
multiple: true
widget: tags_input # Инпут с тегами
Deal:
fields:
status:
type: taxonomy_term
vocabulary: deal_statuses
widget: select
# Views с таксономией
views:
- id: products_by_category
base_entity: Product
# Контекстный фильтр по категории
contextual_filters:
- field: category
type: taxonomy_term
validate: true
breadcrumb: true # Показывать в хлебных крошках
# Группировка по категории
aggregation:
enabled: true
group_by: [category.name]
# Python API
from cifra import taxonomy
# Получить термины таксономии
categories = taxonomy.get_vocabulary('product_categories')
# Создать новый термин
new_category = taxonomy.create_term(
vocabulary='product_categories',
name='Аксессуары',
parent='electronics'
)
# Получить все термины с детьми (дерево)
tree = taxonomy.get_tree('product_categories')
# Привязать термин к entity
product.category = taxonomy.get_term('laptops')
product.save()
# Получить все продукты в категории (включая подкатегории)
products = Product.query.filter(
category=taxonomy.get_term_with_children('electronics')
)
# Получить breadcrumbs (хлебные крошки)
breadcrumbs = taxonomy.get_breadcrumbs('laptops')
# → [Электроника, Компьютеры, Ноутбуки]
# menus/site_menus.cifra
menus:
# Главное меню
- id: main_menu
name: "Главное меню"
description: "Основная навигация сайта"
items:
- id: home
title: "Главная"
url: /
weight: 0
icon: home
- id: catalog
title: "Каталог"
url: /catalog
weight: 1
icon: shopping-bag
children:
- id: electronics
title: "Электроника"
url: /catalog/electronics
weight: 0
- id: clothing
title: "Одежда"
url: /catalog/clothing
weight: 1
- id: about
title: "О компании"
url: /about
weight: 2
- id: contacts
title: "Контакты"
url: /contacts
weight: 3
# Настройки отображения
settings:
max_depth: 2
expanded: true # Раскрыть все подменю
show_icons: true
# Меню в футере
- id: footer_menu
name: "Меню в подвале"
items:
- {title: "Политика конфиденциальности", url: /privacy}
- {title: "Условия использования", url: /terms}
- {title: "Помощь", url: /help}
# Административное меню
- id: admin_menu
name: "Административное меню"
access: [admin, manager]
items:
- title: "Панель управления"
url: /admin
icon: dashboard
- title: "Контент"
url: /admin/content
icon: file-text
children:
- {title: "Контакты", url: /admin/contacts}
- {title: "Сделки", url: /admin/deals}
- {title: "Продукты", url: /admin/products}
- title: "Настройки"
url: /admin/settings
icon: settings
# Динамическое меню (генерируется из таксономии)
menus:
- id: categories_menu
name: "Меню категорий"
type: dynamic
source: taxonomy
vocabulary: product_categories
max_depth: 2
url_pattern: /catalog/{term.slug}
# blocks/site_blocks.cifra
blocks:
# Блок с недавними статьями
- id: recent_articles
name: "Недавние статьи"
type: view
view: recent_blog_posts
display: block
settings:
title: "Последние новости"
items_to_display: 5
cache: 300 # 5 минут
visibility:
pages:
include: ["/", "/blog", "/blog/*"]
exclude: ["/blog/archive"]
roles: ["*"] # Все роли
# Блок с HTML контентом
- id: promo_banner
name: "Промо-баннер"
type: html
content: |
<div class="promo-banner">
<h2>Скидка 20% на всё!</h2>
<p>До конца месяца</p>
<a href="/sale" class="btn">Купить</a>
</div>
visibility:
pages:
include: ["/"]
date_range:
start: "2025-11-01"
end: "2025-11-30"
# Блок с формой поиска
- id: search_form
name: "Форма поиска"
type: form
form: search_form
# Блок с меню
- id: main_nav
name: "Главная навигация"
type: menu
menu: main_menu
# Регионы (области на странице)
regions:
- id: header
name: "Шапка"
blocks: [main_nav, search_form]
- id: sidebar_left
name: "Левая колонка"
blocks: [categories_menu, recent_articles]
- id: content
name: "Основной контент"
# Сюда идёт основной контент страницы
- id: sidebar_right
name: "Правая колонка"
blocks: [promo_banner]
- id: footer
name: "Подвал"
blocks: [footer_menu, contacts_block]
# Layout (раскладка страницы)
layouts:
- id: two_column
name: "Две колонки"
template: |
<div class="layout-two-column">
<header>{{ region('header') }}</header>
<div class="main-wrapper">
<aside class="sidebar-left">{{ region('sidebar_left') }}</aside>
<main>{{ region('content') }}</main>
</div>
<footer>{{ region('footer') }}</footer>
</div>
- id: three_column
name: "Три колонки"
template: |
<div class="layout-three-column">
<header>{{ region('header') }}</header>
<div class="main-wrapper">
<aside class="sidebar-left">{{ region('sidebar_left') }}</aside>
<main>{{ region('content') }}</main>
<aside class="sidebar-right">{{ region('sidebar_right') }}</aside>
</div>
<footer>{{ region('footer') }}</footer>
</div>
# content_types/content_types.cifra
content_types:
# Тип контента: Статья блога
- id: blog_post
name: "Статья блога"
entity: Node # Базовая entity
description: "Статья для блога компании"
# Поля этого типа контента
fields:
- title:
type: string
label: "Заголовок"
required: true
max_length: 255
- body:
type: rich_text
label: "Содержание"
required: true
- summary:
type: text
label: "Анонс"
max_length: 500
- featured_image:
type: image
label: "Изображение"
allowed_formats: [jpg, png, webp]
max_size: 2MB
- category:
type: taxonomy_term
vocabulary: blog_categories
label: "Категория"
required: true
- tags:
type: taxonomy_term
vocabulary: tags
label: "Теги"
multiple: true
- author:
type: entity_reference
entity: User
label: "Автор"
default: current_user
- published_at:
type: datetime
label: "Дата публикации"
default: now
- seo_title:
type: string
label: "SEO заголовок"
max_length: 70
- seo_description:
type: text
label: "SEO описание"
max_length: 160
# Настройки отображения
display:
full:
# Полное отображение статьи
template: blog_post_full
fields:
- featured_image: {format: large}
- title: {format: h1}
- author: {format: link}
- published_at: {format: "d F Y"}
- body: {format: html}
- tags: {format: links}
teaser:
# Анонс статьи (для списков)
template: blog_post_teaser
fields:
- featured_image: {format: medium, link: true}
- title: {format: h3, link: true}
- summary: {format: plain}
- read_more: {label: "Читать далее", link: true}
# URL pattern
url_pattern: /blog/{year}/{month}/{slug}
# Комментарии
comments:
enabled: true
moderation: true
threading: true
max_depth: 3
# Workflow (статусы публикации)
workflow:
states: [draft, review, published, archived]
default_state: draft
# Права доступа
permissions:
create: [editor, admin]
edit_own: [author, editor, admin]
edit_any: [admin]
delete_own: [author, editor, admin]
delete_any: [admin]
# Тип контента: Продукт
- id: product
name: "Продукт"
entity: Node
fields:
- name: {type: string, required: true}
- sku: {type: string, unique: true, required: true}
- description: {type: rich_text}
- price: {type: decimal, required: true}
- images: {type: image, multiple: true, max: 10}
- category: {type: taxonomy_term, vocabulary: product_categories}
- specifications: {type: key_value, label: "Характеристики"}
display:
full:
template: product_full
teaser:
template: product_card
url_pattern: /product/{sku}
# media/media_library.cifra
media:
# Типы медиа
types:
- id: image
name: "Изображение"
allowed_extensions: [jpg, jpeg, png, gif, webp]
max_size: 5MB
# Автоматическая генерация размеров
image_styles:
- id: thumbnail
width: 150
height: 150
mode: crop
- id: medium
width: 600
height: 400
mode: scale
- id: large
width: 1200
height: 800
mode: scale
- id: og_image # Для social media
width: 1200
height: 630
mode: crop
# EXIF данные
extract_metadata: true
metadata_fields:
- camera_model
- focal_length
- iso
- aperture
- id: document
name: "Документ"
allowed_extensions: [pdf, doc, docx, xls, xlsx, ppt, pptx]
max_size: 10MB
# Извлечение текста для поиска
extract_text: true
- id: video
name: "Видео"
allowed_extensions: [mp4, webm, avi, mov]
max_size: 100MB
# Генерация превью
generate_thumbnail: true
thumbnail_time: 5s # Кадр на 5 секунде
- id: audio
name: "Аудио"
allowed_extensions: [mp3, wav, ogg]
max_size: 20MB
# Хранилища
storage:
- id: local
type: filesystem
path: /var/www/media
public_url: https://example.com/media
- id: s3
type: s3
bucket: company-media
region: eu-west-1
cdn_url: https://cdn.example.com
# Организация медиа
folders:
- id: products
name: "Фото продуктов"
storage: s3
- id: blog
name: "Изображения для блога"
storage: local
- id: documents
name: "Документы"
storage: s3
# Права доступа
permissions:
upload: [editor, admin]
edit: [editor, admin]
delete: [admin]
# Оптимизация
optimization:
images:
compress: true
quality: 85
convert_to_webp: true
strip_metadata: false # Сохранить EXIF
videos:
compress: false
generate_formats: [mp4, webm]
# revisions/content_revisions.cifra
revisions:
# Какие entity версионируются
enabled_entities:
- Deal:
track_changes: true
store_full_copy: false # Хранить только изменения
max_revisions: 50
- BlogPost:
track_changes: true
store_full_copy: true # Хранить полную копию
auto_save_interval: 30s # Автосохранение каждые 30 секунд
- Contract:
track_changes: true
store_full_copy: true
require_revision_message: true # Обязательный комментарий
# Что отслеживается
tracked_fields:
Deal:
- amount # Изменения суммы
- stage # Изменения статуса
- assigned_to # Изменения ответственного
# История изменений
change_history:
format: diff # Показывать diff изменений
show_user: true
show_timestamp: true
show_ip_address: true
# Восстановление
restore:
enabled: true
require_permission: restore_revisions
notify_on_restore: true
# API для работы с версиями
Python API:
# Получить все версии
revisions = deal.get_revisions()
# Получить конкретную версию
old_version = deal.get_revision(revision_id=5)
# Сравнить версии
diff = deal.compare_revisions(revision_a=5, revision_b=7)
# Откатиться к версии
deal.restore_revision(revision_id=5, message="Откат к версии от 10.11")
# История изменений
history = deal.get_change_history()
# → [
# {user: "Ivan", time: "2025-11-10 15:30", changes: {amount: 10000 → 15000}},
# {user: "Petr", time: "2025-11-10 14:20", changes: {stage: "lead" → "proposal"}}
# ]
# comments/comment_system.cifra
comments:
# На каких entities разрешены комментарии
enabled_entities:
- BlogPost:
mode: threaded # Древовидные комментарии
max_depth: 5
order: newest_first
moderation: false
anonymous_allowed: true
edit_time_limit: 15m # Можно редактировать 15 минут
- Deal:
mode: flat # Плоский список
moderation: false
anonymous_allowed: false
mentions_enabled: true # @username упоминания
attachments_enabled: true
- Task:
mode: threaded
max_depth: 3
real_time_updates: true # WebSocket обновления
# Поля комментария
comment_fields:
- author: {type: user, required: true}
- body: {type: rich_text, required: true}
- created_at: {type: datetime, auto: true}
- updated_at: {type: datetime, auto: true}
- parent: {type: comment, nullable: true} # Для вложенных
- attachments: {type: file, multiple: true}
# Модерация
moderation:
enabled: true
auto_approve_registered: true
auto_approve_threshold: 10 # После 10 одобренных - автоодобрение
spam_filter: akismet
require_email: true
# Уведомления
notifications:
on_new_comment:
notify: [content_author, parent_comment_author]
channels: [email, in_app]
on_mention:
notify: [mentioned_user]
channels: [email, in_app, push]
# Реакции (лайки)
reactions:
enabled: true
types: [like, love, helpful, insightful]
# search/search_config.cifra
search:
# Поисковый движок
engine: elasticsearch # или: meilisearch, typesense, algolia
connection:
host: elasticsearch.example.com
port: 9200
index_prefix: cifra_
# Индексируемые entities
indexed_entities:
- Product:
fields:
- name: {boost: 3} # Название важнее
- description: {boost: 1}
- category.name: {boost: 2}
- tags.name: {boost: 1}
settings:
analyzer: russian # Морфология русского языка
suggest: true # Автодополнение
- BlogPost:
fields:
- title: {boost: 3}
- body: {boost: 1}
- tags.name: {boost: 2}
settings:
analyzer: russian
highlight: true # Подсветка найденного
# Facets (фасеты для фильтрации)
facets:
Product:
- field: category
type: hierarchical
label: "Категория"
max_values: 100
- field: price
type: range
label: "Цена"
ranges:
- {from: 0, to: 1000, label: "До 1000"}
- {from: 1000, to: 5000, label: "1000-5000"}
- {from: 5000, to: 10000, label: "5000-10000"}
- {from: 10000, label: "Свыше 10000"}
- field: brand
type: terms
label: "Бренд"
max_values: 50
- field: in_stock
type: boolean
label: "В наличии"
- field: rating
type: range
label: "Рейтинг"
ranges:
- {from: 4, label: "4+ звёзд"}
- {from: 3, to: 4, label: "3-4 звезды"}
# Поисковая страница
search_page:
path: /search
results_per_page: 24
sort_options:
- {field: relevance, label: "По релевантности"}
- {field: created_at, direction: desc, label: "Сначала новые"}
- {field: price, direction: asc, label: "Сначала дешёвые"}
- {field: price, direction: desc, label: "Сначала дорогие"}
# Did you mean (подсказки)
suggestions:
enabled: true
max_suggestions: 3
# Автодополнение
autocomplete:
enabled: true
min_chars: 3
max_results: 10
# aliases/url_aliases.cifra
aliases:
# Автоматическая генерация алиасов
auto_generate:
enabled: true
patterns:
BlogPost: /blog/{year}/{month}/{slug}
Product: /product/{category.slug}/{slug}
Deal: /deals/{id}
Contact: /contacts/{id}
# Генерация slug из названия
slug:
source_field: title # Или name
transliterate: true # Транслитерация (кириллица → латиница)
separator: "-"
lowercase: true
max_length: 100
# Правила транслитерации
transliteration:
а: "a"
б: "b"
в: "v"
# ... и т.д.
# Уникальность
unique:
check: true
on_conflict: append_number # Добавить цифру: "my-post-2"
# Редиректы при изменении
redirects:
create_on_change: true # Создать редирект со старого URL
redirect_type: 301 # Permanent redirect
# redirects/redirects.cifra
redirects:
# Простые редиректы
- from: /old-page
to: /new-page
type: 301 # Permanent
- from: /temporary
to: /other
type: 302 # Temporary
# Редиректы с wildcard
- from: /old-blog/*
to: /blog/*
type: 301
# Регулярные выражения
- from: /product-(\d+)
to: /products/$1
type: 301
regex: true
# Условные редиректы
- from: /special-offer
to: /sale
type: 302
conditions:
date_range:
start: "2025-11-01"
end: "2025-11-30"
# Автоматические редиректы
auto_redirects:
on_url_change: true
on_delete: false
retention: 1y # Хранить 1 год
# seo/seo_settings.cifra
seo:
# Глобальные настройки
global:
site_name: "Моя компания"
default_title_suffix: " | Моя компания"
default_description: "Лучшие товары и услуги"
default_image: /images/og-default.jpg
# Настройки для content types
content_types:
BlogPost:
title_pattern: "{title} | Блог"
description_source: summary
image_source: featured_image
canonical: auto
# Open Graph
open_graph:
type: article
article_author: "{author.name}"
article_published_time: "{published_at}"
# Twitter Card
twitter_card:
card: summary_large_image
creator: "{author.twitter}"
Product:
title_pattern: "{name} - купить в {site_name}"
description_pattern: "{name}. {short_description}. Цена: {price} руб."
image_source: images[0]
# Schema.org structured data
schema:
type: Product
properties:
name: "{name}"
description: "{description}"
image: "{images[0].url}"
price: "{price}"
priceCurrency: "RUB"
availability: "{in_stock ? 'InStock' : 'OutOfStock'}"
# Sitemap
sitemap:
enabled: true
path: /sitemap.xml
entities:
- BlogPost: {priority: 0.8, changefreq: weekly}
- Product: {priority: 0.9, changefreq: daily}
exclude:
- path: /admin/*
- path: /user/*
# Robots.txt
robots:
enabled: true
path: /robots.txt
content: |
User-agent: *
Disallow: /admin/
Disallow: /api/
Sitemap: https://example.com/sitemap.xml
# cache/cache_config.cifra
cache:
# Глобальные настройки
default_ttl: 300 # 5 минут
# Стратегии кэширования
strategies:
# Кэш для entity
entity:
enabled: true
backend: redis
ttl: 3600
# Invalidation (когда сбрасывать)
invalidate_on:
- entity_update
- entity_delete
# Кэш для views
view:
enabled: true
backend: redis
ttl: 300
# Кэш на основе query
cache_key:
- view_id
- display_id
- filters
- sort
- page
# HTTP кэш
http:
enabled: true
public_paths: ["/", "/blog/*", "/products/*"]
private_paths: ["/admin/*", "/user/*"]
headers:
Cache-Control: "public, max-age=300"
Vary: "Accept-Encoding, Cookie"
# CDN
cdn:
enabled: true
provider: cloudflare
purge_on:
- entity_update
- deployment
# Backends
backends:
- id: redis
type: redis
host: redis.example.com
port: 6379
db: 0
- id: memcached
type: memcached
servers: [memcached.example.com:11211]
# Warming (прогрев кэша)
warming:
enabled: true
cron: "0 */6 * * *" # Каждые 6 часов
urls:
- /
- /catalog
- /blog
# queues/queue_config.cifra
queues:
# Определение очередей
queues:
- id: default
priority: 0
workers: 4
retry: 3
timeout: 300s
- id: email
priority: 10 # Высокий приоритет
workers: 2
retry: 5
timeout: 60s
- id: heavy
priority: -10 # Низкий приоритет
workers: 1
retry: 1
timeout: 3600s # 1 час
# Backend
backend: redis
connection:
host: redis.example.com
port: 6379
# Типы задач
jobs:
# Отправка email
- id: send_email
queue: email
handler: email_service.send
retry: 5
retry_delay: 60s
# Генерация отчёта
- id: generate_report
queue: heavy
handler: reports.generate
timeout: 1800s
# Импорт данных
- id: import_csv
queue: default
handler: import.process_csv
retry: 3
# Обработка изображений
- id: process_image
queue: default
handler: media.process_image
batch: true # Можно группировать
batch_size: 10
# Планировщик (cron)
scheduled:
- job: cleanup_old_files
schedule: "0 2 * * *" # 2:00 каждый день
queue: default
- job: send_daily_digest
schedule: "0 9 * * *" # 9:00 каждый день
queue: email
# activity/activity_log.cifra
activity_log:
# Что логировать
tracked_events:
# CRUD операции
- entity_created
- entity_updated
- entity_deleted
# User actions
- user_login
- user_logout
- user_password_changed
# Бизнес-события
- deal_won
- deal_lost
- order_shipped
- payment_received
# Форматирование сообщений
messages:
entity_created: "{user.name} создал(а) {entity_type} '{entity.label}'"
entity_updated: "{user.name} обновил(а) {entity_type} '{entity.label}'"
entity_deleted: "{user.name} удалил(а) {entity_type} '{entity.label}'"
deal_won: "{user.name} выиграл(а) сделку '{deal.title}' на сумму {deal.amount}"
# Хранение
storage:
backend: database
table: activity_log
retention: 180d # Хранить 180 дней
archive_to: s3 # Архивировать в S3
# Доступ
access:
view_own: [user]
view_team: [manager]
view_all: [admin]
# complete_application.cifra
# 1. БАЗОВЫЕ КОМПОНЕНТЫ
entities: {...}
processes: {...}
rules: {...}
api: {...}
# 2. БЕЗОПАСНОСТЬ
security: {...}
# 3. UI/UX
ui: {...}
menus: {...}
blocks: {...}
# 4. КОНТЕНТ-СИСТЕМА (из CMS)
content_types: {...} # ✅ НОВОЕ
taxonomies: {...} # ✅ НОВОЕ
views: {...} # ✅ НОВОЕ
media: {...} # ✅ НОВОЕ
revisions: {...} # ✅ НОВОЕ
comments: {...} # ✅ НОВОЕ
aliases: {...} # ✅ НОВОЕ
redirects: {...} # ✅ НОВОЕ
# 5. ПОИСК И SEO
search: {...} # ✅ НОВОЕ
seo: {...} # ✅ НОВОЕ
# 6. ПРОИЗВОДИТЕЛЬНОСТЬ
cache: {...} # ✅ НОВОЕ
queues: {...} # ✅ НОВОЕ
# 7. МОНИТОРИНГ
activity_log: {...} # ✅ НОВОЕ
integrations: {...}
notifications: {...}
reports: {...}
tests: {...}
deployment: {...}
localization: {...}
scheduling: {...}
Можно создать:
- CRM/ERP системы
- E-commerce магазины
- Блог-платформы
- Корпоративные порталы
- SaaS приложения
- И всё что угодно!
Все в одном формате .cifra 🎯