django - 使用带有一些动态元素的公共头

时间:2009-09-22 23:20:05

标签: javascript python django

我打算使用django创建一个网站,整个网站都有一个共同的标题。我已经阅读了django关于模板继承的文档,但我似乎无法找到一个优雅的解决方案来为我的标题中的“动态”元素。

例如,网站中的标题将包含标签,类似于http://www.google.com/(其中包含“网络”,“图片”等),其中所选标签将描述您在网站中的当前位置

使用django模板继承,看起来你会像这样创建一个基本模板:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My Amazing Site{% endblock %}</title>
</head>
<body>
<div id="header">
    {% block header %}
     .... html to create tabs ...
    {% endblock header %}
</div>

然后在我的所有其他页面中,我会这样做:

{% extends "base.html" %}
{% block header % }
 .... html to create tabs with one tab "selected" ...
{% endblock header %}

这看起来很烦人,因为我的每个页面都必须有标题信息的重复HTML,但略有不同。因此,当需要添加新选项卡时,我必须修改每个HTML文件。

进一步阅读后,似乎还有其他一些可能的解决方案:

1 - 创建一个自定义模板标记,该标记接收当前选中的选项卡,在我刚调用的每个HTML页面中都采用这种方式:     {%block header%}     {%mycustomtag abc%}     {%endblock header%}

我不喜欢这个解决方案,因为它需要将HTML放入python代码中来创建这个自定义标记。

2 - 创建X数量的base.html子模板,所有子模板都选中了相应的选项卡。然后,每个页面将根据他们想要选择的选项卡从相应的子模板继承。

这个解决方案似乎很好,除了它需要X个几乎完全相同的HTML,并且仍然遇到在添加或删除选项卡时必须修改所有文件的问题。

3 - 使用javascript(如jquery)修改页面加载时的标题以“选择”正确的标签。

这个解决方案很好,但是需要记住将这个功能添加到每个页面的javascript中。好的部分是标题HTML只存在于一个HTML文件中。

还有其他建议吗?

谢谢!

3 个答案:

答案 0 :(得分:9)

我假设每个标签都是模板base.html中的列表项。

<ul>
    <li>Tab 1</li>
    <li>Tab 2</li>
    ...
</ul>

为每个li添加一个额外的块。

<ul>
    <li class="{% block class_tab1 %}inactive{% endblock %}">Tab 1</li>
    <li class="{% block class_tab2 %}inactive{% endblock %}">Tab 2</li>
    <li class="{% block class_tab3 %}inactive{% endblock %}">Tab 3</li>
    ...
</ul>

然后在模板中选择选项卡1:

{% extends "base.html" %}

{% block class_tab1 %}active{% endblock %}
...

因此,为Tab 1呈现的html是:

<ul>
    <li class="active">Tab 1</li>
    <li class="inactive">Tab 2</li>
    <li class="inactive">Tab 3</li>
    ...
</ul>

您可以根据需要编写CSS以定位li .active

答案 1 :(得分:1)

#1版本可以实现这一功能 - 使用单独的标签模板文件。

假设您有“类别”和“文章”模型。

class Category(models.Model):
    title           = models.CharField(_("Name"), max_length=200)
    introduction    = models.TextField(blank=True, null=True)
    slug            = models.SlugField(help_text=_("Used for URLs"))
    sort_order      = models.IntegerField(_("Sortierung"))

class Article(models.Model):
    title = models.CharField(_("Full Name"), max_length=255)
    slug = models.SlugField(_("Slug Name"), unique=True, help_text=_("This is a short, descriptive name of article that will be used in the URL link to this item"))
    text = models.TextField(_("Text of Article"), blank=True, null=True)
    category = models.ForeignKey(Category)
在您的视图中,您可以将正在查看的类别传递给模板:

@render_to('cat_index.html')
def category_view(request,string):

    cat = Category.objects.get(slug=string)
    articles = Article.objects.filter(category = cat).order_by('date')
    return {
             'articles':articles,
             'category':cat,
             }

(注意:使用annoying render_to - 装饰器 - 与render_to_response相同

并在您的模板中调用include_tag,如下所示:

@register.inclusion_tag('snippets/navigation.html')
def navigation(cat=None):
    return {'cats':Category.objects.order_by('sort_order'),
            'cat':cat
            }

在你的基础模板中使用它(通常称为base.html)

{% navigation category %}

现在在inclusions_tags的模板(snippets/navigation.html)中,您可以循环cats,如果其中一个等于cat,您可以分配其他样式

    <ul>    
      {% for c in cats %}
          <li{% ifequal c cat %} class="active"{% endifequal %}>
              <a href="{{c|url}}">{{ c }}</a>
          </li>
      {% endfor %}
    </ul>

答案 2 :(得分:1)

这是一个相当常见的问题,我想出了一些解决方法。

由于您要求选项,这里有3种其他替代方法可以实现此效果。您提到的选项以及下面列出的选项都有正面和负面的选项。这取决于你决定哪种最合适。

备用1 - 使用正则表达式和哈希表

这可以在客户端(不太有利)或服务器端(更好的选择)执行。要做到这一点,你可以有一个带有1个输入的标签:正则表达式。在使用中它看起来像这样......

// In base.html...

<li class="tab {% is_tab_active r'^/cars/' %}"><a>Cars</a></li>
<li class="tab {% is_tab_active r'^/trucks/' %}"><a>Trucks</a></li>

自定义标记将正则表达式应用于正在查看的当前页面。如果成功,它会添加一个css类“active”,如果不是“inactive”(或者你的CSS类别)。

我一直在思考这种方法。我觉得应该有一些好的方法来想出一个将它绑定到urls.py的方法,但我还没有看到它。

备用2 - 使用CSS

如果您要识别每个[body]标记,或者至少为您网站的各个部分设置一个通用模板,可以使用CSS来指定哪些是活动的。请考虑以下事项:

body.cars_section .navigation #cars_tab { color: #00000; }
body.truck_section .navigation #trucks_tab { color: #00000; }

对于您的基本模板......

<body class="{% block category %}{% endblock %}">

...

<ul class="navigation">
    <li id="cars_tab"><a>Cars</a></li>
    <li id="trucks_tab"><a>Trucks</a></li>

然后对于任何页面,您只需将类别放入(与CSS规则匹配)...

{% extends "base.html" %}

...

{% block category %}cars_section{% endblock %}

备用3 - 有一些膨胀的中间件

Django允许您编写中间件以影响您想要的任何内容的行为。这似乎是一条臃肿而复杂的路线,可能会对业绩产生负面影响,但我认为我至少会将其视为一种选择。