Sammaye
Sammaye

Reputation: 43884

Django how to dynamically add js and CSS in sub templates?

I am new to Django.

I have a basic template set up where I have base.html using {% block body %}{% endblock %} to include a sub template of index.html and test.html where they have {% extends 'base.html' %} at the top.

The base.html template includes Bootstrap. It is where the CSS and JS are included. index.html needs to include select2 but test.html does not.

I could use blocks here to solve my problem (adding CSS and JS block to base.html) but I see that as getting very messy very quickly.

Is there anyway I can use assets in Django to create a select2 asset and have that called in the sub template to register the needed JS and CSS with the parent template?

All I see is compression and numerous searches have, so far, come up empty.

Upvotes: 2

Views: 2154

Answers (2)

pythad
pythad

Reputation: 4267

It okay to add 2 more blocks in your base.html:

<some css>
{% block additional_css %}
{% endblock additional_css %}

...

<some js>
{% block additional_js %}
{% endblock additional_js %}

and the override them in any page extended from base.html:

{% extends "base.html" %}

{% block additional_css %}
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap-datetimepicker.min.css' %}">
{% endblock additional_css %}

...

{% block additional_js %}
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.0/moment.min.js"></script>
    <script type="text/javascript" src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
{% endblock additional_js %}

That is a good practice because in this case the scripts will load in the very end and if some of your added script require for example JQuery, you won't face any problems.

It doesn't make the code messy, it's flat and easy to explain. It's better to think how not to make JS messy, and as you pointed, there are several ways to do this, on of them is to compress all the JS.

Upvotes: 5

Sayse
Sayse

Reputation: 43300

There are a few options that I can think of

The first is the ugly way that involves an {% if include_my_js_please %} in the base.html that is ignored if the context variable isn't included and for obvious reasons, arguments would be had if this made its way into our production code

The second is the way that you say can get very messy but its the way we do it and works very well for us, we have an {% extended_head %} and {% extended_footer %} in the base.html and as you'd expect we use this sparingly when required. Although we are very careful about what is included into this.

The third way is to just include everything in the base.html and only worry about it when it actually becomes a problem (I can see both the pros and con's of this)

and the fourth and final way I can think of is to make use of the Forms Media class

Django allows you to associate different files – like stylesheets and scripts – with the forms and widgets that require those assets. For example, if you want to use a calendar to render DateFields, you can define a custom Calendar widget. This widget can then be associated with the CSS and JavaScript that is required to render the calendar. When the Calendar widget is used on a form, Django is able to identify the CSS and JavaScript files that are required, and provide the list of file names in a form suitable for easy inclusion on your Web page.

Obviously this doesn't work in all use cases

Upvotes: 1

Related Questions