Как добавить свойства в вывод unordered_list? - PullRequest
4 голосов
/ 12 декабря 2010

Я использую тег unordered_list в django.

У меня есть следующий список:

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 Ответ

5 голосов
/ 12 декабря 2010

Как видно из исходного кода, <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, в зависимости от того, как вы хотите, чтобы он работал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...