开发者

Append Django template tag with Jquery

开发者 https://www.devze.com 2023-03-02 02:33 出处:网络
I want to build a menu where I can set one link highlighted using the {% block %} tag. I have something like this in my Javascript:

I want to build a menu where I can set one link highlighted using the {% block %} tag. I have something like this in my Javascript:

<loop>
$('#a-div').append('{% block ' + variab开发者_开发知识库le + ' %} <a href...</a> {% endblock %}')
<endloop>

In the source, this is displayed as "{% block Home %}"

How can I make JQuery not append this as a string but as a template tag?


You can't. At least not without making an AJAX request to a Django template. In your case, it would be slow and make unnecessary extra requests. It's just not worth it. You can insert snippets from Django templates via jQuery by using, for example, the jQuery load function. But you can't replace a specific {% block %} tag, because by the time jQuery runs, the template has already been processed (and references to block tags removed). But this is not a situation where you should be doing that in any case.

Why don't you rather highlight the menu with a CSS class? Here is my usual solution to this problem:

  1. Create a file called base_extras.py in one of your templatetags folders. If you don't have one, create one in an appropriate folder.
  2. Inside base_extras.py, paste this code:

    from django import template
    from django.core.urlresolvers import reverse
    
    register = template.Library()
    
    @register.simple_tag
    def navactive(request, urls):
        if request.path in ( reverse(url) for url in urls.split() ):
            return "active"
        return ""
    
  3. Now, in your template, on your menus in your base template, do something like this:

    <ul class="menu">
        <li class="home {% navactive request 'home' %}"><a href="{% url home %}">Home</a></li>
        <li class="contact {% navactive request 'contact' %}"><a href="{% url contact %}">Contact</a></li>
        <li class="signup {% navactive request 'signup' %}"><a href="{% url signup %}">Sign up</a></li>
    </ul>
    
  4. This will make that the menu where your URL currently is has the active class. Then, in your CSS, just add a special class for a menu item with active to look slightly different than the other menus.

    ul.menu li.active {background: red; color: white;}
    

And if you happen to need to change the active menu with jQuery, you can just remove the active class on all menus, and add it to the newly selected menus:

$('ul.menu li').removeClass('active').find('.home').addClass('active'); // for example


You can't do that like that. The Django template tags are processed on the server side, before the page is even sent to the browser. Javascript (including jQuery) is, on the other hand, invoked in the browser, after the page has been received from the server.

What you can do is prerender the content of {% block %} tag to JS variable and use it in jQuery code:

var blockContent = "{% block Home %} ... {% endblock %}";
// ...
$("#a-div").append(blockContent);

If you need more than one block to choose from (as you seem to indicate in the code sample you've provided), you could resort to an array of prerendered blocks.


Your best bet is to create a proxy view that makes what is currently your AJAX request, processes the results like the javascript would, and then returns whatever you're trying to get from the Django templating system.

Then, instead of making the AJAX call you're currently making, you call your own view instead. Django does the processing in the view like it should, you get fine-grained control over what's returned to your javascript, and it's still only one (client-side) server call.

0

精彩评论

暂无评论...
验证码 换一张
取 消