Get Content of Template Block to Use in IF Statement - django

Currently I have a block setup for my page titles in my base.html. It takes a unique value from each template page, and adds the website name to the end. For example: ABOUT US - My Site Name. The "ABOUT US" is passed by template and " - My Site Name" appears on every page regardless.
However, I want to use the same base.html on my index page, but only show "My Site Name." I was hoping to use an if statement by parsing the block each template passes to look for a unique value, signifying I am on the index page.
So far my code looks like this:
<title>
{% if {% block title %}{% endblock %} == "index_pg" %}
My Site Name
{% else %}
{% block title %}{% endblock %} - My Site Name
{% endif %}
</title>
obviously this doesn't work. Anyone ideas on how I can accomplish this? Thanks.

Typically I would use two blocks, one wrapped around the other, something like this:
# base.html template
<title>
{% block title %}
{% block inner_title %}{% endblock inner_title %} - The Stock Column
{% endblock title %}
</title>
So for most of your pages, you would extend base.html, and do this:
{% block inner_title %}Page XYZ{% endblock inner_title %}
And then on your index page, you would also extend base.html, but you would then do this:
{% block title %}TEST{% endblock title %}
The resulting output from the first one would be:
<title>Page XYZ - The Stock Column</title>
And the output of the second one, from your index page, would be:
<title>TEST</title>

Related

Purpose and use of Wagtail/Django template tags of the form {% block body_class %}template-homepage{% endblock %}

In the Wagtail docs (Your first Wagtail site) we are told to create a homepage.html template as follows:
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block body_class %}template-homepage{% endblock %}
{% block content %}
{{ page.body|richtext }}
{% endblock %}
In the above code, what is that tag {% block body_class %}template-homepage{% endblock %} supposed to be doing? I can't find any mention of it in the text of the tutorial.
The tutorial goes on to instruct us to create two more templates, blog_index_page and blog_page templates, both of which are to contain {% block body_class %} tags. Again, I can find no mention at all of those lines in the docs, let alone an explanation of how they might be used/modified.
A search for "body_class" in the docs finds only the three code blocks just mentioned, and one other mention: in the version 1.2 release notes, under 'What's new — Minor features' the notation: "Simplified body_class in default homepage template."
Any insight as to what I'm supposed to do with these tags? What special meaning or function, if any, does the text enclosed within the tags in those tutorial templates (for example, "template-homepage" in the code above)?
In base.html you have a part that looks like <body class="{% block body_class %}{% endblock %}">. What you add into that block in your templates will be rendered into that section.
For example, lets say on your design your <body> contains a bottom margin, however on a particular template you don't want the margin there and create a css class .remove-margin { margin-bottom: 0 };
You can then add {% block body_class %}remove-margin{% endblock %} into your template and it will apply the class to the <body> tag without you having to modify the base.html template for that one use case.
You are also able to create your own ones. In base.html add a custom block such as {% block my_custom_block %}{% endblock %} and then in your template include some text or html inside that my_custom_block and it will be rendered wherever you've place that part in the base template.
Just to help clarify the correct answers above with a picture as I was also wondering what that block tag was doing, here is the rendered html. As per answer above, this is standard Django.
In the base.html you have this line:
<body class="{% block body_class %}{% endblock %}">
The substitution happens in the home_page.html template:
{% block body_class %}template-homepage{% endblock %}
And it renders as per below screenshot:
<body class="template-homepage">

Django-CMS show_placeholder not working as expected

I'm working on a site where the footer content is shared across all pages. What is the best way to do in Django-CMS?
I tried using show_placeholder tag, but it somehow didn't work. A little more details on what I did:
First, I have a {% placeholder footer_info %} in base.html. Then I add a page called "Home" (template homepage.html) in django admin and put some text under footer_info as a Text plugin. As the accepted answer in this question suggested (http://stackoverflow.com/questions/3616745/how-to-render-django-cms-plugin-in-every-page),
I add
{% placeholder footer_info or %}
{% show_placeholder footer_info "Home" %}
{% endplaceholder %}
In a template called services.html which I used as the template for page Services.
However, the content in home page is not showing up in services page. I also tried adding an id home_cms_page to home page in the Advanced option area, so that I can reference it in services.html like this:
{% placeholder footer_info or %}
{% show_placeholder footer_info "home_cms_page" %}
{% endplaceholder %}
But the content is still not showing up.
Could anyone tell me what I am doing wrong? And is this the best way of getting some content from a page across all other pages (and I have to add show_placeholder in every other page)?
Thank you
EDIT:
It is not a multilingual site. I commented out 'cms.middleware.multilingual.MultilingualURLMiddleware', because the only language I use on the site is English.
I have this in my base.html:
{% load cms_tags sekizai_tags %}
<!-- all the rest of the HTML markups -->
<div class="span4">
{% placeholder footer_info %}
</div>
Then I added a page in the admin called "Home" with a Text plugin and an id of "home_cms_page".
The following is in my services.html:
{% extends "base.html" %}
{% load cms_tags %}
{% block base_content %}
{% placeholder services_info %}
{% endblock base_content %}
{% block page_content %}
Home page
{% endblock page_content %}
{% placeholder "footer_info" or %}
{% show_placeholder "footer_info" "home_cms_page" %}
{% endplaceholder %}
Read the documentation:
If you know the exact page you are referring to, it is a good idea to
use a reverse_id (a string used to uniquely name a page) rather than a
hard-coded numeric ID in your template. For example, you might have a
help page that you want to link to or display parts of on all pages.
To do this, you would first open the help page in the admin interface
and enter an ID (such as help) under the ‘Advanced’ tab of the form.
Then you could use that reverse_id with the appropriate templatetags:
{% show_placeholder "right-column" "help" %}
I added "index" in the advanced options of the index page, and added {% show_placeholder "banner" "index" %} in the base template. It all works.

Django: How to include a block site wide?

Apologies, this is pretty basic. I have abstracted my static html navigation bar to a block so that it can be dynamically rendered from a model. I have created a new block marker in base.html with the following syntax
{% block navigation %}{% endblock %}
How can I ensure this is rendered on every page? Do I need to create some sort of middle layer for this? Everything I have done so far has simply used the primary block.
EDIT Sunday, 14 August 2011 11:25 AM
I didn't explain this very well. The content of navigation block is
{% extends 'base.html' %}
{% block navigation %}
<nav>
<ul>
{% for item in items %}
<li>{{ item.name }}</li>
{% endfor %}
</ul>
</nav>
{% endblock %}
I want to render this on every page without having to go through child templates of base.html individually and add it to them, if that is possible.
You have got static navigation bar, so you can just write code in your base.html page and then use it with {% extends 'base.html' %} tag on every new page. Your markup will be in every page. Also, if you use only extends tag in your child page and then render it - you will see base.html without any edition.
If you have got code, which need to appear on few pages, but not on everyone - create 'includes' directory, save code there and extend your base template with {% include %} tag. It won't avoid repating, but make your code shorter.
And last thing you'll need in future, maybe with dynamic code - caching. With {% cache %} tag you can cache block for some time.
Your block is not doing anything here, but if you want something to appear in all the templates, you have to define it in a base template (base.html) and make the others extend from it:
base.html
Yor menu and the stuff you want to appear everywhere
{% block content %}{% endblock %}
Another template
{% extends "base.html" %}
{% block content %}
The actual content of the page
{% endblock %}
{% block FOO %}{% endblock %} reserves a space to be overwritten in sub templates.
{% include "foo.html" %} pulls content from another file into the current file.
To get {% block navigation %}{% endblock %} to display on every page, you need to add content
{% block navigation %}SHOW ME{% endblock %}

Is there a way to make a block optional in Django template

In Django's templates system, if I have a block that I want to make optional using an if statement, how do I do it?
I was trying this:
{% if val %}{% block title %}Archive {{ foo }}{% endblock %}{% endif %}
But that doesn't work. Is there a way to do that, so that for a given value (in this case Null) the block isn't issued and the base template uses the original values?
Edit:
Let me be a little more specific, so that it is easier to answer.
I have a page with 10 entries per page. The user can then go on to the next page and see the next ten items. For each further page they go, past the first, I would like to have the title tag say something like "Archive 1" or "Archive 10" but if they get back to the original page, it is no longer archive, and it should just go to the original site title already given in the base templates.
I ran into a similar issue with a project I'm working on. Here's how I resolved it using {{ block.super }} to pull the default value from the parent block:
My parent template contains:
{% block title %}Default Title{% endblock %}
My child template contains:
{% block title %}
{% if new_title %}{{ new_title }}{% else %}{{ block.super }}{% endif %}
{% endblock %}
*Note: You may want to wrap the code in {% spaceless %}{% endspaceless %} if you plan to use the result in an HTML title tag.
(It looks like Jordan Reiter posted the same solution in the comments of the original question a bit before my response.)
As far as I understand blocks are placeholders to be "overridden" in the child templates. They have to be defined at "compile time" and not at "run time".
As for your specific problem why not modify the title based on the page number (assuming you use pagination)? Something like this:
{% block title %}
{% ifequal page 1 %}Current{% else %}Archive {{ page }}{% endifequal %}
{% endblock %}
I would only have to add to the good answers above that depending on the Django version sometimes the {{ block.super }} puts the content from the master twice, this seems to happen in the most recent versions of Django.
I am using Django 1.8 and whenever i put the {{ block.super }} it started to behave in that way just as an addition to the Jamie answer i can say that in the base template you can put the content you wish
{% block title %} Default Title {% endblock %}
And then in the child if you want the footer to be inherited and displayed just do not do anything it will be. But if you do not want that block to be displayed then put the tag in the child with empty content just like this:
{% block title %}
{% endblock %}
Then it will be hidden once it is rendered also you can overwrite the content on it if you wish.

How do I list items in my Django models?

Am working with django Publisher example, I want to list all the publishers in the db via my list_publisher.html template, my template looks like;
{% extends "admin/base_site.html" %}
{% block title %}List of books by publisher{% endblock %}
{% block content %}
<div id="content-main">
<h1>List of publisher:</h1>
{%regroup publisher by name as pub_list %}
{% for pub in pub_list %}
<li>{{ pub.name }}</li>
{% endfor %}
</div>
{% endblock %}
but when I run "http://127.0.0.1:8000/list_publisher/" the template just prints the page title with no error! What am I doing wrong?
A few suggestions:
check that your base_site.html does define a {% block content %}{% endblock %} section to be refine by your my list_publisher.html
check the cardinality of your list: {%regroup publisher by name as pub_list %}{{ pub_list|length }}. That should at least display the length of your list. If is is '0'... you know why it does not display anything
check that your list is indeed sorted by name before using regroup, or use a {% regroup publisher|dictsort:"name" by name as pub_list %} to be sure
If the length is '0', you have to make sure publisher is defined (has been initialized from the database), and sorted appropriately.
In other word, do you see anywhere (in your template or in the defined templates):
publisher = Publisher.objects.all().order_by("name")
?
(again, the order by name is important, to ensure your regroup tag works properly)
Good answer by VonC.
A quick and dirty way to look at pub_list is to stick [{{pub_list}}] in your template. I put it in square brackets in case it's empty. BTW, you may get something that looks like [,,,,,]. This is because object references are wrapped in <> and your browser is going WTF? Just do a View Source and you'll see the full result.