Content: Blog

Tutorials

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

Christian Bertschy

Feb. 16, 2016

Index


Part 2: Building Our First Template

In your project's "templates" folder, you’ll find all the HTML files. Each addon has its own folder with the specific templates required for the application to work (we’ll cover this later).

Since django CMS is based on Django, the templates use the Django template language (DTL). If you know Smarty or Jinja2, DTL will look very familiar to you. We only need the basics for this tutorial, though.

base.html

The basis of all django CMS websites is the base.html template. Most of the other templates will "inherit" from this template. Our project already comes with an example base.html.

This feature allows you to reuse templates so you don’t have to waste time repeating steps. Basically, a template can build up on other templates by extending them with blocks. In the case of our project, the inheritance is as follows:
 

base.html (Defines the basic HTML document for your website, such as header, content and footer)

   ↖  content.html (Defines the entry point for your content)

 

In this scenario, content.html extends base.html. This keeps a CMS template (content.html) nice and tidy:

{% extends "base.html" %}
{% load cms_tags %}

{% block content %}
    {% placeholder content or %}
        <p>This page has no content yet. Make sure you are in <em>Edit</em> mode
           (hit the <strong>Edit page</strong> button if required). Then switch to
           <em>Structure</em> mode.</p>
    {% endplaceholder %}
{% endblock content %}

Since we want to incorporate the previously downloaded theme, copy the about.html file from the downloaded theme folder into your project’s “templates” folder.

Then, delete the "base.html" file and rename the "about.html" to "base.html".

If you go back to your browser, you’ll see a Django template error. Don’t worry, just reload and your site should now show the HTML content. If the error is still present, open "base.html" in your editor, add and remove a line and press save.

You might notice that it doesn’t look “pretty,” yet. This is due to your static files not being properly linked, yet. Let’s fix this.

Open "base.html" in your code editor (i.e. AtomBrackets, Sublime or similar). The first couple of lines should look like this:

<!DOCTYPE html>
<html lang="en">

<head>

   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
...

To enable some basic features in the template, we need to add the following code on the first line:

{% load staticfiles i18n cms_tags sekizai_tags menu_tags %}
<!DOCTYPE html>
<html lang="en">

<head>
...

This declares static files (staticfiles) and use of internationalization (i18n), includes cms features (cms_tags, menu_tags) and defines some blocks to render on-demand files for i.e. styles or javascript (sekizai_tags).

The base.html file contains nine references to files we need to modify. Let’s start at the top with three CSS files:

   <!-- Bootstrap Core CSS --> 
   <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">

   <!-- Theme CSS --> 
   <link href="css/clean-blog.min.css" rel="stylesheet">

   <!-- Custom Fonts -->
   <link href="vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

To load files from the django CMS static folder, we need to modify them as follows:

   <!-- Bootstrap Core CSS -->
   <link href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">

   <!-- Theme CSS -->
   <link href="{% static 'css/clean-blog.min.css' %}" rel="stylesheet">

   <!-- Custom Fonts -->
   <link href="{% static 'vendor/font-awesome/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css">

About External Files

The theme contains additional files that get loaded from an external source, such as:

<link href='http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>

These files don’t need to be modified and can be left untouched.

Next, we’ll replace the header picture. You’ll find it here:

<!-- Page Header -->
<!-- Set your background image for this header on the line below. -->
<header class="intro-header" style="background-image: url('img/about-bg.jpg')">

We’ll change it in the same way as the previous files:

<!-- Page 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' %})">

The last file paths we need to modify are the javascript files at the very end of the template:

</footer>

<!-- jQuery -->
<script src="vendor/jquery/jquery.min.js"></script>

<!-- Bootstrap Core JavaScript -->
<script src="vendor/bootstrap/js/bootstrap.min.js"></script>

<!-- Contact Form JavaScript -->
<script src="js/jqBootstrapValidation.js"></script>
<script src="js/contact_me.js"></script>

<!-- Theme JavaScript -->
<script src="js/clean-blog.min.js"></script>

Change the paths to:

</footer>

<!-- jQuery -->
<script src="{% static 'vendor/jquery/jquery.min.js' %}"></script>

<!-- Bootstrap Core JavaScript -->
<script src="{% static 'vendor/bootstrap/js/bootstrap.min.js' %}"></script>

<!-- Contact Form JavaScript -->
<script src="{% static 'js/jqBootstrapValidation.js' %}"></script>
<script src="{% static 'js/contact_me.js' %}"></script>

<!-- Theme JavaScript -->
<script src="{% static 'js/clean-blog.min.js' %}"></script>

Save your changes, go back to your website and refreshYour site should look like this:


Adding the django CMS Toolbar

Adding the django CMS toolbar to your template is very simple and just requires the addition of five tags.

{% cms_toolbar %}

  Loads the toolbar itself

{% render_block "css" %}

  Loads necessary CSS files for django CMS and its addons

{% render_block "js" %}

  Loads necessary Javascript files for django CMS and its addons

{{ ALDRYN_SNAKE.render_head }}

  Loads necessary files for Divio Cloud and its addons to the top

{{ ALDRYN_SNAKE.render_tail }}

  Loads necessary files for Divio Cloud and its addons to the bottom

These elements need to be placed as follows in the base.html template:

   <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
   <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
   <!--[if lt IE 9]>
       <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
       <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
   <![endif]-->

   <!-- django CMS -->
   {% render_block "css" %}

   <!-- Divio Cloud -->
   {{ ALDRYN_SNAKE.render_head }}

</head>
<body>
    <!-- django CMS Toolbar -->
    {% cms_toolbar %}

    <!-- Navigation -->
    <nav class="navbar navbar-default navbar-custom navbar-fixed-top">
...
    <!-- Theme JavaScript -->
    <script src="{% static 'js/clean-blog.min.js' %}"></script>

    <!-- django CMS -->
    {% render_block "js" %}

    <!-- Divio Cloud -->
    {{ ALDRYN_SNAKE.render_tail }}

</body>

Hit “Save” and reload


Adding the Content

Now we need to prepare a place for our content to be loaded into the template. Currently, we have lorem ipsum text in place:

    <!-- Main Content -->
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Saepe nostrum ullam eveniet pariatur voluptates odit, fuga atque ea nobis sit soluta odio, adipisci quas excepturi maxime quae totam ducimus consectetur?</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eius praesentium recusandae illo eaque architecto error, repellendus iusto reprehenderit, doloribus, minus sunt. Numquam at quae voluptatum in officia voluptas voluptatibus, minus!</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nostrum molestiae debitis nobis, quod sapiente qui voluptatum, placeat magni repudiandae accusantium fugit quas labore non rerum possimus, corrupti enim modi! Et.</p>
            </div>
        </div>
    </div>

Remove the paragraphs inside and replace them with the proper content block. It should look exactly like this: 

<!-- Main Content -->
<div class="container">
    <div class="row">
        <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
            {% block content %}{% endblock %}
        </div>
    </div>
</div>

Save your changes.The default text from our content.html template should now show up. 

Adding Your Navigation

To render the navigation, we’ll need to replace the following code:

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse"id="bs-example-navbar-collapse-1">
        <ul class="nav navbar-nav navbar-right">
            <li>
                <a href="index.html">Home</a>
            </li>
            <li>
                <a href="about.html">About</a>
            </li>
            <li>
                <a href="post.html">Sample Post</a>
            </li>
            <li>
                <a href="contact.html">Contact</a>
            </li>
        </ul>
    </div>

With this code:

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse"id="bs-example-navbar-collapse-1"> 
        <ul class="nav navbar-nav navbar-right">
            {% show_menu 0 0 100 100 %}
        </ul>
    </div>

This tag automatically renders the main menu from the CMS. 

The numbers after "show_menu" define what levels of navigation are rendered. To learn more about this, check out the django CMS docs, here.

Check your browser and reload. 

At this point, the toolbar will be in the way of viewing the navigation. Disable the toolbar by clicking on the first menu item next to the django CMS logo and click “Disable Toolbar.” 

You should now see the menu on your website. 

Enable the toolbar again by replacing “?toolbar_off” with “?edit” in the website address in your browser. 

This might not help you if you want to stay in “Draft” mode. To solve this, add this simple snippet inside your <head> tag:

<!-- django CMS toolbar adjustment -->
{% if request.toolbar %}
<style>
    .cms-toolbar-expanded .navbar-custom {
        margin-top: 45px;
    }
</style>
{% endif %}

</head>

The CMS adds “cms-toolbar-expanded” to the document when the toolbar is expanded and removes it again when collapsed. You can expand and collapse the toolbar by clicking the triangle on the right side of the toolbar.

You should now see the two pages you added: “Home” and “Blog.”


Final Touches to your Project

Your base.html file is now ready to be used. 

Below are some optional modifications that are easy to implement and greatly enhance your templates by adding dynamic values. 

To dynamically set the language of your template, change the html-tag:

<!DOCTYPE html>
<html lang="en">
...

To:

<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}">
...

To easily add specific meta descriptions for each django CMS page, simply add the appropriate tag to the template.

...
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
...

Simply add the {% page_attribute 'meta_description' %} tag:

...
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="{% page_attribute 'meta_description' %}">
    <meta name="author" content="">
...

Next, we want to setup a dynamic page title. Navigate to the <title></title> tag and check its content. It currently reads: “Clean Blog - About.” 

    <meta name="author" content="">

    <title>Clean Blog - About</title>

    <!-- Bootstrap Core CSS -->
    ...

Replace this with:

<meta name="author" content="">

    <title>
        {% block title %}
            {% page_attribute "page_title" %} - {{ request.site.name }}
        {% endblock title %}
    </title>
    <!-- Bootstrap Core CSS -->
    ...

The block title might be used by third party addons, as well as provide additional information on your page. 

In this case, we want to display the page_title attribute which might read “Home” or “Blog”. The second param request.site.name will display “Site” or whatever you configured in the Sites section earlier on.

The logo is currently defined as follows:

<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header page-scroll">
    ...
    <a class="navbar-brand" href="index.html">Start Bootstrap</a>
</div>

To make it more dynamic, let’s change the href-attribute to “/" and "Start Bootstrap" to {{ request.site.name }}

<a class="navbar-brand" href="/">{{ request.site.name }}</a>

Divio Cloud installs all static files and templates from addons directly into your project. Any subsequent addon update will not override these templates. We recommend that you remove at least the following folders:

  • static/aldryn_bootstrap3
  • static/djangocms_text_ckeditor
  • static/djangocms_googlemap
  • templates/admin
  • templates/aldryn_bootstrap3
  • templates/cms/
  • templates/djangocms_file, _googlemap, _link, _picture, _snippet, _video, _style

This will not break your project, the templates will just fallback to the addons default templates following the Django template inheritance.

django CMS has very few strict conventions on how to use or name things in your template. This is merely a best practice example to help you get started. Feel free to adapt it to your own personal flavour.

Jump to Index   Part 3: Adding Content

 

blog comments powered by Disqus

Want to post your article here?

Contact us