(template_components)= # 템플릿 컴포넌트 HTML 템플릿에 엘리먼트로 렌더링하는 방법을 아는 객체로 작업하는 것은 Wagtail 관리자 전체에서 볼 수 있는 일반적인 패턴입니다. 예를 들어, 관리자 홈페이지는 중앙 `wagtail.admin` 앱에서 제공하는 뷰이지만, 이미지 및 문서와 같은 Wagtail의 다양한 다른 모듈(타사 패키지에서 제공하는 다른 모듈과 함께)에서 가져온 정보 패널을 함께 제공합니다. 이러한 패널은 [`construct_homepage_panels`](construct_homepage_panels) 후크를 통해 홈페이지에 전달되며, 각 패널은 자체 HTML 렌더링을 제공할 책임이 있습니다. 이러한 방식으로 패널을 제공하는 모듈은 홈페이지에 표시되는 방식에 대한 완전한 제어권을 갖습니다. Wagtail은 **컴포넌트**라는 표준 객체 유형을 사용하여 이 패턴을 구현합니다. 컴포넌트는 다음 메서드와 속성을 제공하는 Python 객체입니다. ```{eval-rst} .. method:: render_html(self, parent_context=None) 호출 템플릿의 컨텍스트 사전( :py:class:`Context ` 객체 또는 컨텍스트 변수의 일반 :code:`dict` 일 수 있음)이 주어지면 템플릿에 삽입할 문자열 표현을 반환합니다. 이는 Django의 HTML 이스케이프 규칙의 적용을 받으므로 HTML로 구성된 반환 값은 일반적으로 :py:mod:`SafeString ` 인스턴스로 반환되어야 합니다. .. attribute:: media 컴포넌트에서 사용하는 JavaScript 및 CSS 리소스를 정의하는 (비어 있을 수 있는) :doc:` 폼 미디어 ` 객체입니다. ``` ```{note} 이 API를 구현하는 모든 객체는 유효한 컴포넌트로 간주될 수 있습니다. 아래에 설명된 `Component` 클래스에서 반드시 상속할 필요는 없으며, 컴포넌트로 작업하는 사용자 코드는 이를 가정해서는 안 됩니다(예를 들어, 주어진 값이 컴포넌트인지 확인하기 위해 `isinstance` 를 사용해서는 안 됩니다). ``` ```{note} 버전 6.0부터 Wagtail은 [Laces](https://pypi.org/project/laces/) 라이브러리를 사용하여 모든 컴포넌트 관련 구현을 제공합니다. Laces 라이브러리는 "템플릿 컴포넌트" 개념을 더 넓은 Django 생태계에서 사용할 수 있도록 Wagtail에서 추출되었습니다. 아래에 표시된 모든 가져오기 경로는 계속 작동하지만 Laces의 구현에 대한 참조일 뿐입니다. "템플릿 컴포넌트"는 Wagtail 관리자 확장에만 국한되지 않습니다. 아래의 개념과 도구를 사용자 대면 코드에서도 사용할 수 있습니다. 컴포넌트 사용에 대한 자세한 정보는 [Laces 문서](https://github.com/tbrlpld/laces/blob/main/README.md)에서 찾을 수 있습니다. ``` (creating_template_components)= ## 컴포넌트 생성하기 컴포넌트를 만드는 가장 좋은 방법은 `wagtail.admin.ui.components.Component` 의 서브클래스를 정의하고 `template_name` 속성을 지정하는 것입니다. 그러면 렌더링된 템플릿이 컴포넌트의 HTML 표현으로 사용됩니다. ```python 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`: ```html+django

내 앱에 오신 것을 환영합니다!

``` 템플릿이 필요 없는 간단한 경우에는 `render_html` 메서드를 대신 재정의할 수 있습니다. ```python 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("

{}

", "내 앱에 오신 것을 환영합니다!") ``` ## 템플릿에 컨텍스트 전달하기 `get_context_data` 메서드를 재정의하여 컨텍스트 변수를 템플릿에 전달할 수 있습니다. `render_html` 과 마찬가지로 이 메서드는 호출 템플릿에서 컨텍스트 사전을 받습니다. ```python 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`: ```html+django

{{ username }}님, 내 앱에 오신 것을 환영합니다!

``` ## 미디어 정의 추가하기 Django 폼 위젯과 마찬가지로 컴포넌트는 내부 `Media` 클래스 또는 동적 `media` 속성을 사용하여 관련 JavaScript 및 CSS 리소스를 지정할 수 있습니다. ```python class WelcomePanel(Component): template_name = 'my_app/panels/welcome.html' class Media: css = { 'all': ('my_app/css/welcome-panel.css',) } ``` ## 자신의 템플릿에서 컴포넌트 사용하기 `wagtailadmin_tags` 태그 라이브러리는 템플릿에 컴포넌트를 포함하기 위한 `{% component %}` 태그를 제공합니다. 이 태그는 호출 템플릿의 컨텍스트 변수를 컴포넌트로 전달하는 작업을 처리합니다(기본 `{{ ... }}` 변수 태그의 경우는 그렇지 않음). 예를 들어, 다음 뷰가 주어졌을 때: ```python from django.shortcuts import render def welcome_page(request): panels = [ WelcomePanel(), ] render(request, 'my_app/welcome.html', { 'panels': panels, }) ``` `my_app/welcome.html` 템플릿은 다음과 같이 패널을 렌더링할 수 있습니다. ```html+django {% load wagtailadmin_tags %} {% for panel in panels %} {% component panel %} {% endfor %} ``` `with` 키워드를 사용하여 컴포넌트에 추가 컨텍스트 변수를 전달할 수 있습니다. ```html+django {% component panel with username=request.user.username %} ``` 제공된 변수만으로 (그리고 호출 템플릿의 컨텍스트에서 다른 변수 없이) 컴포넌트를 렌더링하려면 `only` 를 사용하십시오. ```html+django {% component panel with username=request.user.username only %} ``` 컴포넌트의 렌더링된 출력을 즉시 출력하는 대신 변수에 저장하려면 `as` 다음에 변수 이름을 사용하십시오. ```html+django {% component panel as panel_html %} {{ panel_html }} ``` 컴포넌트에 정의된 모든 미디어 선언을 출력하는 것은 템플릿의 책임입니다. Wagtail 관리자 뷰의 경우, 뷰 내에서 전체 페이지에 대한 미디어 객체를 구성하고 이를 템플릿에 전달한 다음 기본 템플릿의 `extra_js` 및 `extra_css` 블록을 통해 출력하는 것이 가장 좋습니다. ```python 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`: ```html+django {% 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 %} ```