Django templates, pass template language through a template variable - django

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

Related

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

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.

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.

Does django support separating your templates into parts?

I would like to create separate templates for each part of the page like Navigation, Side bar, Login panel, etc. Django seems to use inheritance rather than composition. I was wondering if there is any support for separating templates out into parts and passing in template specific models to each template. I'm thinking of something like:
values = {
'navbar_data' = ...
'sidebar_data' = ...
}
{{ template.render('navbar', navbar_data) }}
{{ template.render('sidebar', sidebar_data) }}
There are many good ways to do this.
You can use the builtin templatetage include for this. This template tag allows you to to use and reuse specific fragments of a template. This is usually most useful for mini templates that say represent a single model and will be used throughout the site. This can be especially useful if you combine it with the with templatetag to allow you to craft the context used in the included template
Alternatively just simply using block may give you the feel you're looking for
Finally you can use custom inclusion templatetags (https://docs.djangoproject.com/en/1.4/howto/custom-template-tags/#inclusion-tags) to give you an even deeper level of control. These will allow you to render a subtemplate with a completely custom context.
That is what templatetags are for. You define a tag in a file called myapp/templatetags/mytags.py, then in your template do this
{% load mytags %}
{% navbar %} {% sidebar %}
The official documentation has plenty of information about this.

How can two apps respond to the same URL in Django?

I think I'm missing a basic concept here. In the stereotypical Django project, you'd have two apps responding to different urls:
http://localhost/myproj/app1/33
http://localhost/myproj/app2/newcomment.html
But what mechanisms exist to handle cases where the two apps are complementary - say one provides content, and the other provides presentation? Or maybe one is content and the other is a kind of static, side-wide content that should appear on every page.
In particular, I don't understand how both apps can use template inheritance to extend the same template. Imagine there's a base app "baseapp" with a template "base.html":
...
<div blah blah>
{% block content %}
{% endblock %}
...
App1 extends it:
{% extends "baseapp/templates/base.html" %}
{% block content %}
... here's the actual content...
{% endblock %}
App2 adds a little banner or something:
{% extends "baseapp/templates/base.html" %}
{% block content %}
<div class="banner">Please support our site!</div>
{{ block.super }}
{% endblock %}
So what are the ways that both templates can get displayed? I can think of:
app1 could extend app2's templates. But this seems wrong: app1 is the content provider, and shouldn't be dependent on something as trivial as app2.
app2 could extend app1's templates. But this seems wrong: now the URL scheme would have to funnel every URL through app2 (if I understand correctly)
middleware?
As I said, I'm probably missing something very basic. Or I'm making some very faulty assumptions that I don't know about. (This question is my third attempt, after Embed an optional Django application in another page, if that app is present and How to capture and display information external to my webapp, but relevant to users of it? - I'm having trouble framing the issue.)
App doesn't respond to an URL, a view does. View is a function that can use models, forms and other object from any app. There isn't any problem here.
If you want to add something to template, inheritance isn't the only way. You'd better use custom context processor or custom template tag.
I think what I was actually missing here:
Apps can override templates just by including a template of the right name in the right subdirectory. The Django docs don't make this very clear, that I can see: they refer to this functionality in the context of Admin templates
When overriding a template as above, you can't extend it, but:
This snippet lets you both override a template and extend it: http://djangosnippets.org/snippets/1376/
Here's a closely related question: Django: Overriding AND extending an app template

django extends different base templates

I understand we can use "extends variable" in the template to switch between two different extended templates.
e.g.
views:
if something:
base = 'base1.html'
else:
base = 'base2.html'
return render_to_response ('template.html', {'base':base})
template.html:
{% extends base %}
Normally that works fine. However, my problem is that I am using django-registration of which I don't have to write my own view to handle the registration and login process. That also means that I am not able to pass the variable to the template. Though I do have the registration templates under my project directory. (like login.html)
Unfortunately, Django can't do this in the template:
{% if something %}
{% extends 'base1.html' %}
{% else %}
{% extends 'base2.html' %}
{% endif %}
The only way I know that the 'variable base' can be passed down to the auth-login is to write my own views like login, logout,etc. This seems like not fitting the DRY model and fairly error prone going forward.
Is there another way that I can accomplish this? Or any pointers to workaround the problem?
Thanks.
-P
If it's just 2 (or 3) options where that 'something' can be made to a Boolean, then you could use the yesno filter:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#yesno
So:
{% extends something|yesno:"base1.html,base2.html" %}
If you want something a bit more free-form, then you could make use of the extra context / custom context processor option mentioned above, and try something like:
{% extends selected_template|default:"base2.html" %}
where selected template is just the path to whatever base template you like.
To be honest this looks to me like a code smell - I've used django-registration a few times, I work on quite large sites and I never needed to extend a template from another template which is only known at run time.
Anyway, if you really want to pass a custom variable to a template rendered by 3rd party module, and you don't want to hack that module, then you have to use e.g. custom template context processor. Also, django-registration allows extra_context to be passed to its views, maybe that would be enough. You can also try monkey-patching. Or maybe you can try manipulating template folders or template loaders to get what you need.
But all these things are IMHO hacks and you shouldn't use different templates for one view, unless it's a generic view.
I think you should not place differences between the templates into the selection of different base templates. Having different base templates is what violates the DRY principle. Place the common things into a template, ie. registration.html, the differences into other templates that you call via 'include':
{%extends base.html%}
{%if something%}
{%include "type1.html"%}
{%else%}
{%include "type2.hmtl"%}
where the template names are the same as you would use in the view definition.
This probably isn't what you are looking for, but could you just include your conditionals in your base.html?