1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

# Copyright 2013-2016 The Distro Tracker Developers 

# See the COPYRIGHT file at the top-level directory of this distribution and 

# at https://deb.li/DTAuthors 

# 

# This file is part of Distro Tracker. It is subject to the license terms 

# in the LICENSE file found in the top-level directory of this 

# distribution and at https://deb.li/DTLicense. No part of Distro Tracker, 

# including this file, may be copied, modified, propagated, or distributed 

# except according to the terms contained in the LICENSE file. 

"""Additional distro-tracker specific template tags.""" 

 

import re 

 

from django import template 

from django.template.loader import render_to_string 

from django.utils.html import conditional_escape 

from django.utils.safestring import mark_safe 

 

register = template.Library() 

 

 

class RepeatNode(template.Node): 

""" 

A :class:`Node <django.template.base.Node>` for implementing the 

:func:`repeat` template tag. 

""" 

def __init__(self, nodelist, count): 

self.nodelist = nodelist 

self.count = template.Variable(count) 

 

def render(self, context): 

""" 

Renders the contents of the template tag :attr:`count` times. 

""" 

output = self.nodelist.render(context) 

return output * int(self.count.resolve(context)) 

 

 

@register.tag 

def repeat(parser, token): 

""" 

Repeats the string enclosed in the tag the number of times given in 

the parameter of the tag. 

""" 

try: 

tag_name, count = token.split_contents() 

except ValueError: 

raise template.TemplateSyntaxError( 

'{tag} tag requires an argument'.format( 

tag=token.contents.split()[0])) 

 

nodelist = parser.parse(('endrepeat',)) 

parser.delete_first_token() 

return RepeatNode(nodelist, count) 

 

 

@register.simple_tag() 

def octicon(name, title='', content=None, role="img"): 

""" 

Renders an octicon with alternate text. 

""" 

if content is None: 

content = mark_safe('<span class="sr-only">[{}]</span>'.format(title)) 

 

return mark_safe(render_to_string( 

'core/octicon.html', 

{'name': name, 'title': title, 'content': content, 'role': role} 

).rstrip()) 

 

 

@register.simple_tag() 

def toggle_chevron(title='Toggle details'): 

""" 

Renders a chevron to toggle details. 

""" 

chevron = \ 

'<span role="button" aria-label="{}">{}</span>'.format( 

title, octicon('chevron-down', title=title, content='')) 

return mark_safe(chevron) 

 

 

@register.filter(name='zip') 

def zip_iterables(first, second): 

""" 

A convenience template filter to :func:`zip` two sequences in the template. 

 

Using this filter it is possible to iterate through the values of two 

sequences in the same time in the template itself. 

""" 

return zip(first, second) 

 

 

@register.filter() 

def lookup(dictionary, key): 

""" 

A filter to retrieve values from dictionaries. 

 

The lookup filter can access dictionary entries by their key, where the 

key can be a variable and not only a literal value. It can be used 

like this "dictionary|lookup:key" where both "dictionary" and "key" 

are variables. 

""" 

return dictionary.get(key, '') 

 

 

@register.filter() 

def breakable(content): 

""" 

A filter that adds <wbr> (word breakpoints) to long words. Useful for 

very long versions strings that would otherwise cause text overflows in 

small cells. Returns an empty string when passed None. 

""" 

if content is None: 

return '' 

 

if len(content) >= 10: 

content = conditional_escape(content) 

return mark_safe(re.sub(r'([-~+\.])', '\\1<wbr>', content)) 

 

return content