如何在unordered_list的输出中添加属性?

时间:2010-12-12 09:22:19

标签: django django-templates

我在django中使用unordered_list标记。

我有以下列表:

foo = ['A', ['B', 'C', 'D'], 'E']

以下标记:

{{ foo|unordered_list }}

正如预期的那样产生以下内容:

<li>A
    <ul>
            <li>B</li>
            <li>C</li>
            <li>D</li>
    </ul>
</li>
<li>E</li>

我想要做的是将 id class 属性添加到每个“li”节点。 我知道我可以在JavaScript中完成它,或者在django中实现我自己的模板标记。但我想先问一下。可能在django模板中已经存在一种简单的内置方式吗?

1 个答案:

答案 0 :(得分:5)

正如您在源代码中看到的那样,<li>是硬编码的,因此如果不创建自己的模板过滤器,则无法执行此操作。

def unordered_list(value, autoescape=None):                                                                                                                                                                                                                                                                                 
    """                                                                                                                                                                                                                                                                                                                     
    Recursively takes a self-nested list and returns an HTML unordered list --                                                                                                                                                                                                                                              
    WITHOUT opening and closing <ul> tags.                                                                                                                                                                                                                                                                                  

    The list is assumed to be in the proper format. For example, if ``var``                                                                                                                                                                                                                                                 
    contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``,                                                                                                                                                                                                                                               
    then ``{{ var|unordered_list }}`` would return::                                                                                                                                                                                                                                                                        

        <li>States                                                                                                                                                                                                                                                                                                          
        <ul>                                                                                                                                                                                                                                                                                                                
                <li>Kansas                                                                                                                                                                                                                                                                                                  
                <ul>                                                                                                                                                                                                                                                                                                        
                        <li>Lawrence</li>                                                                                                                                                                                                                                                                                   
                        <li>Topeka</li>                                                                                                                                                                                                                                                                                     
                </ul>                                                                                                                                                                                                                                                                                                       
                </li>                                                                                                                                                                                                                                                                                                       
                <li>Illinois</li>                                                                                                                                                                                                                                                                                           
        </ul>                                                                                                                                                                                                                                                                                                               
        </li>                                                                                                                                                                                                                                                                                                               
    """                                                                                                                                                                                                                                                                                                                     
    if autoescape:                                                                                                                                                                                                                                                                                                          
        from django.utils.html import conditional_escape                                                                                                                                                                                                                                                                    
        escaper = conditional_escape                                                                                                                                                                                                                                                                                        
    else:                                                                                                                                                                                                                                                                                                                   
        escaper = lambda x: x                                                                                                                                                                                                                                                                                               
    def convert_old_style_list(list_):                                                                                                                                                                                                                                                                                      
        """                                                                                                                                                                                                                                                                                                                 
        Converts old style lists to the new easier to understand format.                                                                                                                                                                                                                                                    

        The old list format looked like:                                                                                                                                                                                                                                                                                    
            ['Item 1', [['Item 1.1', []], ['Item 1.2', []]]                                                                                                                                                                                                                                                                 

        And it is converted to:                                                                                                                                                                                                                                                                                             
            ['Item 1', ['Item 1.1', 'Item 1.2]]                                                                                                                                                                                                                                                                             
        """                                                                                                                                                                                                                                                                                                                 
        if not isinstance(list_, (tuple, list)) or len(list_) != 2:                                                                                                                                                                                                                                                         
            return list_, False                                                                                                                                                                                                                                                                                             
        first_item, second_item = list_                                                                                                                                                                                                                                                                                     
        if second_item == []:                                                                                                                                                                                                                                                                                               
            return [first_item], True                                                                                                                                                                                                                                                                                       
        old_style_list = True                                                                                                                                                                                                                                                                                               
        new_second_item = []                                                                                                                                                                                                                                                                                                
        for sublist in second_item:                                                                                                                                                                                                                                                                                         
            item, old_style_list = convert_old_style_list(sublist)                                                                                                                                                                                                                                                          
            if not old_style_list:                                                                                                                                                                                                                                                                                          
                break                                                                                                                                                                                                                                                                                                       
            new_second_item.extend(item)                                                                                                                                                                                                                                                                                    
        if old_style_list:                                                                                                                                                                                                                                                                                                  
            second_item = new_second_item                                                                                                                                                                                                                                                                                   
        return [first_item, second_item], old_style_list                                                                                                                                                                                                                                                                    
    def _helper(list_, tabs=1):                                                                                                                                                                                                                                                                                             
        indent = u'\t' * tabs                                                                                                                                                                                                                                                                                               
        output = []                                                                                                                                                                                                                                                                                                         

        list_length = len(list_)                                                                                                                                                                                                                                                                                            
        i = 0                                                                                                                                                                                                                                                                                                               
        while i < list_length:                                                                                                                                                                                                                                                                                              
            title = list_[i]                                                                                                                                                                                                                                                                                                
            sublist = ''                                                                                                                                                                                                                                                                                                    
            sublist_item = None                                                                                                                                                                                                                                                                                             
            if isinstance(title, (list, tuple)):                                                                                                                                                                                                                                                                            
                sublist_item = title                                                                                                                                                                                                                                                                                        
                title = ''                                                                                                                                                                                                                                                                                                  
            elif i < list_length - 1:                                                                                                                                                                                                                                                                                       
                next_item = list_[i+1]                                                                                                                                                                                                                                                                                      
                if next_item and isinstance(next_item, (list, tuple)):                                                                                                                                                                                                                                                      
                    # The next item is a sub-list.                                                                                                                                                                                                                                                                          
                    sublist_item = next_item                                                                                                                                                                                                                                                                                
                    # We've processed the next item now too.                                                                                                                                                                                                                                                                
                    i += 1                                                                                                                                                                                                                                                                                                  
            if sublist_item:                                                                                                                                                                                                                                                                                                
                sublist = _helper(sublist_item, tabs+1)                                                                                                                                                                                                                                                                     
                sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,                                                                                                                                                                                                                                                   
                                                         indent, indent)                                                                                                                                                                                                                                                    
            output.append('%s<li>%s%s</li>' % (indent,                                                                                                                                                                                                                                                                      
                    escaper(force_unicode(title)), sublist))                                                                                                                                                                                                                                                                
            i += 1                                                                                                                                                                                                                                                                                                          
        return '\n'.join(output)                                                                                                                                                                                                                                                                                            
    value, converted = convert_old_style_list(value)                                                                                                                                                                                                                                                                        
    return mark_safe(_helper(value))                                                                                                                                                                                                                                                                                        
unordered_list.is_safe = True                                                                                                                                                                                                                                                                                               
unordered_list.needs_autoescape = True

重写过滤器以添加id / class支持应该相当容易,具体取决于您希望它如何工作。