How to assign value to a variable on Django template through jQuery - django

I have a Django template file working with a passed value like the below.
{% include 'boutique/rating.html' with score=[I want to put value here] %}
When I usually put value into the template, I could easily do it by doing like the below.
{% for store in stores %}
{% include 'boutique/rating.html' with score=store.review_score %}
{% endfor %}
However, as I get into more complex templates, I need to assign the value to the score parameter in the include section through jQuery. Is there a way that I can acheive this through jQuery?

What you need to understand is this: The part of the template between {% and %} is interpreted by Django. It is processed entirely on the server. In other words, it never shows up in the browser, but gets replaced by some sort of standard HTML.
On the other hand, jQuery is a Javascript library and operates entirely in the browser -- it doesn't know anything about the server or Django.
So, to modify the included template with jQuery, you have to find out what HTML it renders to. You can probably do that by looking at the included template file. Then, treat that HTML the way you would any other part of the page for manipulation with jQuery.

Related

Tag or inherit the same code in Django template with minor changes

I have a bunch of code that I will need to use repeatedly on a page, and on multiple pages. For example, here is a shorter version of the code:
<a href="#"
data-toggle="popover"
title="{% for terms in s_terms %}{% if terms.slug == 'neuron' %}{{terms.title}}{% endif %}{% endfor %}"
data-content="{% for terms in s_terms %}{% if terms.slug == 'neuron' %}{{terms.para_one}}{% endif %}{% endfor %}">
Toggle popover
</a>
There is a lot more code in the block. Now, for obvious reasons I do not want to keep repeating such large chunks of code. I am a fan of the DRY approach.
However, I can't figure out how to render this same piece of code repeatedly. The only thing that would change is the word = "neuron" in there. I thought of using template tags, but that didn't work.
I tried saving the code as a separate file, and inherit it within my template, but then I can't change the keyword ('neuron'). I also tried creating a separate dynamic page, and include that in my Django template, but looks like the include tag only works for templates, and not for dynamic pages.
Can anyone help, please? Thank you, in advance.
You could use Django template built-in template tag include.
From the documentation:
Loads a template and renders it with the current context. This is a
way of “including” other templates within a template.
So, you can just extract your snippet in a separate template and then use it with:
{% include "snippet_template.html" %}
Additionally, you can pass a variable to the include template using the with keyword - you would use this to pass your word parameter:
{% include "snippet_template.html" with word="neuron" %}
As #bonidjukic wrote the include statement is what you search.
But include statement inside for-loop could reach one weakness of Django template Engine (vs Jinja). You include just variables, so it will be fast.
In the case of needing tags (like trans), Django will load tags at each include. Where Jinja will have global "tags".
So just be careful, with how you DRY you templates.

Template Contexts not recognized from external file (Django)

So, I've been editing a website and have many JavaScript functions that utilize the Contexts that the views.py file passes to the page. Until now, these functions have been contained in the base.html file and so have been loaded onto every page directly. However, to make things cleaner, I copy and pasted all the functions to an external .js file. Now, rather than use the contexts, the functions consider them to be literal strings.
Example:
$('#title').text('{{ event.name }}');
The above line will actually set the text of the element to say "{{ event.name }}" rather than the name of the event. Any ideas on how to fix this? I really don't want to keep these functions in the base file where they can be seen by anyone who inspects the page source.
It doesn't matter if you put your javascript functions in an external file or in your base.html it would still get exposed to the user. Only a minification of the file would actually help to trick the user from seeing the actual values but with javascript all your code is public.
Why you're having this problem is because when you rendered the javascript inline (in your base.html) you had access to the template context.
This is no longer the case and the Django template engine doesn't interpolate your {{ event.name }} anymore.
The problem you're facing as well is a good one. You should never mix and match javascript with Djangos template language or any template language for that matter and the only way of fixing it is to
a) start pulling the values from the DOM ie. render a proper DOM
b) to start to fetch the values from the server, traditionally using AJAX.
And the smallest example that I can muster at the moment is below:
Your view:
def my_django_view(request):
return HttpResponse(json.dumps({'meaningoflife':42}), mimetype='application/json')
Your HTML
<input type="hidden" id="myMeaning" value="{{ meaningoflife }}" />
Your javascript
var meaning = document.querySelector('#myMeaning').value;
alert(meaning); //should alert 42.
In your view you return some form of render_to_response which takes a template argument and a context argument. What the render_to_response function does is read your template, and replace all {{ placeholders }} with the values passed via the context dictionary.
Templates are essentially a complex version of this
"""
<h1>{{ person.name }}</h1>
<p>{{ person.phone_number }}</p>
""".format(person)
The problem is the templating engine does not know files specified by a scripts src attribute is actually a Django template. To fix this don't use the script src attribute. Instead do something like this.
<!--base.html-->
<h1>Site Title</h1>
<p>Some content</p>
<script>
{% include 'jsfile.js' %}
</script>
Using the include statement should do the trick.

Can a django template be referenced from within a loop on another template?

I have a django template which loops over many notes/comments. As a simplified example take this.
{% for note in notes %}
<p>
Date added: {{ note.date_added }}
{{ note.note|urlize|url_target_blank|linebreaks }}
</p>
{% endfor %}
Then on the same page I have a form to add a new note. This note form is an ajax form and returns the newly submitted note back to the page and appends it at the end of the already existent note area.
I don't like this because I have to maintain the same html structure both in the page for the initial load, as well as in the response from the ajax form.
Is there a way to put a call to another template, inside of a template (in this for loop) so I can maintain the note formatting in one location only?
Thanks.
Perhaps you're looking for the "include" tag: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#include

Django templates, pass template language through a template variable

I was thinking about putting my static pages in the database (simple model of url, title and content) and then having a basic base_static.html template - making them super easy to edit (from admin interface) if necessary.
I know you can easily escape html like so:
{{ content|safe }}
or
{% autoescape off %}
{{ content }}
{% endautoescape %}
But I need to be able to use some of the template language in the static pages, e.g. a simple for loop to go over variables passed to it from the view.
Is this possible, or would you recommend simply using templates to serve the static pages?(They won't change that much ever)
Thank you for your help.
If you want to store templates in db (and that is what you want if you want to use a template language) you can use this app : django-dbtemplates.
Check this question: Extending Django Flatpages to accept template tags
You may get some ideas from the solution exposed there

Django conditional template inheritance

I have template that displays object elements with hyperlinks to other parts of my site. I have another function that displays past versions of the same object. In this display, I don't want the hyperlinks.
I'm under the assumption that I can't dynamically switch off the hyperlinks, so I've included both versions in the same template. I use an if statement to either display the hyperlinked version or the plain text version. I prefer to keep them in the same template because if I need to change the format of one, it will be easy to apply it to the other right there.
The template extends framework.html. Framework has a breadcrumb system and it extends base.html. Base has a simple top menu system.
So here's my dilemma. When viewing the standard hyperlink data, I want to see the top menu and the breadcrumbs. But when viewing the past version plain text data, I only want the data, no menu, no breadcrumbs. I'm unsure if this is possible given my current design. I tried having framework inherit the primary template so that I could choose to call either framework (and display the breadcrumbs), or the template itself, thus skipping the breadcrumbs, but I want framework.html available for other templates as well. If framework.html extends a specific template, I lose the ability to display it in other templates.
I tried writing an if statement that would display a the top_menu block and the nav_menu block from base.html and framework.html respectively. This would overwrite their blocks and allow me to turn off those elements conditional on the if. Unfortunately, it doesn't appear to be conditional; if the block elements are in the template at all, surrounded by an if or not, I lose the menus.
I thought about using {% include %} to pick up the breadcrumbs and a split out top menu. In that case though, I'll have to include it all the time. No more inheritance. Is this the best option given my requirement?
You can put your hyperlinks inside a block that is overridden by the loading templates.
Let's say you have your framework.html like this:
{% extends "base.html" %}
<html>...<body>...
{% block hyperlinks %}
your hyperlinks here
{% endblock %}
rest of the code
</body></html>
You can then create something of a nolinks.html template and use it
{% extends "framework.html" %}
{# here you'll have everything from framework
but now we disable the breadcrumbs #}
{% block hyperlinks %}{% endblock %}
If you're getting the past data you can then use nolinks to render instead of framework.
I hope this helps.
From here: Any way to make {% extends '...' %} conditional? - Django
It can be done like this :
{% extends ajax|yesno:"ajax_base.html,main_base.html" %}
Or:
{% extends a_variable_containing_base_template_name %}
Which ever best suited for you.
Regards;