В качестве хобби, я решил открыть для себя мир веб-разработки, попутно освещая свои успехи, а может и неудачи на пути к просветлению…

В настоящее время я публично описываю процесс создания веб-сайта с нуля на Django и Bootstrap, где задача разработать такие приложения как: аккаунты, вопросы, статьи и книги.

В проекте решаются только реальные задачи, которые почему-то так любят обходить стороной в учебной литературе.

Создание веб-сайта с нуля на Django и Bootstrap. Аккаунты. Регистрация с подтверждением адреса электронной почты. Шаблоны

Сергей Серов

Шаблоны

В заключительной части мы создадим шаблоны для всех писем, утилит, декораторов и представлений.

Шаблоны писем

Переходим в каталог templates и создаем директорию accounts и в ней подкаталог vcode. Затем формируем файл subject.txt:

Ссылка для подтверждения операции

Далее в подкаталоге vcode cоздаем базовый файл для содержимого писем base.txt:

{% block action %}{% endblock %}

Для подтверждения операции просто откройте ссылку ниже или скопируйте и вставьте ее в Ваш бразуер.

{{ domain }}{% block link %}{% endblock %}

Создаем файл join.txt в подкаталоге vcode:

{% extends 'accounts/vcode/base.txt' %}

{% block action %}РЕГИСТРАЦИЯ{% endblock %}

{% block link %}{% url 'accounts:join_confirm' vcode %}{% endblock %}

Шаблон декоратора

В директории accounts создаем файл anonymous_required.html:

{% extends 'base.html' %}

{% load core_tags %}

{% block title %}Уведомление{% endblock %}

{% block main %}
    <div class="accounts-anonymous-required">
        <h1>Уведомление</h1>

        {% alert_tag success %}
            Вы уже вошли как <strong>{{ user.username }}</strong>. Возможно эта страница устарела или Вы на нее зашли по ошибке.
        {% end_alert_tag %}
    </div>
{% endblock %}

Здесь мы используем шаблонный тег alert_tag.

Шаблонные теги

В каталоге приложения core создаем директорию templatetags, название директории обязательно условие для поиска шаблонных тегов. Далее мы создаем пустой файл __init__.py и core_tags.py со следующим содержимым:

from django import template
from django.template.loader import render_to_string

register = template.Library()


@register.filter
def label_with_classes_filter(field, classes):
    return field.label_tag(attrs={'class': classes})


@register.filter
def field_with_classes_filter(field, classes):
    return field.as_widget(attrs={'class': classes})


def alert(status, body):
    return render_to_string('core/alert.html', {
        'status': status,
        'body': body,
    })


class AlertNode(template.Node):
    def __init__(self, nodelist, status):
        self.nodelist = nodelist
        self.status = status

    def render(self, context):
        body = self.nodelist.render(context)
        return alert(self.status, body)


@register.tag
def alert_tag(parser, token):
    try:
        tag_name, status = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError('alert_tag принимает только один аргумент (статус уведомления)')
    nodelist = parser.parse(['end_alert_tag'])
    parser.delete_first_token()
    return AlertNode(nodelist, status)

Первые два тега это хаки, которые добавляют классы, например, от фреймворка Bootstrap для правильного отображения полей формы.

Следующие объекты реализуют один шаблонный тег alert_tag. В основной функции мы передаем статус уведомления и само сообщение в шаблон. Статус влияет на цвет уведомления, например, класс success, Bootstrap отобразит зеленым цветом.

В директории templates создаем каталог core и шаблон с названием alert.html:

<div class="alert alert-{{ status }}" role="alert">
    <i class="fa fa-exclamation-circle" aria-hidden="true"></i>
    {{ body }}
</div>

Шаблон регистрации

В подкаталоге accounts создаем шаблон с названием join.html:

{% extends 'base.html' %}

{% block title %}Присоединиться{% endblock %}

{% block main %}
    <div class="accounts-join">
        <h1>Присоединиться</h1>

        <form action="{% url 'accounts:join' %}" method="post">
            {% csrf_token %}
            {% include 'core/form_fields.html' %}
            <button type="submit" class="btn btn-success">Присоединиться</button>
        </form>
    </div>
{% endblock %}

Для вывода непосредственно полей формы мы подключаем другой шаблон. Переходим в подкаталог core и создаем form_fields.html:

{% load core_tags %}

{% for error in form.non_field_errors %}
    {% alert_tag danger %}
        {{ error }}
    {% end_alert_tag %}
{% endfor %}

{% for field in form %}
    <div class="form-group{% if field.errors %} has-error{% endif %}">
        {{ field|label_with_classes_filter:'control-label' }}
        {{ field|field_with_classes_filter:'form-control' }}
        {% if field.errors or field.help_text %}
            <span class="help-block">{% if field.errors %}{{ field.errors }}{% else %}{{ field.help_text }}{% endif %}</span>
        {% endif %}
    </div>
{% endfor %}

Шаблон подтверждения

В подкаталоге accounts создаем файл join_confirm.html:

{% extends 'base.html' %}

{% load core_tags %}

{% block title %}Присоединиться (подтверждение){% endblock %}

{% block main %}
    <div class="accounts-join-confirm">
        <h1>Присоединиться (подтверждение)</h1>

        {% if status == 'waiting' %}
            {% alert_tag success %}
                Мы выслали проверочный код на Ваш адрес электронной почты и с нетерпением ждем подтверждения.
            {% end_alert_tag %}
            <p>Если по каким-то причинам письмо не пришло Вы можете воспользоваться <a href="{% url 'accounts:join_resend' %}">формой повторной отправки кода</a>.</p>
            <p>А если Вы видите это сообщение постоянно, то можете обратиться за помощью к администрации проекта.</p>

        {% elif status == 'success' %}
            {% alert_tag success %}
                Поздравляем! Теперь Вы один из нас.
            {% end_alert_tag %}

        {% elif status == 'invalid' %}
            {% alert_tag danger %}
                Ваш код неверен или устарел, проверочные коды, как правило, не отличаются высокой продолжительностью жизни…
            {% end_alert_tag %}
            <p>Вы можете воспользоваться <a href="{% url 'accounts:join_resend' %}">формой повторной отправки кода</a>.</p>
        {% endif %}
    </div>
{% endblock %}

Шаблон повторной отправки кода

В подкаталоге accounts создаем шаблон join_resend.html:

{% extends 'base.html' %}

{% block title %}Реактивация{% endblock %}

{% block main %}
    <div class="accounts-join-resend">
        <h1>Реактивация</h1>

        <form action="{% url 'accounts:join_resend' %}" method="post">
            {% csrf_token %}
            {% include 'core/form_fields.html' %}
            <button type="submit" class="btn btn-success">Отправить</button>
        </form>
    </div>
{% endblock %}