2010-12-12 34 views
4

我在django中使用unordered_list標記。如何將屬性添加到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> 

我想這樣做是要添加idclass屬性給每個「li」節點。 我知道我可以用JavaScript來做,或者在django中實現我自己的模板標籤。但我想先問。可能在那裏已經存在一個簡單的內置方式在django模板中做到這一點?

回答

5

正如您在源代碼中看到的那樣,<li>是硬編碼的,所以如果不創建自己的templatefilter,就無法做到這一點。

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支持,雖然,這取決於你怎麼想它的工作。

+0

謝謝WoLpH。是的,我看到了這一點,但希望能有一些django魔術可以幫助我。我想我必須推出自己的過濾器。 – nagaru 2010-12-12 18:17:20