Могу ли я использовать что-то вроде Hyde из Django?
У меня есть сайт с несколькими сотнями страниц, где, возможно, 75% страниц являются статическим контентом, а остальные соответствуют типичной модели "веб-приложения". Я предпочитаю Django, поэтому я в основном искал решения, основанные на этом.
Контент очень индивидуален - большинство страниц имеют мало общего с базовым хромом сайта и достаточно сложны, чтобы проще было писать их в HTML, а не пытаться заставить правильный текстовый редактор дать правильный вывод. Таким образом, в настоящее время я направляю направление на определение содержимого в шаблонах - у меня есть одно представление и я использую входящий путь в качестве пути шаблона. Это сохраняет каждую страницу на сайте как страницу в файловой системе (легко просматривать, легко отслеживать в управлении версиями), но позволяет каждой странице совместно использовать любое количество общих элементов (верхние и нижние колонтитулы, навигация) и вставлять свои собственные данные в их по мере необходимости.
Это увязло во многих деталях. Например:
- Совместное использование данных страницы с другими страницами. Например, заголовок, определяемый страницей, должен отображаться в меню навигации на других страницах и т. Д. Я нашел этот вопрос о получении значения блока из шаблона, но это кажется действительно запутанным (и не масштабируемым).
- Смежный вопрос: если я определяю что-то как блок, я могу использовать его только один раз. Я видел пример {% block title %} - который обычно проходит в нескольких местах на странице - несколько раз в SO без отличного решения.
- Множественное / гибкое наследование. Для хлебных крошек я мог бы хотеть наследовать от предка страницы, но для макета я бы, вероятно, хотел бы наследовать от чего-то другого (например, базовый шаблон с одним столбцом или с двумя столбцами).
Я думаю, что эти конкретные проблемы могут быть решены сами по себе, в основном с помощью включений и пользовательских тегов шаблонов, но, глядя вниз, я вижу взломы, сложенные поверх хаков, которых я хотел бы избежать - это должно быть довольно просто и легко вздрогнула система.
Изучая их, я наткнулся на Хайда, который, похоже, решает многие из этих проблем. В частности, мне очень нравится, что он имеет представление о структуре сайта и дает страницам несколько хороших инструментов для навигации.
Но у меня все еще есть все динамичные части, которые действительно должны соответствовать без проблем. Поэтому все, что я делаю для страниц контента, должно быть действительно доступно для любого шаблона, который является частью динамического приложения. Кроме того, одна вещь, которая мне действительно нравится в подходе "каждая страница в шаблоне", это то, что я могу изменить обработку любой конкретной страницы, просто добавив ее путь к urls.py и указав настраиваемое представление.
Есть ли хорошее решение для этого типа использования? В более общем смысле, это не то, что Джанго не следует просить делать? Мне приходит в голову, что я пытаюсь использовать файловую систему в качестве базы данных CMS, что, вероятно, приведет к проблемам с масштабированием, но Django, похоже, довольно хорошо обрабатывает и кеширует содержимое шаблона, а также просматривает некоторые существующие CMS. решения (django-cms, feincms, fiber) Мне действительно не нравится идея иметь одно решение для статического контента и совершенно другое для интерактивного контента.
редактировать
Вот что я получил, используя пользовательские теги для обработки метаданных / конфигурации страницы:
- Словарь на странице данных передается на верхнем уровне (так что тег может записать в него, а затем код выше в стеке может прочитать его обратно)
- Пользовательский тег данных позволяет страницам записывать данные в данные этой страницы.
- Другие пользовательские теги считывают и визуализируют структуры (навигация, хлебные крошки и т. Д.) Из данных
Основным элементом является тег, который будет считывать данные (записанные в формате JSON) в глобальный текст:
class PageInfoNode(Node):
def __init__(self, page_info):
self.title = page_info['title']
self.breadcrumb_title = page_info.get('breadcrumb_title', self.title)
self.show_breadcrumb = page_info.get('show_breadcrumb', False)
self.nav_title = page_info.get('nav_title', self.breadcrumb_title)
self.side_nav = page_info.get('side_nav', None)
def render(self, context):
# 'page_info' must be set someplace higher in the context stack
page_info = context['page_info']
page_info['title'] = self.title
page_info['nav_title'] = self.nav_title
if self.show_breadcrumb:
if 'breadcrumb' in page_info:
page_info['breadcrumb'] = [self.breadcrumb_title] + page_info['breadcrumb']
else:
page_info['breadcrumb'] = [self.breadcrumb_title]
if self.side_nav != None:
page_info['side_nav'] = self.side_nav
return ''
@register.tag
def pageinfo(parser, token):
nodelist = parser.parse(('endpageinfo',))
parser.delete_first_token()
return PageInfoNode(json.loads(nodelist.render(Context())))
Каждая страница устанавливает свои данные как:
{% block data %}
{{ block.super }}
{% load my_page_tags %}
{% pageinfo %}
{
"title": "My Page Title",
"show_breadcrumb": true,
"side_nav": ["/section1/page.html", "/section2/page.html"]
}
{% endpageinfo %}
{% endblock data %}
Это работает, но кажется непрозрачным и хрупким:
- Глобальный dict нужно как-то добавить - сейчас я делаю это в представлении, но я думаю, что лучше использовать процессор с собственным контекстом
- Это должно быть в унаследованном блоке, чтобы он действительно отображал
- Поскольку нам иногда нужны данные супер (например, для хлебных крошек), он должен вызывать {{ block.super }}, но он должен быть в правильном порядке, чтобы данные супер не могли перезаписать данные целевой страницы.
Я просто чувствую, что работаю против того, как Django хочет работать, и я надеялся, что есть какой-то лучший способ справиться с такого рода вещами, которые мне не хватало.
2 ответа
Прекратите создавать данные в своих шаблонах. Создайте его в своих представлениях, передайте его в ваши шаблоны. Например, с хлебными крошками нет никаких причин, по которым код, добавляемый в цепочки крошек, должен жить в шаблоне. Он может жить в представлении, или даже лучше, быть контекстным процессором.
Одним из решений является использование статического сайта + модель услуг. Вы используете hyde для создания статического сайта, но ваш динамический контент обрабатывается с использованием javascript на клиентском сайте и прекрасного REST API на вашем сервере.