开发者

Django: Does DRY fundamentally conflict with logic separation?

This is similar to this question: How to use method parameters in a Django template?

I understand (and agree with and appreciate) the basic django philosophy of separation of business logic from presentation logic.

However, at times it seems to make DRYness more difficult, and DRY is a practice of even greater gravity, no?

Let's say I have a template that I use for breadcrumb navigation. I re-use (by including) this template over and over for each navigation l开发者_如何转开发ayer. Nice and dry. Yet I want the template to know which iteration of the nav it is representing.

I swear I remember a method to accomplish this - something like {% include 'llamas'html' | 2 %} but I may be wrong.

If I am, how can I keep this template (and the navigation) DRY without violating the principle of separation of logic?


Instead of including, you might also extend from a common template that includes or inlines the code for breadcrumbs.

e.g. sometemplate.html:

{% extends "base_with_breadcrumbs.html" %}

Also, if you don't want to have breadcrumbs on some pages, inside the "base_with_breadcrumbs.html" you can wrap the crumbs into an {% if with_crumbs %}...{% endif %} statement.

Inside the base template you can define blocks that may be populated in the derived templates.

Also, take a look at jinja2, it is similar to django, but has many nice features. I've rewritten 50-some templates in jinja for my project and never looked back.


My advice would be to switch to Jinja2. The include tag is mostly the same, but you also have the macro tag which gives you a callable block which can be easily reused with variables.

Some variation on the include tag:

{% include "sidebar.html" ignore missing %}
{% include "sidebar.html" ignore missing with context %}
{% include "sidebar.html" ignore missing without context %}
{% include ['page_detailed.html', 'page.html'] %}
{% include ['special_sidebar.html', 'sidebar.html'] ignore missing %}

With macros you can do stuff like this:

{% macro input(name, value='', type='text') -%}
    <input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
{%- endmacro %}

Which can be called like this:

{% import 'forms.html' as forms %}
<dl>
    <dt>Username</dt>
    <dd>{{ forms.input('username') }}</dd>
    <dt>Password</dt>
    <dd>{{ forms.input('password', type='password') }}</dd>
</dl>

Assuming that the file with the macro is forms.html. You can also put the macro in the same file so you won't have to import.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜