I know this isn't exactly Django templating philosophy, but i'd like to be able to include different templates depending on a list of plugins that I've specified in the http response context. For example, if I have the following plugins configured:
context['plugins'] = ['weather']
I attempt to include each template in the base template file:
{% for custom_plugin in custom_plugins %}
{% include "map/plugins/custom/{{ plugin }}/includes.html" %}
{% endfor %}
I've also tried:
{% for plugin in plugins %}
#register.inclusion_tag("map/plugins/custom/{{ plugin }}/includes.html", takes_context=True)
{% endfor %}
For now the each plugin will only contain script references and css classes in their includes.html file:
<script type="text/javascript" src="{{ MEDIA_URL }}map/js/plugins/custom/weather/weatherStation.js?ver={{ version }}"></script>
Any suggestions?
Your first way seems the best, and this answer might provide some pointers as to how you'd go about it: How to concatenate strings in django templates?
You basically want to build a string of the template to include in a variable with the with tag, then include it.
Related
I have a template where I need to access a directory based on the user's fields.
The code looks like this:
{% with user.client.company as company %}
{% static 'uploads/{{ company }}' as files %}
{% endwith %}
I also tried:
{% static 'uploads/{% user.client.company %}' as files %}
How can I achieve this? I want the folder name to be equal to user.client.company but right now I get an error like:
Invalid block tag: 'static', expected 'endwith' for the first one and
Invalid block tag: 'static' for the second
Obviously I am doing it wrong. Any help would be much appreciated.
It was pointed out I should use media rather than static. But even so, I am unsure how to dynamically set the path based on the user's parameters.
remember to load you statics!!
{% load staticfiles %}
I was working on an old django-cms project and was trying to edit base.html file and no changes are reflected when I reload the page.
But if I delete all the lines in that file the django runserver refuses to start showing error
django.core.exceptions.ImproperlyConfigured: The 'js' and 'css' sekizai namespaces must be present in each template, - or a template it inherits from - defined in CMS_TEMPLATES. I can't find the namespaces in 'project/cms/home.html'.
They why isn't other changes like adding a new class not reflected in the page reload or server restart.
NOTE:
The project is working good as it is. I was trying to modify it a little bit. Changes I made in the css pages are getting reflected when I reload the page. Issue is only when I try to edit HTML pages
For base.html, you need to have {% load cms_tags sekizai_tags %} in the file. Add {% render_block "css" %} to <head></head> and {% render_block "js" %} somewhere between <body></body>. Depending on the template files that inherit from base.html, certain portions may have been overwritten. For example, if you had:
{# base.html #}
{% block content %}
<div class="example-class"></div>
{% endblock %}
But in another file say:
{# layout.html #}
{% extends "base.html" %}
{% block content %}
{% endblock %}
The div would not appear.
If however, you are talking about missing CSS files, you still need to include them in <head> for it to be displayed. render_block "css" is for django-cms css files that are included in plugins etc. I usually use a LESS or SCSS compiler to include CSS into my projects.
Hope that helps. Post more details for a better diagnosis.
I loaded a custom template tag note_extras.py in base.html.
base.html
<div id="wrap">
{% load note_extras %}
{% block content %}
{% endblock %}
</div><!--wrap-->
but it is not accessible at templates which is an extend of base.html ie::
home.html
{% extends "base.html" %}
{% block content %}
<div class="container">
{% create_tagmenu request.user.pk %}
</div>
{% endblock %}
it is working fine if i load note_extras in home.html ie:
{% extends "base.html" %}
{% load note_extras %}
....
In Django template language, you must load all needed template libraries in each of the templates.
I personally think it is a good idea because it makes templates more explicit (which is better than implicit). Ill give an example. Prior to Django 1.5, the default behavior for a url tag was to provide the view name in plaintext as well as all the needed parameters:
{% url path.to.view ... %}
There however was no way to provide the path to the view via a context variable:
{% with var='path.to.view' %}
{% url var ... %}
{% endwith %}
To solve that, starting with 1.3, you could import the future version of the url tag (which became the default in 1.5) by doing:
{% load url from future %}
{% url var ... %}
or
{% url 'path.to.view' ... %}
Now imagine that you would need to create a template which would extend from a base template which you did not create (e.g. one of django admin base templates). Then imagine that within the base template it would have {% load url from future %}. As a result, {% url path.to.view ... %} within your template would become invalid without any explicit explanation.
Of course this example does not matter anymore (starting with 1.5) however hopefully it illustrates a point that being explicit in templates is better than implicit which is why the currently implementation is the way it is.
If you want that a template tag is loaded in every template you want to do it in the init file of your app:
from django.template.loader import add_to_builtins
add_to_builtins('my_app.templatetags.note_extras')
In case anyone was wondering, add_to_builtins has been deprecated but one could still load a tag for all of the templates in the project via settings.TEMPLATES - supported for Django 1.9 onwards as described here:
https://stackoverflow.com/a/59719364/2447803
I am using Django and Crispy Forms. I can get the form to render correctly, but no CSS formatting appears. What do I need to do?
I have added
CRISPY_TEMPLATE_PACK = 'bootstrap'
to my settings.py file.
The html file is as simple as it gets:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
{% crispy form %}
{% endblock %}
What else is necessary to make it work? I understand that since the bootstrap files come bundled with crispy_forms, I don't need to copy and reference them specifically in my project's CSS path. Is this correct?
It sounds as if your django instance can't find the static files for crispy forms. If you are running the development server, have you included 'crispy_forms' in INSTALLED_APPS?
If you're running a production server you'll probably need to ensure that your STATIC_FILES paths are correct and you've run collectstatic recently.
The authors have documented the installation process here - have you followed that completely?
Its supposed to be {{ form|crispy }}, not {{ crispy form }}. You are putting the form through a filter (which is what | does in Django templates).
Also, you forgot the {% csrf_token %}.
I'm very new to jinja2 and the use of templates in general so I was wondering if there's an easy way to load an external javascript. I was thinking of using:
{% block javascript %}
<script src="myscript.js"></script>
{% endblock %}
But I can't help to ask:
Is there a way of loading this script directly from within a template directive?
You have two choices here -- the first is the way you did it -- simply add the appropriate markup into a template (or a block if you want to be able to override it in templates which extend your first template.)
The second way is to use Jinja2's include function:
{% block javascript %}
<script type="text/javascript">
{% include "myscript.js" %}
</script>
<!-- The contents of myscript.js will be loaded inside the script tag -->
{% endblock %}
The advantage of using include is that Jinja2 will process your javascript before including it -- which means you can have variables in your javascript that change depending on the state of your program.
The disadvantage of using include in this manner is the same -- your .js file will be run through Jinja2 before being sent out -- if you are not using dynamic content you will just be processing the file unnecessarily for every request -- and if you are using a javascript templating library with Jinja2 syntax then trouble is likely.
This question is quite old, but there is another way of doing it that might be interesting as well. I found it while working with Jinja2 and flask.
I used the url_for() and it works fine:
{% block javascript %}
<script src="{{ url_for('static',filename='myscript.js') }}"></script>
{% endblock %}
And I have my myscript.js in my static folder. Specified in Jinja2 environment, or by default in flask.