How to use template blocks to import css links ?

Hello there!

I’m trying to use templating but i cannot seem to understand the logic.

I have the following folder structure:

BASE_DIR/templates/_base.html
BASE_DIR/static/css/base.css
BASE_DIR/tempates/elements/css.html

I would like my BASE_DIR/templates/_base.html to use a code block located in css.html which looks in base.css

my _base.html looks like this:

<!-- templates/_base.html -->
{% extends "elements/css.html" %}
{% load static %}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{% block title %}Bookstore{% endblock title %}</title>
    {% block css %}CSS{% endblock css %}
</head>
<body>
    <div class="container">
        {% block content %}
        {% endblock content %}
    </div>
</body>
</html>

my css.html looks like this:

{% block css %}
<link rel="stylesheet" href="{% static 'css/base.css' %}">
{% endblock css %}

my base.css looks like this:

/* static/css/base.css */

h1 {
    color: #369;
    font-size: 1.2em;
    font-weight: normal;
}

Can anyone please explain me why this does not work ?

Thank you in advance!

In your _base.html you should include css.html something like this

<head>
    <meta charset="utf-8">
    <title>{% block title %}Bookstore{% endblock title %}</title>
    {% include 'elements/css.html' %}
</head>

You’re looking at the organization of templates “backwards”.

Blocks don’t work “top-down”, they work “bottom up”. A view rendering a template that extends a base template provides blocks that override the blocks defined by the base. The base template does not “pull” blocks from other templates.

Review the docs at The Django template language | Django documentation | Django

If you want to do something “top-down”, you would need to use the include tag as described in the previous answer.

1 Like

Thank you! I’ve read the docs and got it working. For both instances (include and extends).

However, if I use include I cannot use logic to check the name of the webpage for example. What I want is to effectively use css.html als a dictionary. So for example if the webpage name is ‘Home’ it should pull the codeblock {% block Home %} and of the webpage title is ‘Book’ it should pull the codeblock {% block Book %} from that file (css.html). How can I do that ? I would prefer to keep all the logic on css.html te keep my _base.html as readable as possible.

Can i pass arguments or something to load a certain code block ?

I have tried if statements in css.html but they do not see that the rendered page is Home.html.

There has to be a way to do this I hope ?

What specifically do you mean by “webpage name”? Are you talking about the url? The view? The url name? Something else?

Again however, your phrasing still reads like you’re looking at this from the wrong direction. A template does not “pull” a block. A block is supplied by the template being rendered that extends the base template.

So one option would be in your view that generates these pages that you render the appropriate block.

Another option, if these files are “well defined”, is that you use the include tag as described above, supplying the name of the file to be included in the context.

If this is not clear, then I suggest you post a minimal example here of what it is you’re trying to achieve, and then we can offer suggestions as to how it may be done.

Note: When posting code or templates here, enclose the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code (or template), then another line of ```. Do not post images of code or templates, and make sure you use the backtick (`) and not the apostrophe (').

Hi there!

Sorry for my stupid question!

I’ve found the solution, what I forgot was to actually give the page a title.

I changed my view to:

from django.views.generic import TemplateView

# Create your views here.
class home(TemplateView):

    template_name = 'home.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = 'Home'
        return contextext

And then I could put an IF statement in css.html:

{% load static %}

{% if title == "Home" %}
<link rel="stylesheet" href="{% static 'css/base.css' %}">
{% endif %}

My problem was that I thought I already gave the page a title, i did do that in the html code using a title tag, but i needed to put that name in my views aswell.

Actually, you don’t really want to do it this way, because each time you add a new view with a new title, you’re going to need to add another if block.

You’d be better off doing something like:

{% if page_css %}
<link rel="stylesheet" href="{% static page_css %}">
{% endif %}

Then, in your view:
context['page_css'] = 'css/base.css'

This allows you to add any number of named (or even unnamed) pages with custom css to be added to that page without needing to alter your template.

2 Likes

My result was only an example. But yes your comment is a great addition! I will be using that! Thanx!