Is there a way to construct pages with components - django

I am familiar with the concept of extends and include with django templates.
However, I am trying to build up pages with components (which relates more to the "include" approach). Unfortunately, some elements on a page should be added in the header of the page (e.g. stylesheets) and some should be added at the end of the page (e.g. scripts).
Is there a way to declare blocks (e.g. {% block extraheaders %}<link...>{% endblock %}) in the included files so they are placed in the correct region of the page?

Perhaps you are looking for the following setup:
<!-- base.html -->
<html>
<head>
{% block css %}
<link href="/css/bootstrap.css">
<link href="/css/base.css">
{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
{% block js %}
<script src="/js/jquery.js"></script>
<script src="/js/bootstrap.js"></script>
<script src="/js/base.js"></script>
{% endblock %}
</body>
</html>
{% extends base %}
{% block css %}
{{ block.super }}
<link href="/css/home-page.css" />
{% endblock %}
{% block content %}
<h1>Hello, World!</h1>
{% endblock %}
{% block js %}
{{ block.super }}
<link href="/js/home-page.js" />
{% endblock %}
...with the main point being that we can use {{ block.super }} to place specific resources into a parent template's blocks through inheritance.

Related

Unable to load multiple content blocks in Django 4.0 using TailwindCSS

Folder Structure:
mysite
-theme
--templates
---main_base.html
---theme_footer.html
---theme_menu.html
-home
--templates
---home
----main.html
main.html:
{% extends "main_base.html" %}
{% block content %}
blah blah
{% end content %}
main_base.html:
{% load static tailwind_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
{% tailwind_css %}
</head>
<body class="bg-blue-100">
<nav>
{% block navbarn %}
{% endblock %}
</nav>
{% block content %}
{% endblock %}
<footer>
{% block footer %}
{% endblock %}
</footer>
</body>
</html>
theme_menu.html:
{% extends "main_base.html" %}
{% block navbarn %}
home
{% endblock %}
theme_footer.html
{% extends "main_base.html" %}
{% block footer %}
<h1>this is a footer</h1>
{% endblock %}
So I was able to setup Django with Tailwind following the instructions on the plugin page. But I can't get the base theme to show multiple blocks. It doesn't show the menu nor the footer, just the base html template with content from main.html. Can't get it to work!
If anyone else is running into this issue, you can't use multiple extends. You instead, include it in your base.
For me, I removed the {% extends %} tags from the ancillary pages, and then included them in my theme_base.html like:{% include 'theme_footer.html' %}

Django how to use blocks in templates

Basicly my django project consists of the templates with html.
I would like to fill the context of the site using blocks.
My problem is that I would like to send the block to sidebar and the base part of the page from application's .html files.
Templates:
sidebar.html
footer.html
header.html
base.html
In my base.html I use:
{% include 'partials/_sidebar.html' %}
{% block content %}{% endblock %}
in my sidebar.html I use
{% block sidebar %}{% endblock %}
and in my Application index.html i try to use:
{% extends 'base.html' %}
{% load static %}
{% block content %}
<h1>Home Page</h1>
{% endblock %}
{% block sidebar %}
<div class="bg-white py-2 collapse-inner rounded"></div>
<h6 class="collapse-header">Custom Components:</h6>
<a class="collapse-item" href="{% url 'veggies' %}">veggies</a>
<a class="collapse-item" href="{% url 'fruits' %}">fruits</a>
</div>
{% endblock %}
But it is obviously not working.
The starting page triggers app/index.html with a view.
How to workaround such a problem?
[i cant add post][1]
[1]: https://i.stack.imgur.com/FV3Co.png
Hopefully I can demonstrate how you use blocks by sharing some example templates with you.
Starting with a base template, that generally has the most content and contains the basic markup;
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>{% block title %}{% endblock title %}</title>
<meta name="description" content="{% block meta_description %}{% endblock meta_description %}">
<meta name="viewport" content="width=device-width,initial-scale=1">
{% block styles %}{% endblock %}
{% block scripts %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.2.1/js.cookie.min.js"></script>
<script type="text/javascript" src="https://kit.fontawesome.com/c3c34cb042.js" crossorigin="anonymous"></script>
{% endblock %}
{% block head_extras %}{% endblock %}
</head>
<body>
{% block header %}{% endblock header %}
{% block content %}{% endblock content %}
{% block footer %}{% endblock footer %}
{% block footer_scripts %}
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
{% endblock %}
</body>
</html>
Then a page for content would extend that and you'd include in this template the blocks you want to add content to;
{% extends "base.html" %}
{% load static %}
{% block title %}Content Page{% endblock title %}
{% block content %}
<section class="">
<div class="container-fluid container-xl">
<div class="content-section">
<h1 class="content-section__heading-1">Content Page</h1>
<p>Hello World!</p>
</div>
</div>
</section>
{% endblock content %}
That'd be a really simple setup. But as you've said, you might also use the {% include %} tag.
What that does is inject the content of the included template into the template at the point you use the tag.
So in a template with a sidebar, that might look like;
{% extends "base.html" %}
{% load static %}
{% block title %}Sidebar Content Page{% endblock title %}
{% block content %}
<section class="">
<div class="container-fluid container-xl">
<div class="content-section">
<h1 class="content-section__heading-1">Content Page</h1>
<p>Hello World!</p>
</div>
{% include 'partials/_sidebar.html' %}
</div>
</section>
{% endblock content %}

Multiple Levels Of Inheritance Using Django Templates

I'm creating a Django project, where I want to use multiple levels of inheritance in my templates. E.g I want to do something like this:
project_base.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
<link href="{% static "css/bootstrap.min.css" %}" rel="stylesheet">
</head>
<body>
<div id="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
Then in app_base.html I extend this.
{% extends "project/project_base.html" %}
{% block title %}Generic Title{% endblock %}
{% block content %}
<img src="/dir/sub_dir/image.jpg">
{% block app_content %}
{% endblock %}
{% endblock %}
Finally I have my actual template
{% extends app_base.html %}
{% block title %}Specific Title{% endblock %}
{% block app_content %}
{% for obj in objects %}
{{ obj.name }}
{% endfor %}
{% endblock %}
The problem that I have is that when I go to load that page I see a single heading from an entirely unrelated template, and not my list of hyperlinks. What's the correct/best way to have multiple levels of inheritance for my template files?

External JS in Django apps best practice

I have two pages that extends a base template. Each page has their own external js which i need to load. For the time being, i have put both of them before closing body tag in the base which means that both JS are loaded on both pages. How is it possible to load specific JS for specific page?
Yes you can do it:
1. base.html
<html>
<head>
<title>Foobar</title>
</head>
<body>
{% block content %}{% endblock %}
{% block js %}{% endblock %}
</body>
</html>
2. yourpage.html
{% extends "base.html" %}
{% load staticfiles %}
{% block content %}
<p>your content!</p>
{% endblock %}
{% block js %}
<script src="{% static 'js/foobar.js' %}"></script>
{% endblock %}

CSS works only in one of three templates when extended from the same template

Okay I've got my base template and I extended it in my three other templates and it only works in one of them. I find this really strange. I'm not sure what code would relevant here so please comment what code I should post.
base:
<link rel="stylesheet" type="text/css" href="static/default.css" media="screen"/>
<title>{% block title %}Marijus Merkevicius{% endblock %}</title>
<div class="holder">{% block content %}{% endblock %}
index(css works for this template):
{% extends "base.html" %}
{% block title %}Marijus Merkevicius{% endblock %}
{% block content %}
{% for entry in entries %}
<h1><a href="{{ entry.category.slug }}/{{ entry.slug }}/"</h1>
<p>{{ entry.text|safe|escape }}</p>
{% endfor %}
{% endblock %}
detail(css doesnt work):
{% extends "base.html" %}
{% block title %}{{ entry.title }} | Marijus Merkevicius{% endblock %}
{% block content %}
<h1>{{ entry.title }}</h1>
<p>{{ entry.text|safe|escape }}</p>
{% endblock %}
<link rel="stylesheet" type="text/css" href="static/default.css" media="screen"/>
You're using a relative link. That means depending on what URL rendered this page, the URL for your CSS is changing too.
Since you're using an index template and detail template, I'm guessing the two have a different root url (typical pattern is that the detail page is a "subdirectory" of the index).
Point directly to your css file instead: /static/default.css if your css file is at example.com/static/default.css