So, originally I was using {% include}, and that was working fine, then I wanted to try out {% block}, and its not showing the nav.html content anymore. I've been trying to figure this out for about 15 minutes now, and it looks like its the same as I've seen everyone else do it. This is my code, what am i doing wrong?
<html>
<body>
It is now {{ current_date }}
{% block content %} {% endblock %}
</body>
</html>
this block of code being the current_datetime file.
{% extends 'current_datetime.html' %}
{% block content %} <h1>this is a test</h1> {% endblock %}
and this block of code being nav.html. I'm 100% sure that I'm naming the extends file correctly since I copied the name from the views file.
It seems you got stuck with you inheritance and how things have to work.
extends is used for inheritance. But you are trying to include one code snippet into another and that's the work for include.
You are not rendering nav.html. You are rendering current_datetime.html as you mention in the comments, that's why block works not as you expected. The code is correct, but your login is a little bit incorrect. Basically I want to point out that nav mustn't extend current_datetime.html. It has to be included in it.
Related
I'm creating a blog and have numerous pages that will display a list of articles. So, to avoid repeating that code, I'm trying to place it within a parent template that I can extend where needed.
The problem is I'll need a different for loop to display the article lists on each page/view. I figure the easiest approach would be to simply create blocks where I want the loop to start and close within the parent, then alter accordingly within each child.
However, Django doesn't allow you to close blocks that have an open for loop, despite closing the loop later in a different block.
My initial approach, in the parent, article_list.html:
<div class="row">
{% block loop_start %}
{% endblock loop_start %}
<div class="col-xs-12 col-sm-4">
<div class="card">
<a class="img-card">
<img class="img-fluid"src="../../static/{{ post.featured_image }}" />
</a>.... etc
I know I have to fix my src code.
Extends to child as:
{% block loop_start %}
{% for post in recent_articles %}
{% endblock loop_start %}
However, that doesn't work as noted above.
I've also tried wrapping the entire code for the article list in a block, extending it and performing the following within the child:
{% for post in recent_articles %}
{% block.super article_list %}
{% endblock article_list %}
{% endfor %}
That doesn't work either. Again, producing the same error as a block is closing before the loop ends. I've also tried closing the loop in the parent which doesn't work either.
Is there an easier way of going about this that I'm missing? I could pass the same variable to each view then implement the loop in the parent, but that seems janky and limiting.
What's best practice here?
You should take a look at a 'base.html' file. Take a look at this web-page: https://ultimatedjango.com/learn-django/lessons/create-the-project-base-template/
This will allow you to do {% extends 'base.html' %} all of which Django will handle.
I work in SublimeText 3. When writing Django templates I have a mixture of html and functions.
I like to indent my code so that block, if and other such statements are indented. For example:
Manual formatting
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
{% endblock %}
However, when I run any autoformatter HTML-CSS-JS-Prettify it ignores these brackets and treats them as text:
After formatting
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
{% endblock %}
Although plugins like Djaneiro give great tag highlighting, I haven't been able to find a way to get SublimeText to treat these as tags.
Has anyone had any luck?
This is a late answer, but I would like to mention a Django template formatter that I've created myself: DjHTML. You can install it using pip install djhtml.
Let's say template.html contains the following:
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
<script>
$(function() {
console.log("Password changed!");
});
</script>
{% endblock %}
Then running djhtml template.html will give the following output:
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
<script>
$(function() {
console.log("Password changed!");
});
</script>
{% endblock %}
It's easiest to use DjHTML as a pre-commit hook, so that templates will be automatically indented when you run git commit. Instructions on how to configure pre-commit can be found in the README.
There isn't one for sublime text as far as I can tell. I have no source I can quote on this, but I have basically searched nothing came up.
This discussion is by any means old, but active. I found this really old ticket about formatting standards for Django and it has been updated 9 Months ago to basically say they are "in favour of standards" and the proposed formatting for templates would be:
<ul>
{% for x in y %}
<li>{{ x }}</li>
{% endfor %}
</ul>
They also made a place happen that holds information about formatting guidelines in Django.
You might find this discussion interesting as well. It's old too, but it highlights the confusion about formatting in Django and the DIY solutions people came up with to cope.
In trying to keep with DRY, I'm setting up my Django project HTML files now. I have successfully extracted most repeated information to my base.html page. On most (but not all) of my pages, my content is displayed within a general 'panel' which is basically just a container set-up with styling, but it's got a few div-tags to it so it looks a bit ugly and I'm having to type out the exact same code out several times on each page.
My idea was to extract this to a 'panel.html' then call it whenever I need it, for example some pages might just have one 'panel' whereas my dashboard (it's an administrative site) will have maybe 15+. So it seemed a better idea and cleaner to not have to type out all this code each time I need to set up a 'panel'.
My ideal page would look something like..
{% extends 'base.html' %}
{% block content %}
{% extends 'panel.html' %}
{% block panel_content %}
Panel content...
{% endblock panel_content %}
{% extends 'panel.html' %}
{% block panel_content %}
Second panel content
{% endblock panel_content %}
{% endblock content %}
I know I can't use extends multiple times but I'm using it just as an example for what it is I'm trying to achieve.
I am going to potentially have hundreds of these identical 'panels' across my site but each containing different content and it would be so much cleaner if I could just have one stored somewhere in a HTML file and call it however many times I need.
Is there a way to do this?
You can use include
{% include "panel.html" %}
I should mention that too many include statements create a performance issue.
I'm trying to extend the password reset form like so:
<!-- templates/registration/password_reset_form.html -->
{% extends registration/password_reset_form.html %}
{% block content %}
<h1> hello </h1>
{% endblock %}
As far as I can tell, this should take the template from /usr/local/lib/python3.7/site-packages/django/contrib/admin/templates/registration/password_reset_template.html (which exists, I checked) and replace the block content with the one at templates/registration/password_reset_form.html.
But this isn't happening. In fact, there is no change, nor is there an error. What am I doing wrong?
UPDATE:
I tried deliberately introducing a syntax error into the template name, and no error was issued. It leads me to believe that the template file is not being read at all. According to the django docs, registration/password_reset_form.html is the path to the default template. Why am I not able to at least introduce an error?
Put quotes around path, like this:
{% extends "registration/password_reset_form.html" %}
{% block content %}
<h1> hello </h1>
{% endblock %}
Also if your own template file didn't read at all, make sure that you have your app in INSTALLED_APPS in settings.py and TEMPLATES has 'APP_DIRS': True or DIRS set properly.
Why don't you just use the full path to the html file then?
/usr/local/lib/python3.7/site-packages/django/contrib/admin/templates/registration/password_reset_template.html
Right now you are extending the same file you are working on
The template inheritance page on the django site doesn't really solve my problem (Django 1.2).
My base page looks like:
...
<div class="grid_12" id="content">
{% block content %}{% endblock %}
</div>
...
{% block javascript %}{% endblock %}
I have another template that defines content for these:
{% block content %}
animated sidebar
{% endblock %}
...
{% block javascript %}
alert('hello');
{% endblock %}
This is something like an animated sidebar, so I don't want to extend the base template since it's auxiliary to the main content of the page. If I just use "include", the entire thing is put where the "include" tag is placed - as a result the javascript doesn't run because it's included before one of its dependencies.
What's the best way to solve this?
EDIT
Sorry, I didn't make myself clear.
I have my content pages which render a template that extends "base.html". In "base.html" I want to include a sidebar template that needs to append blocks in "base.html". So I've tried just putting include "sidebar.html" into "base.html", but it just inserts the whole thing where the "include" tag is. What I want it to do is append the blocks in "base.html", which may themselves have been populated by "page.html".
Maybe it's important to say that "sidebar.html" is entirely static - i.e. there's no callable associated with it. So perhaps this question should really be "How can I include a static template into base.html so it will append to blocks in base.html regardless of the output of the actual view that processes the request?"
I think you mean you want to append to a block? You can put {{ block.super }} where you want the inherited content to go. e.g.:
{% block javascript %}
{{ block.super }}
alert('hello');
{% endblock %}
You should only use {% block foo %} tags to extend blocks in a base template, so I'm not clear what you mean when you say you don't want to extend it.
The code, as you've entered it, should render to
...
<div class="grid_12" id="content">
animated sidebar
</div>
...
alert(hello)
Unless you want to append the content (as in Matt's answer) it's not clear what you want to happen.
You shoud be using something like jQuery to trigger execution only after the page is fully loaded. Include jQuery library in the document header and then somewhere:
$(document).ready(function() {
//your code goes here
});