跳转到主要内容

Django includecontents 组件式标签

项目描述

Django IncludeContents 标签

为Django提供组件式 {% includecontents %} 标签。

例如

{% load includecontents %}
{% includecontents "hello.html" %}
    <p>World</p>
{% endincludecontents %}

它还提供了一个可选的Django模板引擎,将此标签扩展为像HTML组件一样工作。

在这个例子中,它将包含并渲染 components/pretty-card.html

<include:pretty-card title="Hello">
  <p>World</p>
</include:pretty-card>

此引擎还允许使用多行模板标签。例如

{% if 
  user.is_authenticated
  and user.is_staff
%}
...
{% endif %}

安装

pip install django-includecontents

安装自定义模板引擎或将此应用添加到您的 INSTALLED_APPS 中。

使用模板引擎安装

替换您设置中的默认 django.template.backends.django.DjangoTemplates 后端

TEMPLATES = [
    {
        'BACKEND': 'includecontents.django.DjangoTemplates',
        ...
    },
]

此引擎还将 includecontents 添加到内置的标签库中,因此您不需要在模板中加载它。

不使用模板引擎安装

或者,将此应用添加到您的 INSTALLED_APPS 中,并在模板中使用 {% load includecontents %}

INSTALLED_APPS = [
    ...
    'includecontents',
]

模板标签使用

includecontents 标签的作用类似于 include 标签,但内容将被渲染并作为 contents 变量传递给包含的模板。

{% includecontents "hello.html" %}
    <p>World</p>
{% endincludecontents %}

命名内容块

您也可以在组件内容内使用命名内容块。

例如

{% includecontents "hello.html" %}
    <p>World</p>
    {% contents footer %}Footer{% endcontents %}
{% endincludecontents %}

其中 hello.html 模板可能看起来像这样

<div class="card">
  <div class="content">
    {{ contents }}
  </div>
  {% if contents.footer %}
  <div class="footer">
    {{ contents.footer }}
  </div>
  {% endif %}
</div>

HTML组件使用

这需要安装自定义模板引擎。

在模板目录下创建一个components目录。这里将放置使用HTML组件格式使用的组件模板。这些组件是普通的Django模板,将在隔离的上下文中渲染。上下文通过组件的属性传递给组件。

组件不应与任何标准HTML标签匹配。实际上,最好将它们命名为HTML自定义元素(1个或多个ASCII字母;一个短横线;1个或多个ASCII字母、数字或短横线)。

例如,一个components/my-card.html模板可能看起来像

<div class="card">
  <h2>{{ title }}</h2>
  <div class="content">
    {{ contents }}
  </div>
</div>

组件总是与父模板隔离渲染,因此不应依赖于父模板中的任何上下文变量。

这将允许您这样使用它(无需加载任何模板库)

<include:my-card title="Hello">
  <p>World</p>
</include:my-card>

您可以在components目录中使用目录来组织您的组件。例如,components/forms/field.html

<include:forms:field ... />

您可以使用命名的{% contents %},就像使用includecontents标签一样。

一些HTML格式化器(如prettier)坚持在HTML属性值上添加引号,您可以通过可选地将模板值包裹在{}中来避免这种情况

<include:my-card title={mytitle} />

当属性名与变量名匹配时,您可以使用简写语法为HTML属性

<include:my-card {title} />

组件属性

您可以在模板顶部以props (或与JinjaX匹配的def )开头的注释中定义组件的必需或默认属性。如果没有提供必需的属性,将引发异常。

传递给组件的任何其他属性,如果在此定义中未列出,将添加到attrs上下文变量中,可以将其渲染为HTML属性。

{# props #}
<div {{ attrs }}>
  {{ contents }}
</div>

您也可以通过{% attrs %}模板标签为这些属性提供默认值。

{# props title, large=False #}

<div {% attrs class="card" %}>
...

上面的示例组件将需要一个title属性,并允许一个可选的large属性。如果未指定类属性,任何其他属性都将渲染在div上,默认类为card

如果您想提供多组未定义的属性,可以使用group.name作为格式。然后使用{{ attrs.group }}(或如果您想使用回退值,则为{% attrs.group %})来渲染它们。

例如,要调用组件如下

<include:form-field label="Name" name="first_name" value="John" input.class="wide"></include:form-field>

它可以定义如下

{# props value, label="" #}

<div {% attrs class="field" %}>
  {% if label %}{{ '<label>'|safe }}{% endif %}
  {{ label }}
  <input {% attrs.input type="text" value=value %}>
  {% if label %}{{ '</label>'|safe }}{% endif %}
</div>

短横线分隔的属性

未定义的属性可以是“短横线分隔的”,例如

<include:example my-prop="value">

要访问通过attrs变量传递的短横线分隔的属性,请使用其驼峰式等效项。尽管如此,{% attrs %}标签与短横线分隔的情况配合得很好:

{# props #}

{% attrs my-prop="fallback" %}

{% if attrs.myProp %}
my-prop is explicitly set to {{ attrs.myProp }}
{% endif %}

扩展/条件类

将您的类列表以"& "开头,以扩展它而不是替换它

{% attrs class="lg" %}        {# sets default class attribute to "lg" but can be overridden #}
{% attrs class="& lg p-3" %}  {# always add 'lg p-3' classes #}

您可以使用Svelte类指令格式为class属性提供条件类

{# props large=False #}

{% attrs class:lg=large %} {# adds 'lg' class if large prop is truthy #}
{% attrs class:lg %}       {# always adds 'lg' class #}

您也可以直接在组件属性上使用相同的条件格式

<include:my-card title="Hello" class:lg={is_large}>
  <p>World</p>
</include:my-card>

tailwindcss中的条件类

在您的tailwind.config.js中添加此转换,以便Tailwind拾取Svelte-like类指令

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: {
    files: ["**/*.{html,js}", "!node_modules"],
    transform: {
      // Also handle Svelte-like class:class-name directives
      html: (content) => content.replace(/(\w):([-\w]+)/g, '$1 "$2" '),
    },
  },
  ...

Prettier格式化

虽然这不是本包的一部分,但django-includecontentsprettier-plugin-jinja-template插件配合得非常好。此插件可以为您的Django(以及显然的Jinja)模板提供一致的格式。

首先使用npm install --save-dev prettier-plugin-jinja-template安装它。

然后在项目根目录中创建一个.prettierrc文件,内容如下

{
  "plugins": ["prettier-plugin-jinja-template"],
  "overrides": [
    {
      "files": ["**/{templates,jinja2}/**/*.html"],
      "options": {
        "parser": "jinja-template",
        "quoteAttributes": false
      }
    }
  ]
}

quoteAttributes设置为false,以避免对模板变量(例如title={mytitle})的HTML属性值添加引号。使用alpineJS x-data指令时,保持引号不变的方法是在引号和花括号之间简单地放置一个空格:x-data=" {...} "

VScode格式化

要使用VScode中的此Prettier格式,请使用以下两个扩展

将此添加到您的设置中(Ctrl-P,粘贴 >首选项:打开工作区设置(JSON)

{
  "[django-html]": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
}

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分发

django_includecontents-1.1.1.tar.gz (18.1 kB 查看哈希值)

上传

构建分发

django_includecontents-1.1.1-py3-none-any.whl (14.4 kB 查看哈希值)

上传 Python 3

支持