Компоненты шаблонов
Работа с объектами, которые знают, как отображать себя как элементы в HTML-шаблоне, — распространённый шаблон, встречающийся в админ-панели Wagtail. Например, домашняя страница админ-панели — это представление, предоставляемое центральным приложением wagtail.admin, но объединяет панели с информацией, полученной из различных других модулей Wagtail, таких как изображения и документы (возможно, вместе с другими, предоставляемыми сторонними пакетами). Эти панели передаются на домашнюю страницу через хук construct_homepage_panels, и каждый из них отвечает за предоставление собственного HTML-отображения. Таким образом, модуль, предоставляющий панель, полностью контролирует её отображение на домашней странице.
Wagtail реализует этот шаблон, используя стандартный тип объекта, известный как компонент. Компонент — это объект Python, предоставляющий следующие методы и свойства:
Принимая словарь контекста из вызывающего шаблона (который может быть объектом Context или обычным dict словарем переменных контекста), возвращает строковое представление, которое должно быть вставлено в шаблон. Оно будет подвергнуто правилам экранирования HTML Django, поэтому возвращаемое значение, состоящее из HTML, обычно должно возвращаться как экземпляр SafeString.
(Возможно, пустой) объект form media, определяющий JavaScript и CSS ресурсы, используемые компонентом.
Примечание
Любой объект, реализующий этот API, может считаться допустимым компонентом; он необязательно должен наследоваться от класса Component, описанного ниже, и пользовательский код, работающий с компонентами, не должен этого предполагать (например, он не должен использовать isinstance для проверки того, является ли данное значение компонентом).
Создание компонентов
Предпочтительный способ создания компонента — определить подкласс wagtail.admin.ui.components.Component и указать атрибут template_name на нём. Затем отрендеренный шаблон будет использоваться в качестве HTML-представления компонента:
from wagtail.admin.ui.components import Component
class WelcomePanel(Component):
template_name = 'my_app/panels/welcome.html'
my_welcome_panel = WelcomePanel()
my_app/templates/my_app/panels/welcome.html:
<h1>Welcome to my app!</h1>
В простых случаях, не требующих шаблона, вместо него можно переопределить метод render_html:
from django.utils.html import format_html
from wagtail.admin.components import Component
class WelcomePanel(Component):
def render_html(self, parent_context):
return format_html("<h1>{}</h1>", "Welcome to my app!")
Передача контекста в шаблон
Метод get_context_data можно переопределить для передачи переменных контекста в шаблон. Как и в случае с render_html, он получает словарь контекста из вызывающего шаблона:
from wagtail.admin.ui.components import Component
class WelcomePanel(Component):
template_name = 'my_app/panels/welcome.html'
def get_context_data(self, parent_context):
context = super().get_context_data(parent_context)
context['username'] = parent_context['request'].user.username
return context
my_app/templates/my_app/panels/welcome.html:
<h1>Welcome to my app, {{ username }}!</h1>
Добавление определений медиа
Как и виджеты Django формы, компоненты могут указывать связанные JavaScript и CSS ресурсы, используя либо внутренний класс Media или динамическое свойство media:
class WelcomePanel(Component):
template_name = 'my_app/panels/welcome.html'
class Media:
css = {
'all': ('my_app/css/welcome-panel.css',)
}
Использование компонентов в собственных шаблонах
Библиотека тегов wagtailadmin_tags предоставляет тег {% component %} для включения компонентов в шаблон. Он позаботится о передаче переменных контекста из вызывающего шаблона в компонент (что не будет происходить с базовым тегом переменной {{ ... }}). Например, при данном представлении:
from django.shortcuts import render
def welcome_page(request):
panels = [
WelcomePanel(),
]
render(request, 'my_app/welcome.html', {
'panels': panels,
})
шаблон my_app/welcome.html мог бы отображать панели следующим образом:
{% load wagtailadmin_tags %}
{% for panel in panels %}
{% component panel %}
{% endfor %}
Обратите внимание, что ваша ответственность — выводить любые определения медиа, определённые в компонентах. В представлении админ-панели Wagtail это лучше всего сделать, создав объект медиа для всей страницы в представлении, передав его в шаблон и выведя его через блоки extra_js и extra_css основного шаблона:
from django.forms import Media
from django.shortcuts import render
def welcome_page(request):
panels = [
WelcomePanel(),
]
media = Media()
for panel in panels:
media += panel.media
render(request, 'my_app/welcome.html', {
'panels': panels,
'media': media,
})
my_app/welcome.html:
{% extends "wagtailadmin/base.html" %}
{% load wagtailadmin_tags %}
{% block extra_js %}
{{ block.super }}
{{ media.js }}
{% endblock %}
{% block extra_css %}
{{ block.super }}
{{ media.css }}
{% endblock %}
{% block content %}
{% for panel in panels %}
{% component panel %}
{% endfor %}
{% endblock %}
© 2014-present Torchbox Ltd and individual contributors.
All rights are reserved.
Licensed under the BSD License.
https://docs.wagtail.org/en/v3.0.3/extending/template_components.html