How to declare variables inside Django templates - django

How do I declare a variable in Django 1.8 Templates for example like this:
{% my_var = "My String" %}
And so that I can access it like this:
<h1>{% trans my_var %}</h1>
Edit:
To demonstrate my purpose of this, this is my code:
{% my_var = "String Text" %}
{% block meta_title %}{% trans my_var %}{% endblock %}
{% block breadcrumb_menu %}
{{ block.super }}
<li>{% trans my_var %}</li>
{% endblock %}
{% block main %}
<h1>{% trans my_var %}</h1>

Try using the with tag.
{% with my_var="my string" %}
{% endwith %}
The other answer is more correct for what you're trying to do, but this is better for more generic cases.
Those who come here solely from the question title will need this.

One way I like to use is:
{% firstof "variable contents" as variable %}
Then you use it as {{variable}} wherever you want without the necessity for nesting with blocks, even if you define several variables.

You can assign the translation to a variable which you can use throughout.
{% trans "my string" as my_var %}
{{ my_var }} {# You can use my_var throughout now #}
Documentation for trans tag which is an alias for translate tag, after Django-3.1
Full example with your code snippet
{% trans "String text" as my_var %}
{% block meta_title %}{{ my_var }}{% endblock %}
{% block breadcrumb_menu %}
{{ block.super }}
<li>{{ my_var }}</li>
{% endblock %}
{% block main %}
<h1>{{ my_var }}</h1>

Related

What is the difference between `blocktrans` and `blocktranslate`? Between `trans` and `translate`?

What is the difference between these two lines of code in a Django template?
{% blocktrans %}Example{% endblocktrans %}
{% blocktranslate %}Example{% endblocktranslate %}
Likewise, what is the difference between these two lines of code in a Django template?
{% trans "Example" %}
{% translate "Example" %}
There is no difference. {% blocktrans %} is equivalent to {% blocktranslate %}, it's just an alias. Likewise, {% trans %} is equivalent to {% translate %}.

{% block something %} always being displayed despite being False in an if-statement

I have two types of blog articles. Regular blog articles, and translation articles. They both have different html markup. I have a boolean variable translation_bool in my models to check if it is a translation article or not. If it is I want it to display my {% block translation %} and if not {% block translation %}. It worked with plain html code and not using html tags. But I had so much reusable code that it got troublesome to manage.
So my question is: why is this happening despite it being inside of an if statement.
Article template:
{% extends "base_generic.html" %}
{% load static %}
{% block js %}...{% endblock %}
{% if blogpost.translation_bool == True %}
{% block translation %}....{% endblock %}
{% else %}
{% block content %}...{% endblock %}
{% endif %}
{% block sidebar %}....{% endblock %}
In Base Generic Template:
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-8">
{% block content %}{% endblock %}
{% block translation %}{% endblock %}
</div>
<div class="col-md-3">
{% block social_media %}...{% endblock %}
{% block sidebar %}...{% endblock %}
</div>
</div>
</body>
This is because blocks not defined in child template will render value from parent template. So in your case you should perform validation inside parent template. Or if it's impossible override blocks in child with empty content:
{% block translation %}
{% if blogpost.translation_bool == True %}
{{ block.super }}
{% else %}
{% endif %}
{% endblock %}
{% block content %}
{% if blogpost.translation_bool == False %}
{{ block.super }}
{% else %}
{% endif %}
{% endblock %}
Note {{ block.super }} will render content from parent template.

Is there a way to pass a variable to an 'extended' template in Django?

I want to add some flexibility to my layout template, but I can't find any way to do so.
I'm looking for a way to extend my layout template with variable, i.e. to pass a variable up in the template tree, not down.
# views.py
def my_view_func(request):
return render(request, "child.html")
# child.html
{% extends 'layout.html' with show_sidebar=True sidebar_width_class="width_4" %}
<div>Templates stuff here</div>
# layout.html
{% if show_sidebar %}
<div class="{{ sidebar_width_class }}">
{% block sidebar %}{% endblock %}
</div>
{% endif %}
I have to maintain four templates with a difference in a few lines of code. For example, I have two templates that differ from each other by a sidebar width class. Am I doing something wrong?
I suspect that block is what you are looking for in the first place.
Form your block inside the base template like this:
{% block sidebar_wrapper %}
{% if sidebar %}
<div class="width{{sidebar_width}}">
{% block sidebar %}{% endblock %}
</div>
{% endif %}
{% endblock sidebar_wrapper%}
And on your child template:
{% extends 'layout.html' %}
{% block sidebar_wrapper %}
{% with sidebar=True sidebar_width=4 %}
{{ block.super }}
{% endwith%}
{% endblock sidebar_wrapper%}
What you need is an include template tag. You can include a template in another template and render that with specific context.
{% include 'layout.html' with sidebar=True sidebar_width=4 %}
Check docs here: https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#include
You can achieve this with some technique. I'll show the code then explain below.
# layout.html
{% block content %}
{% if show_sidebar %}
<div class="{{ sidebar_width_class }}">
{% block sidebar %}{% endblock %}
</div>
{% endif %}
{% endblock %}
# child.html
{% extends 'layout.html' %}
{% block content %}
{% with show_sidebar=True sidebar_width_class="width_4" %}
{{ block.super }}
{% endwith %}
{% endblock %}
In layout.html, wrap everything inside {% block content %}
In child.html, {{ block.super }} is like python's super(), which renders everything in the parent template's block. So if you wrap it inside {% with %} tag, all variables that you declare there will be available inside the parent template as well.

Django translation in template: trans works "trans as" not

I'm new to django and try the translation feature in views. I came across following problem:
I tried to translate a text into a variable, but this is always empty. However if I just output it works fine.
{% extends "myownapp/base.html" %}
{% load i18n %}
{% trans "Test" as test %} <--- here it is defined
{% block title %}Title - {% trans "Test" %}{% endblock %} <--- does work
{% block content %}
<h1>{{ test }}</h1> <--- does not work
{% endblock %}
Note: I haven't created the language files yet - could this be the problem? Thanks
You need to put {% trans "Test" as test %} into the template block in which you are using the variable:
{% block content %}
{% trans "Test" as test %}
<h1>{{ test }}</h1>
{% endblock %}

{% trans "string" as my_translated_string %} is not rendering content in template

Django 1.4 doc says that you can get translated strings into "vars" to be used in different places or to be used as arguments in template tags or filters using the following syntax:
{% trans "String" as my_translated_string %}
<h1>{{ my_translated_string }}</h1>
https://docs.djangoproject.com/en/1.4/topics/i18n/translation/#trans-template-tag
I'm doing it in that way, however the defined var is never rendering the content. Below my template code:
{% extends "default_layout.html" %}
{% load i18n %}
{% trans "My page title" as title %}
{% block meta_title %}{{ title }}{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
{% endblock %}
Of course "title" is being rendered empty in both cases.
Am I missing something ?
Thank you.
As okm said you need to define the variable within the block in which you want to use it, and the scope of that variable is also within the block:
{% extends "default_layout.html" %}
{% load i18n %}
{% block meta_title %}
{% trans "My page title" as title %}
{{ title }}
{% endblock %}
{% block content %}
{% trans "My page title" as title %}
<h1>{{ title }}</h1>
{% endblock %}