Создание сайта на DjangoCMS

Создание сайта на DjangoCMS


Date of publication 27.01.2017



Я уже очень давно слежу за развитием проекта DjangoCMS и честно скажу что он не всегда мне нравился. Но постепенно команда проекта исправила многие косяки и сделала эту CMS по-настоящему удобной, гибкой и функциональной. После этого я стал практически фанатом DjangoCMS и использую его в некоторых своих проектах (например этот блог). Сегодня я подробно расскажу что такое DjangoCMS, в каких случаях его удобно применять и покажу как с помощью него создать простой сайт. Надеюсь вы тоже полюбите этот инструмент :)

На данный момент основная проблема DjangoCMS - отсутствие нормальной документации. Первое что я нашёл на официальном сайте проекта, это инструкция как создать сайт с помощью DjangoCMS и развернуть его на облачной платформе Divio Cloud. Из этой инструкции конечно можно выцепить какое-то количество полезной информации, но я как разработчик, жду совсем другого, тем более что я не планирую использовать Divio Cloud, а хочу развернуть приложение на DjangoCMS где-нибудь у себя. Самое интересное, что существует официальная документация для разработчиков по DjangoCMS, но данную ссылку я нашёл в файле README.md из репозитория проекта на GitHub, в то время как на сайте её почему-то нет.

Есть одна вещь, за которую стоит отдельно похвалить команду Divio - грамотная поддержка в online-чате на сайте проекта DjangoCMS, куда можно задавать вопросы любой сложности! Многие вещи о которых не сказано в документации я узнал лично от ребят из Divio во время переписки с ними. Там есть и наши соотечественники которые отвечали по русски, за что им отдельный респект :)

Хватит лирики, приступаем к созданию собственного сайта на DjangoCMS!

Установка DjangoCMS

В начале необходимо создать и активировать виртуальное окружение для нашего проекта. Для этого выполните команду:

virtualenv env 
source env/bin/activate

Если вы хотите использовать в своём проекте Python 3, то первую команду нужно заменить на:

virtualenv --python=/usr/bin/python3.5 env

Только не забудьте проверить правильность пути к интерпретатору Python 3, так как у вас он может отличаться.

После того как виртуальное окружение создано и активировано нам нужно поставить установщик DjangoCMS - пакет djangocms-installer:

pip install djangocms-installer

djangocms-installer ставит все необходимые пакеты для работы DjangoCMS. После этого ваше виртуальное окружение начинает поддерживать команду djangocms, которой мы скоро воспользуемся.

Создаём директорию для нашего проекта и переходим в неё:

mkdir django_cms_project
cd django_cms_project

И наконец создаём наше приложение на DjangoCMS с помощью команды:

djangocms -f -p . django_cms_example
  • Флаг -f говорит о том что дополнительно будет установлен инструмент Django Filer, который отвечает за работу с файловой системой. Мне данный инструмент нравится и я рекомендую его использовать.
  • Флаг -p с точкой (-p .) задаёт текущую директорию как родительскую для проекта.
  • djangocms_blog - название нашего приложения. Вы можете указать своё собственное.

В старых версиях установщик DjangoCMS задавал вопросы по конфигурированию приложения во время установки. В новой версии приложение конфигурируется автоматически, а так же создаётся суперпользователь с логином admin и паролем admin. После установки вы можете запустить приложение командой:

python manage.py runserver

После выполнения команды откройте в браузере ссылку http://127.0.0.1:8000/. Если всё сделано правильно, вы должны увидеть форму входа в панель администрирования Django:

Для входа просто введите логин admin и пароль admin. На этом процесс установки DjangoCMS можно считать завершённым.

Настройка

Откройте в своей любимой IDE (лично я предпочитаю PyCharm) только что созданный проект. В моём случае файлы проекта располагаются в директории djangocms_blog_project. Структура созданного проекта должна быть примерно такой:

Как Вы видите, это обычный Django-проект, только с прикрученным DjangoCMS в настройках (файл settings.py). В целом наш проект и так прекрасно запускается и работает, но Вы должны помнить что по умолчанию будет использоваться база данных SQLite, которая хорошо подходит для отладки, но совсем не подходит для работы в реальных условиях. Кроме этого DjangoCMS очень много информации хранит именно в базе: контент, меню, список страниц, настройки каждой страницы, посты и т.д. То есть при переходе на другую базу данных придётся делать миграцию и я рекомендую сразу использовать ту базу данных, дамп которой можно потом перенести на продакшен. Но это просто рекомендация, можно успешно отладить приложение, используя SQLite и фейковую информацию на страницах, а затем на новой базе собрать чистовой вариант уже на отлаженных шаблонах. Или же, как правильно заметил Dmytro Kyrychuk в комментариях, использовать команды manage.py dumpdata и loaddata (эти команды подробно описаны тут: https://docs.djangoproject.com/en/1.10/ref/django-admin/​) для того, чтобы сдампить одну базу в JSON и восстановить дамп уже на другой базе.

Так как мой проект демонстрационный, я оставляю настройки базы данных без изменений:

DATABASES = {
    'default': {
        'CONN_MAX_AGE': 0,
        'ENGINE': 'django.db.backends.sqlite3',
        'HOST': 'localhost',
        'NAME': 'project.db',
        'PASSWORD': '',
        'PORT': '',
        'USER': ''
    }
}

Других настроек на данном этапе не требуется.

Создание шаблонов

Прежде чем создавать страницы нашего сайта-блога нам нужны шаблоны на основе которых будут создаваться эти самые страницы. Наверняка вы захотите использовать собственный неповторимый дизайн чтоб было лучше чем у соседа, поэтому нам нужно в начале погрузиться в вёрстку. Шаблоны DjangoCMS это обычные файлы в формате .html с некоторым количеством шаблонных тегов Django и DjangoCMS. При создании нового проекта автоматически генерируется 4 шаблона в папке templates (в моём случае djangocms_blog_project/djangocms_blog/templates):

  • base.html - базовый шаблон, от которого наследуются все остальные шаблоны
  • fullwidth.html - шаблон полноразмерной страницы с контентом на всю ширину экрана
  • sidebar_left.html - страница с левым сайдбаром
  • sidebar_right.html - страница с правым сайдбаром

Кроме того, список шаблонов обязательно должен быть задан в settings.py в переменной CMS_TEMPLATES для того чтобы можно было выбрать нужный шаблон в интерфейсе при создании новой страницы сайта. По умолчанию у нас сконфигурировано 3 шаблона (все кроме base.html):

CMS_TEMPLATES = (
    ('fullwidth.html', 'Fullwidth'),
    ('sidebar_left.html', 'Sidebar Left'),
    ('sidebar_right.html', 'Sidebar Right')
)

Тут всё просто: нужно задать реальное название файла шаблона и произвольное название, которое будет отображаться в интерфейсе. Если вы создаёте новый шаблон, то в обязательном порядке вносите его в CMS_TEMPLATES, иначе вы не сможете им воспользоваться.

Давайте создадим первую страницу с использованием тех шаблонов, что у нас уже есть. После того как вы вошли в панель администрирования под логином admin (см. выше), должны увидеть вот такую страницу:

Выберите пункт Новая страница (Создать страницу рядом с текущей) и нажмите Далее. Откроется вот такое окно:

Заполните заголовок (Главная), путь к странице (index) и содержимое (Hello world!), а затем нажмите кнопку Создать. Всё! Страница готова:

Теперь в верхнем меню выберите Страница > Шаблоны:

В выпадающем меню жирным шрифтом должен быть выделен текущий шаблон страницы, но так как мы его явно не задавали, то по умолчанию стоит значение Наследовать шаблон от ближайшего предка. В нашем случае ближайшим предком является шаблон fullwidth.html. Выберите его и вы увидите что ничего не изменилось в дизайне страницы.

Теперь предлагаю подробно разобрать код шаблона fullwidth.html, но так как он наследуется от base.html, то начнём с базового шаблона:

{% load cms_tags menu_tags sekizai_tags %}
<!doctype html>
<html>
    <head>
        <title>{% block title %}This is my new project home page{% endblock title %}</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <style type="text/css">
            .nav {
                padding-left: 0;
            }
            .nav li {
                display: inline;
                list-style-type: none;
                padding-right: 20px;
            }
            .container {
                width: 940px;
                margin: 0 auto
            }
            .content {
                float: left;
                width: 80%;
            }
            .sidebar {
                float: left;
                width: 20%;
            }
        </style>
        {% render_block "css" %}
    </head>
    <body>
        {% cms_toolbar %}
        <div class="container">
            <ul class="nav">
                {% show_menu 0 100 100 100 %}
            </ul>
            {% block content %}{% endblock content %}
        </div>
        {% render_block "js" %}
    </body>
</html>

Что тут происходит? Да ничего особенного. В первой строке мы загружаем шаблонные теги:

Так же у нас в шаблоне 2 блока, которые можно переопределить в дочерних шаблонах: {% block title %} и {% block content %}.

Кроме этого у нас есть:

  • тег ответственный за отображение тулбара DjangoCMS - {% cms_toolbar %}
  • теги django-sekizai, которые отвечают за размещение блоков со ссылками на css и js в определённых частях страницы - {% render_block "css" %} и {% render_block "js" %}
  • тег, ответственный за отображение меню - {% show_menu 0 100 100 100 %}

Всё остальное вы и так знаете. Переходим к шаблону fullwidth.html:

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

{% block title %}{% page_attribute "page_title" %}{% endblock title %}

{% block content %}
	{% placeholder "content" %}
{% endblock content %}

По факту перед нами стандартный шаблон Django отнаследованный от base.html. Из интересного тут 2 тега DjangoCMS:

  • тег {% page_attribute "page_title" %} - отображает атрибут страницы page_title в блоке title. Данный атрибут задаётся при создании страницы и является её заголовком. Все атрибуты можно просмотреть в документации.
  • тег {% placeholder "content" %} - это очень важный тег, который задаёт изменяемую часть страницы в блоке content. Количество плейсхолдеров на странице может быть неограниченным, главное чтоб название каждого плейсхолдера было уникальным. В панели администратора DjangoCMS можно менять содержимое любого плейсхолдера на своё усмотрение, например туда можно добавить текст, ссылку, картинку и т.д., а можно всё сразу и в любых комбинациях :)

Вот вы уже имеете некоторое представление о шаблонах DjangoCMS. Приведённые выше шаблоны я полностью изменю и доработаю, так как хочу чтобы сайт имел красивый дизайн. Это всё реализуется очень просто, но прежде чем менять шаблоны, давайте заглянем в панель администрирования DjangoCMS, для того чтобы лучше разобраться с плейсхолдерами. Нажмите кнопку Структура на верхней панели и вы увидите вот такую страницу:

Содержимое - это наш плейсхолдер content из шаблона fullwidth.html. Он содержит один единственный плагин, который отображает строчку Hello world!. Вы можете в любой момент отредактировать содержимое плагина, а так же добавлять другие плагины в плейсхолдер и даже создавать свои собственные плагины (об этом я расскажу в другой статье).

Для наглядности добавим ещё один плагин в плейсхолдер content. Для этого нажмите кнопку + и в появившемся окне выберите из списка плагин Google Map:

В открывшемся окне задайте название карты (поле MAP TITLE), а так же широту и долготу своего города (поля LATITUDE и LONGITUDE). В качестве названия у меня просто слово Карта, широта 55.751244, долгота 37.618423:

Нажмите кнопку Сохранить и вы увидите в списке плагинов плейсхолдера contentновый плагин:

В верхней панели появилась синяя кнопка Опубликовать изменения страницы. Нажмите её и вы увидите обновлённую главную страницу с картой:

Вот так легко и просто можно управлять содержимым страницы в DjangoCMS.

Теперь я покажу как кардинально изменить дизайн сайта. Больше всего мне нравится в DjangoCMS то что можно взять практически любой html-шаблон и с минимальными изменениями встроить его в свой проект. В качестве примера я нашёл в интернете бесплатный адаптивный шаблон, свёрстанный с помощью CSS-фреймворка Bootstrap.

Для начала изменим содержимое базового шаблона base.html:

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

<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>{% block title %}Сайт Алексея Кутепова{% endblock title %}</title>

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

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

    <!-- Custom Fonts -->
    <link href="{{ STATIC_URL }}css/font-awesome.min.css" rel="stylesheet" type="text/css">
    <link href='https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
    {% render_block "css" %}

    <!-- 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]-->

</head>

<body>
{% cms_toolbar %}

    <!-- Navigation -->
    <nav class="navbar navbar-default navbar-custom navbar-fixed-top">
        <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header page-scroll">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                    <span class="sr-only">Меню</span>
                    Меню <i class="fa fa-bars"></i>
                </button>
                <a class="navbar-brand" href="/">Алексей Кутепов</a>
            </div>

            <!-- 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 100 100 100 %}
                </ul>
            </div>
            <!-- /.navbar-collapse -->
        </div>
        <!-- /.container -->
    </nav>

    <!-- Page Header -->
    <!-- Set your background image for this header on the line below. -->
    {% block header %}
    <header class="intro-header" style="background-image: url('{{ STATIC_URL }}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>{% placeholder "title" %}</h1>
                        <hr class="small">
                        <span class="subheading">{% placeholder "sub_title" %}</span>
                    </div>
                </div>
            </div>
        </div>
    </header>
    {% endblock header %}

    <!-- Main Content -->
    <div class="container">
        {% block content %}{% endblock content %}
    </div>

    <hr>

    <!-- Footer -->
    <footer>
        <div class="container">
            <div class="row">
                <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                    <ul class="list-inline text-center">
                        <li>
                            <a href="https://twitter.com/alkutepov">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-twitter fa-stack-1x fa-inverse"></i>
                                </span>
                            </a>
                        </li>
                        <li>
                            <a href="https://www.facebook.com/alkutepov">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-facebook fa-stack-1x fa-inverse"></i>
                                </span>
                            </a>
                        </li>
                        <li>
                            <a href="https://github.com/AlexeyKutepov">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-github fa-stack-1x fa-inverse"></i>
                                </span>
                            </a>
                        </li>
                    </ul>
                    <p class="copyright text-muted">Copyright &copy; {% static_placeholder "copyright" %}</p>
                </div>
            </div>
        </div>
    </footer>

    <!-- jQuery -->
    <script src="{{ STATIC_URL }}js/jquery.min.js"></script>

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

    <!-- Theme JavaScript -->
    <script src="{{ STATIC_URL }}js/clean-blog.min.js"></script>
    {% render_block "js" %}
</body>
</html>

Я не буду подробно разбирать этот код, так как статья про DjangoCMS, а не про вёрстку. Тем более вы можете использовать любой другой шаблон вместо этого или создать свой собственный. Данный шаблон я брал "как есть" и дополнил его тегами Django и DjangoCMS, о которых мы сейчас и поговорим.

Как всегда в самом начале мы должны загрузить все необходимые шаблонные теги:

{% load cms_tags menu_tags sekizai_tags %}

В тег <title> я добавил блок title для того чтобы была возможность задавать разные заголовки страницы в разных шаблонах:

<title>{% block title %}Сайт Алексея Кутепова{% endblock title %}</title>

Далее загружаем таблицы стилей из папки static и нужные для шаблона шрифты из интернета:

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

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

<!-- Custom Fonts -->
<link href="{{ STATIC_URL }}css/font-awesome.min.css" rel="stylesheet" type="text/css">
<link href='https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
{% render_block "css" %}

Обратите внимание на переменную {{ STATIC_URL }} - в место него Django автоматически подставляет путь до папки со статикой. Так же в конце присутствует тег {% render_block "css" %}, который на данном этапе бесполезен, но при усложнении шаблона может здорово помочь: вместо этого тега можно динамически подставлять таблицы стилей в зависимости от определённых условий.

После тега <body> нужно не забыть поставить шаблонный тег {% cms_toolbar %}, так как он отвечает за отображение верхней панели инструментов в режиме редактирования сайта. Как вы могли убедиться, мы её используем довольно часто и без неё у нас просто не будет возможности вносить изменения.

В блок навигации я добавил тег {% show_menu 0 100 100 100 %}, который отвечает за отображение пунктов меню (каждый пункт меню будет заключён в тег <li>):

<!-- Navigation -->
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header page-scroll">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Меню</span>
                    Меню <i class="fa fa-bars"></i>
            </button>
            <a class="navbar-brand" href="/">Алексей Кутепов</a>
        </div>

        <!-- 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 100 100 100 %}
            </ul>
        </div>
        <!-- /.navbar-collapse -->
    </div>
    <!-- /.container -->
</nav>

В шаблоне предусмотрен красивый хедер с фоновым изображением. Код, который отвечает за отображение хедера я заключил в блок header для того чтобы его можно было переопределить в дочерних шаблонах. Кроме того, в хедере у нас есть заголовок и подзаголовок, вместо которых я добавил плейсхолдеры title и sub_title, для того чтобы их можно было динамически изменять. При загрузке фонового изображения обязательно используется переменная {{ STATIC_URL }}:

{% block header %}
<header class="intro-header" style="background-image: url('{{ STATIC_URL }}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>{% placeholder "title" %}</h1>
                    <hr class="small">
                    <span class="subheading">{% placeholder "sub_title" %}</span>
                </div>
            </div>
        </div>
    </div>
</header>
{% endblock header %}

После хедера идёт блок content, с которым вы знакомы по предыдущему шаблону:

<!-- Main Content -->
<div class="container">
    {% block content %}{% endblock content %}
</div>

Далее идёт футер, в котором я использовал новый шаблонный тег - {% static_placeholder "copyright" %}. Основное отличие тега static_placeholder от placeholder заключается в том что содержимое static_placeholder наследуется дочерними шаблонами. В данном случае нам достаточно один раз задать значение {% static_placeholder "copyright" %} на главной странице и оно автоматически будет отображаться на других страницах нашего сайта:

<p class="copyright text-muted">Copyright &copy; {% static_placeholder "copyright" %}</p>

В самом конце мы загружаем все необходимые скрипты из папки со статикой:

<!-- jQuery -->
<script src="{{ STATIC_URL }}js/jquery.min.js"></script>

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

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

Теперь чтобы новый шаблон отобразился корректно, нужно поместить все зависимости в папку django_cms_project/django_cms_example/static/, для этого просто скопируйте их из репозитория данного проекта на GitHub.

Перезагрузите сервер и обновите страницу в браузере. Если вы всё сделали правильно, то должны увидеть сайт уже в обновлённом дизайне:

Пока ещё не вся информация отображается на странице, так как мы ещё не заполнили новые плейсхолдеры. Нажмите синюю кнопку Редактировать страницу на верхней панели, а затем на кнопку Структура. Как вы видите, в структуре страницы появились 3 новых плейсхолдера: Title (у меня система перевела название этого плейсхолдера на русский язык как Заголовок), Sub_Title и Copyright.

Теперь нужно заполнить эти плейсхолдеры какой-либо информацией, для этого нажмите на кнопку + возле каждого из новых плейсхолдеров, в открывшемся окне выберите плагин Текст, после этого откроется редактор. Нажмите кнопку Источник в панели инструментов редактора и введите любой текст.

Кроме того у нас ещё есть плейсхолдер content (Содержимое), который мы заполняли ранее. Удалите из него плагин Google Map и откройте на редактирование плагин Текст. Затем нажмите кнопку Источник в редакторе и введите произвольный текст, заключённый в теги:

<div class="row">
    <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        <p>Произвольный текст</p>
    </div>
</div>

Я заполнил плейсхолдеры вот так:

Нажмите кнопку Опубликовать изменения страницы и откроется вот такое окно уже с заполненной информацией:

Отлично! Теперь нас есть полноценная первая страница сайта. Давайте для примера создадим новый шаблон и сделаем ещё одну страницу. Предположим нам нужен особенный шаблон для раздела с контактами на сайте. Для этой цели создайте в папке templates файл contacts.html с таким содержимым:

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

{% block title %}{% page_attribute "page_title" %}{% endblock title %}

{% block header %}
    <header class="intro-header" style="background-image: url('{{ STATIC_URL }}img/contact-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>{% placeholder "title" %}</h1>
                        <hr class="small">
                        <span class="subheading">{% placeholder "sub_title" %}</span>
                    </div>
                </div>
            </div>
        </div>
    </header>
{% endblock header %}

{% block content %}
	<div class="row">
        <div class="col-lg-10 col-lg-offset-2 col-md-10 col-md-offset-1">
            <div class="col-lg-6 col-sm-12 maincontent">
                <h3>Контакты</h3>
                <br>
                <h5><i class="fa fa-envelope-o" aria-hidden="true"></i> {% placeholder "email" %}</h5>
                <h5><i class="fa fa-skype" aria-hidden="true"></i> {% placeholder "skype" %}<br></h5>
                <h5><i class="fa fa-phone" aria-hidden="true"></i> {% placeholder "phone" %}<br></h5>
            </div>
            <div class="col-lg-6 col-sm-12 maincontent">
                <h3>Я в социальных сетях</h3>
                <br>
                <h5><i class="fa fa-vk" aria-hidden="true"></i> {% placeholder "vk" %}<br></h5>
                <h5><i class="fa fa-facebook" aria-hidden="true"></i> {% placeholder "facebook" %}<br></h5>
                <h5><i class="fa fa-linkedin" aria-hidden="true"></i> {% placeholder "linkedin" %}<br></h5>
                <h5><i class="fa fa-github" aria-hidden="true"></i> {% placeholder "github" %}<br></h5>
            </div>
        </div>
    </div>
{% endblock content %}

В этом коде нет ничего нового, я просто сверстал список контактов и добавил для каждого контакта свой плейсхолдер. Ещё я для красоты переопределил блок header. Теперь нужно добавить этот шаблон в settings.py:

CMS_TEMPLATES = (
    ('fullwidth.html', 'Fullwidth'),
    ('sidebar_left.html', 'Sidebar Left'),
    ('sidebar_right.html', 'Sidebar Right'),
    ('contacts.html', 'Contacts')
)

Теперь перезагрузите сервер и создайте новую страницу, выбрав в верхней панели Страница > Создать страницу > Новая страница:

Заполните все поля в появившемся окне и нажмите кнопку Сохранить и продолжить редактирование:

В новом окне нажмите кнопку Расширенные настройки и выберите шаблон Contacts из выпадающего списка:

Нажмите синюю кнопку Сохранить и вы будете автоматически перенаправлены в раздел Структура новой страницы. Необходимо заполнить все плейсхолдеры используя плагины Текст и Ссылка:

Прежде чем пойти дальше, хочу рассказать о плагине Ссылка. Вот так выглядит окно с настройками плагина:

Основные поля:

  • DISPLAY NAME - отображаемое название ссылки
  • EXTERNAL LINK - используется в том случае, если ссылка идёт на внешний ресурс
  • INTERNAL LINK - позволяет ссылаться на внутренние страницы сайта
  • Link settings - в этом разделе для нас интерес представляют поля, которые позволяют сформировать ссылку для электронной почты и телефона

Как видите, сложного ничего нет. Плагин простой, удобный в использовании и довольно функциональный. Я уверен что вы без труда сможете им пользоваться.

Теперь вернёмся к нашей новой странице. После заполнения всех плейсхолдеров необходимо нажать синюю кнопку Опубликовать страницу немедленно в верхней панели инструментов. Все внесённые изменения на странице будут сохранены, сама страница опубликована и в главном меню сайта появится новый пункт Контакты. Вот что должно получиться в итоге:

У нас получился небольшой и красивый сайт, но так как данный проект демонстрационный, тут можно ещё много чего доработать. Теперь вы знаете основы работы с DjangoCMS и уже можете создать свой собственный сайт на основе данного фреймворка.

В этой статье я затронул только малую часть возможностей DjangoCMS, поэтому будет продолжение, где я расскажу о плагинах, сторонних дополнениях и кастомизации функционала сайта.

Исходники проекта вы можете найти по ссылке (не забудьте переключиться на ветку part1): https://github.com/AlexeyKutepov/django_cms_project