Django 中可重用的 HTML 组件库

问题描述 投票:0回答:3

我有一个 Django 网站,其中有许多页面,所有页面都有自己独特的内容和标记(而不是动态填充数据的单个模板)。这些页面的模板源自通用“工具”模板,而通用“工具”模板又源自“基本”模板。每个页面还有一个 JS 文件,用于为该页面编写脚本。每页数据分布在 3 或 4 个位置:

  • 模板
  • 页面脚本(也许还有其他页面特定的静态数据)
  • 中央“工具注册表”,其中包含工具名称、描述和类别等内容
  • 对于某些工具,一组模板标签用于执行特定于该页面的一些 HTML 构造(例如要在表格中呈现的数据)。

但是,尽管每个页面都有独特的布局和内容,但我仍然希望能够在页面之间共享常用的参数化 HTML“片段”。例如,一个页面有一个带有下拉按钮的输入,使用 Bootstrap,看起来像这样:

<div class="input-group">
    <span class="input-group-btn">
        <a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">
            Common baudrates
            <span class="caret"></span>
        </a>
        <ul class="dropdown-menu pull-right" id="common-baudrate-list">
            <li><a href='#'>9600</a></li>
            <li><a href='#'>115200</a></li>
        </ul> 
    </span>           
    <input class="form-control" type="text" id="baudrate-input" val="115200">
</div>

我想制作一个可重用的参数化函数/模板/标签,它允许我放入这样的结构,给出“组 ID”、“条目列表”、“左/右按钮位置”、“默认值”。

到目前为止我看到的方法是:

  • 作为模板,其语法相当有限,并且很难执行类似这样的条目列表之类的操作:
    ['Entry 1', 'Entry 2']
  • 作为模板,通过视图将数据传递到上下文中(并没有真正的吸引力,因为我会将页面内容分散得更多)。
  • 作为模板标签,将 HTML 构建为一个大而令人讨厌的字符串
  • 作为使用像 lxml 这样的 XML 库的模板标签,这是一种非常灵活的方法,但是语法冗长,过于复杂,而且我仍然需要从模板将数据获取到标签中!

这些看起来都不是一个简洁、可重用且松散耦合的方法来处理这个问题(例如,如果我将来更改为 Bootstrap 4,我可能需要重新编写这些组件,我宁愿只做一次)。拥有这样的组件库也将使未来的页面更容易构建。是否有一个规范的“正确”方法来做到这一点,甚至是一个常用的习惯用法?


编辑以显示解决方案实施

使用 Wolph 下面回答的包含标签,我避免使用像这样的笨重结构

{% with [1,2,3] as items %}
    {% my_tag items.split %}
{% endwith %}

如下:

@register.inclusion_tag('components/this_component.html')
def input_with_dropdown(dropdown_title, dropdown_items, default_value, group_id, button_left, *args, **kwargs):

    split_char = kwargs['split_char'] if 'split_char' in kwargs else ' '

    return {
        'dropdown_items': dropdown_items.split(split_char),
        'dropdown_title': dropdown_title,
        'group_id': group_id,
        'default_value' : default_value,
        'button_left': button_left
    }

然后像这样传入变量:

{% input_with_dropdown 'Common baudrates' '9600 48000 115200' 115200 'baudrate-input' 0 %}
html django django-templates
3个回答
16
投票

您看过包含标签吗? https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags

我相信这些将完全满足您的要求,您仍然可以指定参数,但您可以仅传递模板以使其轻松渲染。

示例:

from django import template
register = template.Library()

@register.inclusion_tag('list_results.html')
def list_results(results):
    return {
        'results': results,
        'count': len(results),
    }

list_results.html

Found {{ count }} results.<br>
<ul>
{% for result in results %}
    <li>{{ result }}</li>
{% endfor %}
</ul>

0
投票

使用 templatetags 和 html 模板...然后您可以重复使用该 HTML 模板...


0
投票

2024 年,Cotton 带来了一些在 Django 中构建 UI 的现代方法,包括解耦、可重用和可配置的组件。它将允许您创建快速组件,而无需创建额外的模板标签文件。

只需将文件放入模板/棉花中,它们将在视图中以

<c-my-component />
的形式提供。

使用OP示例的简化版本:

<!-- input_group.html -->

<div class="input-group">
  <a class="btn btn-default">
    {{ slot }}
  </a>
  <ul>
    {% for item in items %}
      <li>{{ item }</li>
    {% endfor %}
  </ul> 
  <input value="{{ default_value }}">
</div>

您不能在任何您希望的地方使用此组件:

<!-- my_view.html -->

<c-input-group default_value="1234" :items=[123,456]>
  Common baudrates
</c-input-group>

<c-input-group default_value="5678" :items=[111,222]>
  Rare baudrates
</c-input-group>
© www.soinside.com 2019 - 2024. All rights reserved.