【问题标题】:How to implement navigation "selected" item如何实现导航“选中”项
【发布时间】:2012-01-16 05:35:49
【问题描述】:

我需要在网页上实现一个导航菜单,可能有几个级别的选项卡。每当 CSS 在我的控制之下时,我都会使用 CSS 方式,但现在我在使用现有的 CSS 库(在本例中为 Twitter 的 Bootstrap)时遇到了问题。

首先,这是我使用的 CSS 方式。示例 HTML:

<html>
<head>
    <title>Example page</title>
</head>
<body class="articles">

<div class="navigation">
    <ul>
        <li class="frontpage"><a href="#">Frontpage</a></li>
        <li class="articles"><a href="#">Articles</a></li>
    </ul>
</div>

<p>Blah blah.</p>

</body>
</html>

... 和 CSS:

body.frontpage div.navigation li.frontpage,
body.articles div.navigation li.articles {
    background-color:red;
    color:white;
}

足够简单。只有在适当的时候才需要更改 body 的类。

现在,Bootstrap 似乎使用基于类的样式来选择导航项(顶部栏、选项卡、药丸)。示例:

...
<div class="navigation">
    <ul class="tabs">
        <li class="active"><a href="#">Frontpage</a></li>
        <li><a href="#">Articles</a></li>
    </ul>
</div>
...

我最初想做类似的事情

navigation = ('frontpage',)
# or
navigation = ('articles', 'categories', 'foo',)

在控制器中,然后将此元组传递给模板,但不知何故,它有这种“做错事”的氛围。

所以问题是:由于我实际上必须在模板中打印类选择,我如何跟踪当前位置(如导航树中此页面的位置),假设页面可能有多级标签或其他导航项?有没有首选的方法来做到这一点?

我正在使用带有 Mako 模板的路线风格的 Pyramid,但通用答案也很受欢迎。

【问题讨论】:

    标签: python navigation pyramid mako


    【解决方案1】:

    我做了类似的事情(Pyramid 和 Bootstrap 也是如此),但仅用于一级导航。

    我做的第一件事是创建一个“视图”对象,它将参数传递给每个渲染,例如标题、标题、get_data 等。例如

    class View_Controller(object):
        def __init__(self, request, **kwargs):
            self.request = request
            self.nav = kwargs.get('nav', None)
    
        @property
        def page(self):
            return request.GET.get('page', 1)
    
    @view_config(route_name='home', renderer='templates/homepage.mako')
    def Homepage_View(request):
        view = View_Controller(request, nav='homepage')
        stuff = DBSession.query(Stuff).all()
        return {'view': view, 'stuff': stuff}
    

    我在每个页面渲染中都设置了属性 nav,但是在没有激活导航元素时设置了 nav = None。然后我在 Mako 中为导航元素创建了一个模板:

    <%def name="navelements(things)">
    % for a in things:
    <li${' class="active"' if nav == a[1] else '' | n }><a href="#">a[0]</a></li>
    % endfor
    </%def>
    

    其中“事物”是导航中所有元素的元组。 [0] 是显示名称,[1] 是内部名称。需要“| n”来转义 html 字符。例如:

    <%! things = [['Frontpage', 'homepage'], ['Articles', 'arts'], ['Categories', 'cats'], ['Foo', 'foo']] %>
    
    % if things:
    <div class="navigation">
      <ul class="tabs">
        ${navelements(things)}
      </ul>
    </div>
    % else:
    <hr />
    % endif
    

    现在,您可以在模板中或通过视图在控制器中进行设置。如果您想要在每个页面上调用的通用选项卡模板,我有“if things”子句;您可以通过在控制器中设置 things = None 来禁用选项卡。

    这只是一个级别的选项卡,但您可以通过将内容制作为更复杂的列表来做到这一点。我会让事情变得更复杂,以便与它目前的外观相比,它看起来像:

    things = [['displayname1', 'elementname1', things1], ['displayname2', 'elementname2', things2], ...]
    

    然后我会让 navelements 递归(Mako 不支持,所以我只需制作两个 navelements 函数的副本并让它们互相调用)并实现对多级导航的支持:

    <%def name="navelements1(things, level=0)">
    % for a in things:
    <li${' class="active"' if nav[level] == a[1] else '' | n }><a href="#">a[0]</a></li>
       % if a[2]:
         <ul class="tabs">
           ${navelements2(a[2], level+=1)}
         </ul>
       % endif
    % endfor
    </%def>
    

    导航看起来像这样:

    nav = ['frontpage', 'best', None, ...]
    

    希望能回答您的问题。只要确保您的列表长度正确,就不会出现错误。

    【讨论】:

    • 刚刚注意到您希望每个列表项都有自己的类。这只是将另一个元素传递给事物中的每个项目。 &lt;li class="${a[x]}${' active' if nav[y] == a[z] else ''}...&lt;/li&gt;
    • 这与我最终所做的非常接近。这有点笨拙,但它有效,所以我会接受这个答案。
    • 酷。实际上,我将设置更改为更好的设置...每个导航项都是具有标题、href 和活动属性的类对象,我只是循环通过它们来显示导航。我发现它好多了。
    【解决方案2】:

    您可以使用渲染过程中使用的系统值通过访问变量view.__name__来获取模板中的视图名称。

    然后更改活动链接(示例在 jinja2 但应该类似)

    <li {% if view.__name__ == "fixtures" %} class="active" {% endif %}>
      <a href="#">Link</a>
    </li>
    

    更多信息见 http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/templates.html#system-values-used-during-rendering

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-22
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 2013-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多