среда, 8 апреля 2009 г.

Наследование шаблонов в Django

В питоновском веб-фреймворке django встроен механизм наследования шаблонов страниц. Лично я считаю, что это очень спорная фишка и должна применяться с большой аккуратностью. Сейчас попробую объяснить почему.
Сначала определимся с терминологией. Этот механизм является именно наследованием, тем самым, которое используется в ООП. Этот вывод я сделал проанализировав получающиеся конструкции. Ведь фактически шаблон-наследник знает о структуре шаблона предка, хотя может и не знать детали реализации, ведь для того, чтобы переопределить (или доопределить) часть исходного шаблона нам потребуется указать имена тех частей, которые необходимо переопределить. Итак, рассмотрим маленкий пример:
Родительский шаблон:
<html>
<head>
<meta equiv="Content-type" content="text/html; charset=utf-8" />
<link type="text/css" rel="stylesheet" href="/static/Styles.css" />
{% block extrahead %} {% endblock %}
<title>{% block title %} {% endblock %}</title>
</head>
<body>
{% block content %} {% endblock %}
</body>
</html>
Шаблон наследник:
{% extends "base.html" %}

{% block extrahead %}
<script type="text/javascript" src="additionalscript.js"></script>
{% endblock %}

{% block title %}
Супер заголовок
{% endblock %}

{% block content %}
...
{% endblock %}

Казалось бы все по джанговски и замечательно. Но! Работа с шаблонами реализованная таким образом таит немало неприятностей, но самая главная из них - шаблон более низкого уровня по иерархии знает о структуре шаблонов более высокого уровня. И не просто знает (что не стало бы проблемой при использовании подходящих конвенций), а просто обязан использовать эти сведения. Получается что шаблон более низкого уровня сильно связан с более абстрактным шаблоном, что не есть правильно и лишает подобную структуру гибкости.
Выход? Есть выход! Наследование шаблонов безусловно мощная вещь и позволяет избежать дублирования кода, но использовать её необходимо с аккуратностью, особенно в больших проектах. Использовать также, как и наследование ООП, проверяя действие принципов используемых в ООП. Лично я для себя проверяю возможность наследования отношением "является", наследование можно применять в случае, если в человеческом языке корректной будет фраза "<наследник> является <предком>". Таким образом, приведенный выше пример корректен, так как шаблон-предок, фактически, является "обобщенной страницей", а шаблон наследник - "конкретной страницей". Но в случаях добавления дополнительных элементов на страницу, контролов и прочего, на мой взгляд более правильным и менее пахнущим будет использование агрегации с использованием механизмов custom tags.

Комментариев нет:

Отправить комментарий