Content: Blog

Tutorials

How to Build a Website and Blog with django CMS, Without Knowing Python/Django - Pt. 5

Angelo Dini

Feb. 27, 2016

Index


Part 5: Fine-tuning the News & Blog Addon

We now have a clean, functional blog, but you might have noticed that our current implementation does not reflect the theme, exactly. Let’s complete this last part, together. 

To do this, we’ll need to:

  • Set up our Home to display the four latest blog entries
  • Configure the blog detail view to display an attractive header

Open your website, navigate to your “Home” page in the dashboard and make sure you are in Edit View by clicking on “Edit page.” 

Next, click “Page.” Then, click “Page settings…,” rename the Title to “About” and adapt the Slug to “about.” Hit “Save” and finalize your changes by clicking “Publish changes.”

After publishing, click on “Page,” select “Create Page” and choose “Duplicate this Page.” Then, set the title to “Home.”

Press “Save” again, switch to Edit View by clicking “Edit page,” and then click “Publish page now.”

Finally, make sure that the home page is positioned as the first page in your menu. You can do this by clicking on the first menu in the toolbar next to the django CMS logo (with the name of your Project), then “Pages” and dragging and dropping “Home” to the first spot.

The navigation will be updated immediately and won’t need publishing.

Make sure that you are in Edit Mode on the home page, then click on “Structure” and remove all plugins within the “Content” placeholder by selecting “Empty all”, so we can add new plugins:

Click on the “+” icon in the “Content” area and search for “Latest Articles.” Add this plugin and choose to display the four latest articles in the options:

Hit "Save".

The plugin will now pull your four most recent blog articles and display them, automatically. Now publish your changes by clicking “Publish page changes.”

Applications vs. Plugins
Applications such as “Aldryn News & Blog” define various plugins that can be used across your website. These plugins reuse the data defined in your blog articles and are used to display information such as latest articles, authors or defined tags. Different applications provide different plugins.

Before we move on, open the Divio App and make sure your project is synced.

Now go back to your website switch back to edit-mode and click the “Content” button in the upper-right of the toolbar. You might notice that the spacing is incorrect or that we don’t have an “Older Posts ->” link.

To solve this, head back to your templates and open "latest_articles.html" inside “/templates/aldryn_newsblog/plugins/” in your editor. It should look like this:

{% load i18n %}

{% for article in article_list %}
    {% include "aldryn_newsblog/includes/article.html" with namespace=instance.app_config.namespace %}
{% empty %}
    <p>{% trans "No items available" %}</p>
{% endfor %}

This template currently renders our latest articles by looping through four articles and passing the information to article.html.

We need to change this template a bit to be in sync with our theme. Now open “index.html” from the downloaded theme and look for this code:

<div class="post-preview">
    <a href="post.html">
        <h2 class="post-title">
            Man must explore, and this is exploration at its greatest
        </h2>
        <h3 class="post-subtitle">
            Problems look mighty small from 150 miles up
        </h3>
    </a>
    <p class="post-meta">Posted by <a href="#">Start Bootstrap</a> on September 24, 2014</p>
</div>
<hr>

...

<!-- Pager -->
<ul class="pager">
    <li class="next">
        <a href="#">Older Posts &rarr;</a>
    </li>
</ul>

To get our template working, head back to “latest_articles.html” and replace:

{% include "aldryn_newsblog/includes/article.html" with namespace=instance.app_config.namespace %}

with the following code:

<div class="post-preview">
    {% include "aldryn_newsblog/includes/article.html" with namespace=instance.app_config.namespace %}
</div>

Add the following code at the end of the file:

<!-- Pager -->
<ul class="pager">
    <li class="next">
        <a href="#">Older Posts &rarr;</a>
    </li>
</ul>

Save the template and go back to your browser.

Look at the home page and compare it with the “index.html” file of the Clean Blog theme. The spaces are now correct. 

Now open "article.html" inside “templates/aldryn_newsblog/includes” and adapt the following lines:

From To
{% render_model article "title" %}
{% render_model article "title" "" "" "striptags" %}
{% render_model article "lead_in" "" "" "truncatewords:'20'" %}
{% render_model article "lead_in" "" "" "truncatewords:'20'|striptags" %}
{% render_model article "lead_in" %}
{% render_model article "lead_in" "" "" "striptags" %}
{{ article.publishing_date|date }}
{{ article.publishing_date|date:"F d, Y" }}
  • striptags will remove all defined HTML markup to render titles correctly, since they are already inside an <h2> or <h3>
  • date:"F d, Y" formats our date to be aligned with the theme

Save the file "article.html".

Configuring Date and Time
Django provides extensive configuration for date and time. In our “article.html” example, we used “date:"F d, Y"” to get the correct format for our article items “Posted by Start Bootstrap on February 2, 2016.” When just using “date” as a filter, Django will use the default configuration in your “settings.py” file.

The last thing left to do is change the “Older Posts” link. Head back to "latest_articles.html" inside “templates/aldryn_newsblog/plugins/” and replace the first line in "latest_articles.html" with:

{% load i18n apphooks_config_tags %}

then look for the following code:

<a href="#">Older Posts &rarr;</a>

and replace it with:

<a href="{% namespace_url "article-list" namespace=instance.app_config.namespace default='' %}">Older Posts &rarr;</a>

Save the file. The result should look like this:

Remaining Plugins
We provide a Bootstrap 3 template set when choosing “Aldryn Bootstrap3 Boilerplate” during project creation. You can view an example of this in the Aldryn News & Blog addon inside the repository. Other addons provide similar templates, however, the structure is always “/app_name/boilerplates/ boilerplate_name.” If no boilerplate folder is found, the “/app_name/templates” is used.

Blog Detail Header

Now let’s head over to the blog detail page and adapt the header to match our theme, as seen here:

We need to move the title, sub-head and date to the header, all while displaying an attractive, custom background image. 

To do this, open “/templates/base.html” where our header is defined, and look for:

{% placeholder header or %}    
<!-- Set your background image for this header on the line below. -->
<header class="intro-header" style="background-image: url({% static 'img/about-bg.jpg' %})">
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <div class="page-heading">
                    <h1>{% page_attribute "page_title" %}</h1>
                </div>
            </div>
        </div>
    </div>
</header>
{% endplaceholder %}

Then, insert {% block header %} above the code and {% endblock %} at the very end of the code.

This should be your result:

{% block header %}
    {% placeholder header or %} 
    <!-- Set your background image for this header on the line below. -->
    <header class="intro-header" style="background-image: url({% static 'img/about-bg.jpg' %})">
        <div class="container">
            <div class="row">
                <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                    <div class="page-heading">
                        <h1>{% page_attribute "page_title" %}</h1>
                    </div>
                </div>
            </div>
        </div>
    </header>
    {% endplaceholder %}
{% endblock %}

This allows us to overwrite our header in the Blog Detail view. Open article_detail.html inside “/templates/aldryn_newsblog/” and in between:

{% block title %}
    {{ article.title }} - {{ block.super }}
{% endblock %}

and

{% block newsblog_content %}
    {% include "aldryn_newsblog/includes/article.html" with detail_view="true" %}
...

add the following code:

{% block header %}
    <!-- Set your background image for this header on the line below. -->
    <header class="intro-header" style="background-image: url({% static 'img/about-bg.jpg' %})">
        <div class="container">
            <div class="row">
                <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                    <div class="page-heading">
                        <h1>{% page_attribute "page_title" %}</h1>
                    </div>
                </div>
            </div>
        </div>
    </header>
{% endblock %}

This is almost identical to the code we added in “/templates/base.html” – just without the placeholder declaration.

In the same file, replace the second line:

{% load i18n cms_tags apphooks_config_tags %}

with the following code:

{% load i18n staticfiles cms_tags apphooks_config_tags %}

Now replace:

<div class="page-heading">
    <h1>{% page_attribute "page_title" %}</h1>
</div>

with the following code:

<div class="post-heading">
    <h1>{% render_model article "title" "" "" "striptags" %}</h1>
    <h2 class="subheading">{% render_model article "lead_in" "" "" "striptags" %}</h2>
    <span class="meta">
        Posted by
        <a href="{% namespace_url 'article-detail' article.slug namespace=namespace default='' %}">
            {{ article.author.name }}
        </a>
        on {{ article.publishing_date|date:"F d, Y" }}
    </span>
</div>

Hit “Save” and preview your result.

Don’t Repeat Yourself (DRY)
Django’s template languages provide multiple mechanisms to build your site “DRY” (Don’t Repeat Yourself) so you don’t have to repeat the same actions over and over. 
In this case, we recommend adding the content within <span class=”meta”> … </span> into a separate file in date.html inside “templates/aldryn_newsblog/includes/” and replacing the content with {% include "aldryn_newsblog/includes/date.html" %} inside your “article_detail.html” and “article.html” files to create one easily maintainable source for the date.

When doing this, don’t forget to add {% load apphooks_config_tags %} to the top of the file, otherwise you’ll receive an error that template loaders are missing.

Our title is currently displayed twice. Open article.html inside “templates/aldryn_newsblog/includes” and add {% if not detail_view %} before <div class="post-preview"> and {% endif %}  after the <hr>. 

The result should look like this:

{% if not detail_view %}
    <div class="post-preview">
        ...
    </div>
    <hr>
{% endif %}

Save article.html.

Our last missing piece is the image. For this, we need to go to an article detail page.

Click on a blog entry in your latest articles under the page where you added the "Latest articles" plugin. Next, click “News & Blog” and then “Edit this Article” in the upper toolbar. Look for the “Featured Image” section inside the opened model. It will look like this:

We downloaded an example image from “Nasa Image of the Day” that is free to use. Download your own and drag and drop that image into the drop area. 

When choosing your own image, make sure it has dimensions similar to “/static/img/post-big.jpg,” which is about 1200 x 400 pixels. The larger the image, the better the quality.

Hit “Save” and open article_detail.html inside “/templates/aldryn_newsblog/.” Replace the second line to include all required loaders:

{% load i18n staticfiles cms_tags apphooks_config_tags %}

with the following code:

{% load i18n staticfiles thumbnail cms_tags apphooks_config_tags %}

Our background image currently shows the default “img/about-bg.jpg”:

<header class="intro-header" style="background-image: url({% static 'img/about-bg.jpg' %})">

Replace this piece with: 

<header class="intro-header" style="background-image: url(
{% if article.featured_image_id %}
    {% thumbnail article.featured_image 1200x400 crop subject_location=article.featured_image.subject_location %}
{% else %}
    {% static 'img/post-bg.jpg' %}
{% endif %}
)">

Save article_detail.html.

The code we added does the following:

If there is an image, our site will display it with a size of 1200x400 pixels. Otherwise, it will use the default “img/post-bg.jpg” from the template, since the “Featured Image” setting is optional.

This wraps up the blog configuration part of our tutorial. We now have a fully functional blog!

 

Jump to Index   Part 6: Implementing a Contact Form

 

blog comments powered by Disqus

Want to post your article here?

Contact us