Django block template tag to display a Bootstrap modal
from django import template | |
from django.core.exceptions import ValidationError | |
from django.core.validators import validate_slug | |
from django.template import TemplateSyntaxError | |
from django.template.base import token_kwargs | |
register = template.Library() | |
@register.tag | |
def modal(parser, token): | |
""" | |
Display a Bootstrap modal on the page containing any valid Django template code between begin and end tags. | |
Examples: | |
{% modal %} | |
<p>Look ma! I'm in a modal!</p> | |
{% footer %} | |
<span>That's great, son. </span><button class="btn btn-default" data-dismiss="modal">Close</button> | |
{% endmodal %} | |
{% modal %} | |
<form method="POST" action=""> | |
{% csrf_token %} | |
{{ form }} | |
<button type="submit" class="btn btn-primary">Submit</button> | |
</form> | |
{% endmodal %} | |
""" | |
bits = token.split_contents() | |
bit_kwargs = token_kwargs(bits[1:], parser) | |
modal_id = str(bit_kwargs.get('modal_id', 'modal')) | |
title = str(bit_kwargs.get('title', None)) | |
nodelist_body = parser.parse(('footer', 'endmodal')) | |
token = parser.next_token() | |
if token.contents == 'footer': | |
nodelist_footer = parser.parse(('endmodal',)) | |
parser.delete_first_token() | |
else: | |
nodelist_footer = None | |
return ModalNode(template, modal_id, title, nodelist_body, nodelist_footer) | |
class ModalNode(template.Node): | |
def __init__(self, modal_id, title, nodelist_body, nodelist_footer): | |
self.modal_id = modal_id | |
self.title = title | |
self.nodelist_body = nodelist_body | |
self.nodelist_footer = nodelist_footer | |
def render(self, context): | |
modal_id = self.modal_id.resolve(context) if self.modal_id else 'modal' | |
title = self.title.resolve(context) if self.title else None | |
footer = f'<div class="modal-footer">{self.nodelist_footer.render(context)}</div>' if self.nodelist_footer else '' | |
output = \ | |
f'<div class="modal fade" id="{self.modal_id}" tabindex="-1" role="dialog" ' \ | |
f' aria-labelledby="{self.modal_id}-title" aria-hidden="true">' \ | |
f' <div class="modal-dialog modal-dialog-centered" role="document">' \ | |
' <div class="modal-content">' \ | |
' <div class="modal-header">' \ | |
f' <h5 class="modal-title" id="{self.modal_id}-title">{self.title}</h5>' \ | |
' <button type="button" class="close" data-dismiss="modal" aria-label="Close">' \ | |
' <span aria-hidden="true">×</span>' \ | |
' </button>' \ | |
' </div>' \ | |
' <div class="modal-body">' \ | |
f' {self.nodelist_body.render(context)}' \ | |
' </div>' \ | |
f' {footer}' \ | |
' </div>' \ | |
' </div>' \ | |
'</div>' | |
return output |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment