Spec-Zone.ru › Wagtail 3

Компоненты шаблонов

Работа с объектами, которые знают, как отображать себя как элементы в 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API