Template Tag for Random Selection of Any Line

 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
# your_app/temmplatetags/yourtaglib.py

from django import template
import random

register = template.Library()

class AnyNode(template.Node):
    def __init__(self, options, splitter="\n"):
        self.options = options
        self.splitter = splitter
    def render(self, context):
        raw_content = self.options.render(context)
        options = raw_content.split(self.splitter)
        clean_options = []
        for option in options:
            stripped = option.strip()
            if stripped: clean_options.append(stripped)
        if len(clean_options) == 1:
            clean_options = clean_options[0].split("|")
        print "clean_options:", clean_options
        return random.choice(clean_options)

@register.tag(name="any")
def do_any(parser, token):
    """
    This tag defines an area for which options will be used at random.  Options
    can be defined in either (but not mixed) of two ways.  Options can be
    defined one per line.  Empty lines are ignored.  Alternatively, options can
    be defined on ONE line, seperated by the pipe "|" character.  You may nest
    options within options.  Example usage in a template:
    
    <p>
    {% any %}
    One day
    Once upon a time
    In a galaxy far, far away
    {% endany %}
    a young foolish {% any %}programmer|lawyer|Jedi{% endany %}
    {% any %}
    set out
    began his quest
    ran screaming 
    {% endany %}
    to pay his stupid tax.
    </p>
    
    # Possible outcomes:
    <p>In a galaxy far, far away a young foolish lawyer set out to pay his stupid tax.</p>
    <p>One day a young foolish programmer ran screaming to pay his stupid tax.</p>
    """
    options = parser.parse( ('endany',))
    parser.delete_first_token()
    return AnyNode(options)

class SeedRandomizationNode(template.Node):
    def __init__(self, variable_name):
        self.variable_name = variable_name
        self.seed_var = template.Variable(variable_name)
    def render(self, context):
        if self.variable_name == 'None':
            random.seed()
            return ''
        if re.match(r'\d*$', self.variable_name):
            actual_seed = int(self.variable_name)
            random.seed(actual_seed)
            return ''
        try:
            actual_seed = self.seed_var.resolve(context)
            random.seed(actual_seed)
            return ''
        except template.VariableDoesNotExist:
            return ''
@register.tag(name='seed_randomization')
def do_seed_randomization(parser, token):
    """
    If you wish to reproduce the same random selection, seed the random number
    generator by passing any integer as the first and only parameter.  You may
    optionally pass None to reseed using the system default (system time).:
    
    # seed using the primary key of a model
    {% seed_randomization article.pk %}
    
    # reseed using a random number
    {% seed_randomization None %}
    """
    try:
        # split_contents() knows not to split quoted strings.
        tag_name, variable_name = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires exactly one argument" % token.contents.split()[0]
    return SeedRandomizationNode(variable_name)

More like this

  1. Make tags easier with properties by ubernostrum 7 years, 1 month ago
  2. tag to store a settings value as template variable by pflanno 2 years, 9 months ago
  3. Analogue template filter to removetags that also removes the content of the tag by piquadrat 3 years, 5 months ago
  4. Template tag to create a list from one or more variables and/or literals by davidchambers 3 years, 7 months ago
  5. Sometimes Tag by deadwisdom 4 years, 10 months ago

Comments

(Forgotten your password?)