Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass variable between two custom tags in Django

I am trying to implement django template tag {% domready %}{% enddomready %} that would take it's contents, remember it somewhere, and then tag {% domready_render %} that would render all that content.

It would look something like this:

{# main.html #}
<html>
...
<body>
  ...
  <script>
      (function($) {
          $(document).ready(function() {
              {% domready_render %}
          });
      })(jQuery);
  </script>
</body>
</html>


{# some_other_file.html #}
{% extends main.html %}
..some html...
<a href="" id="link1">Link with onclick</a>
{% domready %}
    $('#link1').click(function() { ... describe here your javascript ... });
{% enddomready %}
..some html...
<a href="" id="link2">Another with onclick</a>
{% domready %}
    $('#link2').click(function() { ... describe here your another javascript ... });
{% enddomready %}
..some html...

And so my question is: how do I do that? I mean, here's what I tried to do:

@register.tag
def domready(parser, token):
    nodelist = parser.parse(('enddomready',))
    parser.delete_first_token()
    return DomreadyNode(nodelist)

class DomreadyNode(template.Node):
    def __init__(self, nodelist):
        self.nodelist = nodelist

    def render(self, context):
        if 'dom_ready' not in context:
            context['dom_ready'] = []

        context['dom_ready'].append(self.nodelist.render(context))
        return ''

@register.tag
def domready_render(parser, token):
    return DomreadyRenderNode()

class DomreadyRenderNode(template.Node):
    def render(self, context):
        if 'dom_ready' in context:
            return u"\n".join(context['dom_ready'])
        return ''

But this context['dom_ready'] works only with same template (I mean, I can do {{ dom_ready }} in some_other_file.html, but I don't see it at main.html (maybe because they have different render contexts or what?).

Thank you.

like image 203
Konstantine Rybnikov Avatar asked Mar 31 '26 23:03

Konstantine Rybnikov


1 Answers

As you guess render contexts are not shared between template files.

You can solve your problem by using a module level variable where you define your template tags.

Just add

dom_ready = []

to the top of the file, then where you have context['dom_ready'] replace it with dom_ready.

Did you know that you can call $.ready multiple times? That might be simpler and cleaner than achieving this with template tags.

like image 158
Andrew Wilkinson Avatar answered Apr 03 '26 12:04

Andrew Wilkinson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!