Skip to content

Instantly share code, notes, and snippets.

@mx-moth
Created June 4, 2015 04:09
Show Gist options
  • Save mx-moth/9866992ba6491a665728 to your computer and use it in GitHub Desktop.
Save mx-moth/9866992ba6491a665728 to your computer and use it in GitHub Desktop.
from django.template import Node, TemplateSyntaxError
from django.template.library import parse_bits, Library
from django.shortcuts import render_to_string
register = Library()
class Button(Node):
"""
Usage::
{% button type="button" class="btn-primary" name="submit" icon="cog" %}
Press me
{% endbutton %}
All arguments are optional.
``type``:
- What kind of button to render. Possible values are "a", "button", and
"submit", for `<a>`, `<button>`, and `<input type="submit">`
respectively. Defaults to "a"
``class``:
- Any CSS class names for the button. See the wagtailstyleguide for all the
possible classes. Defaults to the standard button class.
``name``:
- The name attribute for the button. Only applicable for "button" and
"submit" button types. Defaults to no name.
``icon``:
- Used to add an icon to the button. See the wagtailstyleguide for all
the possible icons. Defaults to no icon
"""
TAG_NAME = 'button'
types = {
'a': 'wagtailadmin/components/buttons/a.html',
'button': 'wagtailadmin/components/buttons/button.html',
'submit': 'wagtailadmin/components/buttons/submit.html',
}
def __init__(self, inner, type_var, class_var, icon_var, name_var):
self.type_var = type_var
self.class_var = class_var
self.icon_var = icon_var
self.name_var = name_var
self.inner_nodelist = inner
def render(self, context):
classes = []
if self.class_var:
classes.append(self.class_var.resolve(context))
if self.icon_var:
classes.append('icon-' + self.icon_var.resolve(context))
if self.type_var:
button_type = self.type_var.resolve(context)
if button_type not in self.types:
raise TemplateSyntaxError("'%s' unknown button type %s" % (
self.TAG_NAME, button_type))
else:
button_type = 'a'
template = self.types[button_type]
return render_to_string(template, {
'class': ' '.join(classes),
'name': self.name_var.resolve(context) if self.name_var else '',
'type': button_type,
})
@classmethod
def handle(cls, parser, token):
name = cls.TAG_NAME
bits = token.split_contents()[1:]
# This is typically taken from getargspec, but we are doing funky things...
# All the possible arguments
params = ['type', 'class', 'icon', 'name']
# Everything has an empty default
defaults = [(arg, None) for arg in params]
# No *args or **kwargs
varargs, varkw = None
args, kwargs = parse_bits(
parser, bits, params, varargs, varkw, defaults,
takes_context=False, function_name=name)
# Get the contents till {% endbutton %}
inner = parser.parse(['end' + name])
parser.delete_first_token()
return cls(inner, *args, **kwargs)
register.tag(Button.TAG_NAME, Button.handle)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment