Django模板块:如何重用它们,如何将HTML传递给它们?

时间:2022-03-31 11:15:20

Being a frontend dev familiar with Ruby, i'm trying to learn Django templating system.

作为一个熟悉Ruby的frontend dev,我正在尝试学习Django模板系统。

It appears to be an inside-out version of what i'm used to. I struggle to comprehend its reverse ideology: instead of declaring reusable blocks and including them where necessary, in Django you mark some parts of your template as overridable.

这似乎是我过去习惯的一个内在版本。我很难理解它的逆向思想:在Django中,您没有声明可重用的块并在必要时将它们包含在内,而是将模板的某些部分标记为可重写。

Here are two things that i don't understand about this.

这里有两件事我不明白。

  1. With Ruby's Padrino, i would declare a partial (a reusable snippet of templated HTML) and then include it in multiple places. Wherever i call it, it would output its HTML.

    使用Ruby的Padrino,我将声明一个部分(模板化HTML的可重用片段),然后将它包含在多个位置。无论我把它叫什么,它都会输出它的HTML。

    According to Django's templating documentation, each block can be used on a page only once: Finally, note that you can’t define multiple block tags with the same name in the same template.

    根据Django的模板文档,每个块只能在一个页面上使用一次:最后,请注意,不能在同一个模板中定义具有相同名称的多个块标记。

  2. Another feature of Padrino that i find extermely useful is that partials can accept HTML and output (yield) it in a certain place inside them. Below are a couple examples, one for Padrino and one for Jade.

    我发现Padrino的另一个非常有用的特性是,部分可以接受HTML并在其中的某个位置输出它。下面是几个例子,一个是关于Padrino的,另一个是Jade的。

    Please note that partails HTML not as a string (awkwardly passed via an argument) but in a template language via nesting.

    请注意,部分HTML不是作为字符串(通过参数笨拙地传递),而是通过嵌套使用模板语言。

Padrino (Ruby) example

With Padrino i can pass HTML template code into partials:

使用Padrino,我可以将HTML模板代码分为以下部分:

_container.erb

_container.erb

<div class="container <%= myclass %>">
  <div class="container-inner">
    <%= yield %>
  </div>
</div>

layout.erb

layout.erb

<%= partial 'container', locals: { myclass: 'container--header' } do %>
  <h1><%= Sitename %></h1>
  <p>Welcome to my humble place</p>
<% end %>

Resulting HTML

结果HTML

<div class="container container--header">
  <div class="container-inner">
    <h1>Sitename</h1>
    <p>Welcome to my humble place</p>
  </div>
</div>

Jade example

In Jade, partials are called mixins and are processed directly by the template engine rather than the backend framework:

在Jade中,部分称为mixin,由模板引擎直接处理,而不是后端框架:

Jade source

玉源

mixin article(title)
  .article
    .article-wrapper
      h1= title
      if block
        block
      else
        p No content provided

+article('Hello world')
  p This is my
  p Amazing article

Resulting HTML

结果HTML

<div class="article">
  <div class="article-wrapper">
    <h1>Hello world</h1>
    <p>This is my</p>
    <p>Amazing article</p>
  </div>
</div>

Is it possible with Django?

Questions:

问题:

  1. How do i reuse a block multiple times in Django? I would like to declare a snippet of template code and include it in multiple places on the page.
  2. 如何在Django中重用一个块?我想声明一个模板代码片段,并将其包含在页面的多个位置。
  3. How do i pass HTML (template code) into a block? I would like to reuse it with different content.
  4. 如何将HTML(模板代码)传递到一个块中?我想用不同的内容重用它。

The use case that i'm trying to cover is a reusable partial/mixin/block that would serve as a container wrapper for each section of the site.

我要介绍的用例是一个可重用的部分/mixin/block,它可以作为站点的每个部分的容器包装。

Note that with Padrino, i can even make the partial in such a way that it will let me choose which wrapper tag (div, nav, header...) should be used for each instance of the partial, by passing an argument when including the partial:

注意,使用Padrino时,我甚至可以用这样一种方式来做偏置,它可以让我选择每个偏置实例应该使用哪个包装标签(div, nav, header…),包括偏置时传递一个参数:

<% partial 'container', myclass: 'container--header', tag: 'nav' %>

I wonder how to do that with Django.

我想知道如何用Django实现这个目标。

In your answer, please comment on whether it is possible with both a) basic Django functionality; b) some Django extensions.

在您的回答中,请评论是否可以同时使用a)基本Django功能;b)一些Django扩展。

Thank you.

谢谢你!

1 个解决方案

#1


1  

I’m not familiar with Padrino, so I’m not 100% sure I understand what you’re looking for.

我不熟悉帕提诺,所以我不能百分之百地确定我理解你在找什么。

However, Django template blocks definitely aren’t the equivalent of Padrino’s partials. From your description, I think the equivalent would be custom template tags.

然而,Django模板块绝对不等同于Padrino的partials。从您的描述中,我认为等价的是自定义模板标记。

In outline, to create a custom template tag, you:

在outline中,要创建自定义模板标记,您需要:

  1. Create a templatetags module within your Django app, with a file in it to contain the Python code for the tags e.g.

    在Django应用程序中创建一个templatetags模块,其中包含标记的Python代码的文件。

    yourapp/
        models.py
        templatetags/
            __init__.py
            mytemplatetags.py
    
  2. Within that file, create a variable called register that’s an instance of django.template.Library:

    在该文件中,创建一个名为register的变量,该变量是django.template.Library的实例。

    # mytemplatetags.py
    
    from django import template
    
    register = template.Library()
    
  3. Within that file, write a function for each custom tag that you want.

    在该文件中,为您想要的每个自定义标记编写一个函数。

For a tag that includes a template snippet, you’d want to write an inclusion tag.

对于包含模板片段的标记,您需要编写包含标记。

Inclusion tags can take arguments, which could include HTML (but only as a string).

包含标签可以接受参数,这可能包括HTML(但只是作为字符串)。

#1


1  

I’m not familiar with Padrino, so I’m not 100% sure I understand what you’re looking for.

我不熟悉帕提诺,所以我不能百分之百地确定我理解你在找什么。

However, Django template blocks definitely aren’t the equivalent of Padrino’s partials. From your description, I think the equivalent would be custom template tags.

然而,Django模板块绝对不等同于Padrino的partials。从您的描述中,我认为等价的是自定义模板标记。

In outline, to create a custom template tag, you:

在outline中,要创建自定义模板标记,您需要:

  1. Create a templatetags module within your Django app, with a file in it to contain the Python code for the tags e.g.

    在Django应用程序中创建一个templatetags模块,其中包含标记的Python代码的文件。

    yourapp/
        models.py
        templatetags/
            __init__.py
            mytemplatetags.py
    
  2. Within that file, create a variable called register that’s an instance of django.template.Library:

    在该文件中,创建一个名为register的变量,该变量是django.template.Library的实例。

    # mytemplatetags.py
    
    from django import template
    
    register = template.Library()
    
  3. Within that file, write a function for each custom tag that you want.

    在该文件中,为您想要的每个自定义标记编写一个函数。

For a tag that includes a template snippet, you’d want to write an inclusion tag.

对于包含模板片段的标记,您需要编写包含标记。

Inclusion tags can take arguments, which could include HTML (but only as a string).

包含标签可以接受参数,这可能包括HTML(但只是作为字符串)。