2011-12-08 30 views
1

我需要在网页上实现导航菜单,可能有几个级别的选项卡。每当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; 
} 

够简单。在适当的时候只需要改变身体的课程。

现在,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模板,但一般的答案也赞赏。

回答

3

我做了类似的事情(金字塔& 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。然后,我创建了导航元素模板在马可:

<%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递归(其真子不支持,所以我只想让两个副本该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, ...] 

希望,一个回答你的问题。只要确保您的列表长度正确,以免出现界限错误。

+0

改变通过活动链接(例如在Jinja2的,但它应该是相似的)

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

更多信息只注意到你想每个项目都有自己的班级。这只是将其他元素传递给每件事物。 '

  • ' –

  • +0

    这很接近我最终做的。有点笨重,但它的工作,所以我会接受这个答案。 – tuomur

    +0

    很酷我实际上改变了我的设置,甚至更好...每个导航项目是一个类标题,href和活动属性的对象,我只是循环他们显示导航,我发现它更好。 –