Last active
October 2, 2015 14:08
-
-
Save joncotton/2255481 to your computer and use it in GitHub Desktop.
render_model with
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| A working `render_model with` that works like Django's include templatetag. It's a gist because it's not official enough to fork&commit. There are no tests and `with` isn't implemented on the other `render` tags. | |
| """ | |
| from django.conf import settings | |
| from django.template.loader_tags import BaseIncludeNode | |
| from django.template.defaulttags import token_kwargs | |
| # class RenderObjectNode(template.Node): | |
| # def __init__(self, object, name): | |
| # self.object = template.Variable(object) | |
| # self.name = template.Variable(name) | |
| # def render(self, context): | |
| # name = self.name.resolve(context) | |
| # object = self.object.resolve(context) | |
| # return render_model(object, name, dictionary={}, | |
| # context_instance=context) | |
| class RenderObjectNode(BaseIncludeNode): | |
| def __init__(self, obj, template_name, *args, **kwargs): | |
| super(RenderObjectNode, self).__init__(*args, **kwargs) | |
| self.obj = template.Variable(obj) | |
| self.template_name = template.Variable(template_name) | |
| def render_template(self, obj, template_name, context): | |
| values = dict([(name, var.resolve(context)) for name, var | |
| in self.extra_context.iteritems()]) | |
| if self.isolated_context: | |
| return render_model(obj, template_name, context_instance=context.new(values)) | |
| context.update(values) | |
| output = render_model(obj, template_name, context_instance=context) | |
| context.pop() | |
| return output | |
| def render(self, context): | |
| try: | |
| obj = self.obj.resolve(context) | |
| template_name = self.template_name.resolve(context) | |
| return self.render_template(obj, template_name, context) | |
| except: | |
| if settings.TEMPLATE_DEBUG: | |
| raise | |
| return '' | |
| # @register.tag(name="render_model") | |
| # def do_render_model(parser, token): | |
| # tokens = token.split_contents() | |
| # if len(tokens) is 3: | |
| # _, object, name = tokens | |
| # return RenderObjectNode(object, name) | |
| # message = "Too %s parameters" % ("many" if len(tokens) > 3 else "few") | |
| # raise TemplateSyntaxError(message) | |
| @register.tag(name="render_model") | |
| def do_render_model(parser, token): | |
| bits = token.split_contents() | |
| if len(bits) < 3: | |
| raise TemplateSyntaxError("%r tag takes at least two arguments: the object and the name of the template to render it with." % bits[0]) | |
| options = {} | |
| remaining_bits = bits[3:] | |
| while remaining_bits: | |
| option = remaining_bits.pop(0) | |
| if option in options: | |
| raise TemplateSyntaxError('The %r option was specified more ' | |
| 'than once.' % option) | |
| if option == 'with': | |
| value = token_kwargs(remaining_bits, parser, support_legacy=False) | |
| if not value: | |
| raise TemplateSyntaxError('"with" in %r tag needs at least ' | |
| 'one keyword argument.' % bits[0]) | |
| elif option == 'only': | |
| value = True | |
| else: | |
| raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % | |
| (bits[0], option)) | |
| options[option] = value | |
| isolated_context = options.get('only', False) | |
| namemap = options.get('with', {}) | |
| # path = bits[2] | |
| # if path[0] in ('"', "'") and path[-1] == path[0]: | |
| # return ConstantIncludeNode(path[1:-1], extra_context=namemap, | |
| # isolated_context=isolated_context) | |
| return RenderObjectNode(bits[1], bits[2], extra_context=namemap, | |
| isolated_context=isolated_context) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment