Шаблон проекта на Джанго с инструментами сборки и утилитами. Шаблоны для django cms


Урок 035. Различные шаблоны для рендеринга разных типов контента в поисковой выдаче

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

Посмотрим на пример выдачи.

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

Но это сделано гораздо более изящно, чем выбор через if else . Честно, мне самому очень нравится это решение.

Для каждой модели данных нужно определить поле, которое хранит путь к шаблону для отображения объекта этой модели. При этом в каждой модели это поле должно иметь одно и тоже название. Это очень важно.

Например сделаем так

class Article(models.Model): TEMPLATE_PREVIEW = 'home/article_preview.html' class Comment(models.Model): TEMPLATE_PREVIEW = 'home/comment_preview.html' class Topic(models.Model): TEMPLATE_PREVIEW = 'home/topict_preview.html' class Post(models.Model): TEMPLATE_PREVIEW = 'home/post_preview.html'

В каждом этом шаблоне мы можем прописать своё собственное отображение контента, которое на потребуется. Например для статьи

<div> <a href="{{ object.get_absolute_url }}"><h3>{{ object.itle }}</h3></a> {{ object.content|safe }} <p><a href="{{ object.get_absolute_url }}">Читать далее</a></p> </div>

А для всех остальных шаблонов можем написать что-нибудь другое. Главное, чтобы все методы и поля, а также имя одиночного объекта было одинаковым во всех шаблонах.

А сам шаблон поисковой выдачи может выглядеть так

{% load tz %} {% load trans from i18n %} {% load bootstrap_pagination from bootstrap4 %} <div> {% for object in object_list %} {% include object.TEMPLATE_PREVIEW %} {% empty %} <div>{% trans 'Ничего не найдено' %}</div> {% endfor %} {% bootstrap_pagination object_list pages_to_show="10" url=last_question %} </div>

Нюанс заключается в том, что мы привыкли передавать в тег include строковое имя шаблона, например так

{% include 'home/article_preview.html' %}

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

{% include object.TEMPLATE_PREVIEW %}

А если учесть, что каждый объект имеет свой TEMPLATE_PREVIEW, то и файлы там будут подключаться разные, а значит каждый вид контента будет иметь свой собственный стиль отрисовки.

Для Django рекомендую VDS-хостинг TIMEWEB

evileg.com

Шаблон проекта на Джанго с инструментами сборки и утилитами / Хабр

Иногда приходится создавать с нуля сайт на Джанге. Это и тесты концепций, и простенькие странички (ведь если мы в проекте используем разные мощные инструменты, почему бы сайт-визитку не сделать тоже с их помощью, избавив себя от ручной работы?).

Итак, представляю публике проект под девизом «Поменьше писанины! Побыстрей, дебаг!» Набор для скоростной разработки на Джанго.

Это 2 шаблона:

Установка

Чтобы загрузить проект и создать проект на Джанго, просто выполните команды:

$ hg clone ssh://[email protected]/siberiano/fastdev-django my_new_project $ cd my_new_project $ rm .hg/hgrc $ python bootstrap.py --distribute $ make buildout

(Страница проекта на BitBucket.)

Из чего состоит проект:

Makefile

Вместо набора скриптов командной строки мы в проекте с моей работы сделали Makefile и составили зависимости команд, например, что run можно выполнить только после buildout и bootstrap. Я добавил в make следующие рутинные процедуры:

Buildout

zc.buildout — это скрипт, разработанный в проекте Zope и используемый в Pylons, который собирает в папке проекта или в пользовательской папке ~/.buildout, изолирует окружение проекта от дополнительных пакетов (site packages) и выполняет некоторые рецепты (например, установить скрипт и поставить на него линк из другого).

У buildout есть гибкая система настроек и готовая коллекция разных скриптов, в общем, развитая инфраструктура, которой можно пользоваться, чтобы собрать работающий проект.

Вот пример простейшей конфигурации, где мы устанавливаем Джангу с дополнительными пакетами и статический анализатор кода pyflakes:

[buildout] parts = django pyflakes [django] recipe = djangorecipe eggs = ipython django_extensions [pyflakes] recipe = zc.recipe.egg scripts = pyflakes eggs = pyflakes entry-points = pyflakes=pkg_resources:run_script arguments = 'pyflakes', 'pyflakes'

Buildout скачает со специального сайта рецепт djangorecipe и zc.recipe.egg и выполнит их.

Самый интересный для нас — djangorecipe. Этот рецепт делает обёртку вокруг скрипта manage.py, которая изолирует его от дополнительных пакетов, установленных в системе и подключает к нему только яйца, указанные в конфигурации buildout.

Такая конфигурация избавляет нас от нескольких головных болей:

Установка проекта делается в 2 команды:

$ python bootstrap.py --distribute $ bin/buildout

Проект готов, и сервер Джанго для разработчика уже можно запускать. Вместо manage.py [команда] делаем

$ bin/django runserver 0.0.0.0:8000

Батарейки

Но удобная система сборки проекта — далеко не всё, что нужно для ускоренной разработки. Не спешите запускать свеженаписанный код. Выполните проверку статическим анализатором. Очень много ошибок им отлавливаются сразу.$ bin/pyflakes my_new_script.py Undefined variable: test_string, line 2 Variable used before definition: another_var, line 5

(Обращение к 2 переменным, которые не были объявлены. Без анализатора мы бы дважды запускали сайт и видели баги.)

После анализаторов программистам нужны дебаггеры. Их в Питоне есть масса, но из тех, что мы проверили в команде, самый удобный — PuDB, это интерактивная среда, которая работает как Midnight Commander в текстовом режиме и напоминает старые добрые QBasic или борландовские среды из 80-х годов.

Чтобы его запустить, нужно вставить команду там, где требуется отладка:

import pudb; pudb.set_trace()

внутри дебаггер очень хорошо настраивается (Ctrl+P), и из него можно также зайти в консоль отладки на IPython. Это мощная консоль Питона с автозавершением всего, что можно, и макросами, чтобы записать и повторять какие-то действия, например, отлаживая модули.

Ещё один очень полезный инструмент — панель отладки, или Django Debug Toolbar. По ссылке прямо в выданной странице есть панель со всеми параметрами построения страницы, списком шаблонов и переменными всех контекстов. Если страница не «упала», но выводит что-то не то, не нужно править код, можно просто посмотреть контексты.

Что же если страница падает? Обычно, если там происходит какая-то неясная ошибка, нужно сделать следующее:

Если же в проекте установлен Werkzeug, вместо 5 действий нужно сделать одно, потому что это приложение выдаёт консоль посмертной отладки прямо в окне броузера. Причём в любом уровне стека вызова! Для многих проблем этого вполне достаточно.

Если код работает как надо, его нужно причесать для читаемости.

$ bin/pep8 my_new_script.py 'Import *' is very bad style. Line 2 Expected 2 blank lines, found 1. Line 5.

HAML, Sass, OOCSS

Во время работы с любым кодом мы чаще всего не пишем его, а читаем. Поэтому сильно ускоряет работу именно язык разметки, который можно быстро читать, а не IDE, в которой можно быстро писать.

HAML — это, по сути, язык XML, очищенный от мусорных символов, и в нём есть значимая табуляция. Если вы программируете на Джанго, значит вы знаете Питон и его табуляцию. Аттрибуты тэгов пишутся как JSON, тэги Джанго поддерживаются, некоторые даже автоматически закрываются:

- load i18n compress %html %head %title - block title Скоростная разработка в Джанго %body #menu.page.oldSchool - block menu .line.title_bar .unit.size1of2 %a.site_logo{'href': "/"} Скоростная разработка в Джанго .unit.size1of2.lastUnit - include 'language_selector.haml' #body - block body

Он преобразуется в такой документ:

{% load i18n compress %} <html> <head> <title> {% block title %} Скоростная разработка в Джанго {% endblock %} </title> </head> <body> <div> {% block menu %} <div> <div> <a href="/">Скоростная разработка в Джанго</a> </div> <div> {% include 'language_selector.haml' %} </div> </div> {% endblock %} </div> <div> {% block body %} {% endblock %} </div> </body> </html>

Сколько раз у вас разваливалась вёрстка из-за не там закрытого тэга? В языке HAML закрывающих тэгов нет. Теги закрываются там, где кончается уровень табуляции. Такой документ проще править и добавлять уровни вложенности, и проще читать — в нём в 1,5 раза меньше строк и на четверть меньше букв. Единственный проигрыш в символах — JSON для аттрибутов, но это не большая потеря.

В этом проекте используется HamlPy, который, как видно из листинга, поддерживает тэги Джанго и обычный HTML, если языка Haml вам будет недостаточно, например:

<option {% if option.selected %}selected{% endif %}>{{ option.value }}</option>

Аналог Haml для CSS — язык Sass. В проекте Sass поддерживаются 2 вида разметки: SCSS (аналог CSS с фигурными скобками) и SASS (аналог Haml и Питона, с табуляцией). Я предпочитаю последний как более лаконичный. Самый большой выигрыш от Sass — сжатие всех проприетарных правил, как *-linear-gradient, в один вызов:

@import bourbon .action +linear-gradient(top, #6db3f2 0%, #54a3ee 50%, #3690f0 51%, #1e69de 100%)

Развернётся в большой список со всеми реализациями градиента (-moz-..., -o-..., -webkit-… и т.д.). Здесь пример не привожу, но скажу только, что язык Sass поддерживает циклы и условные блоки @if… else. Существует аналогичный проект Less-CSS, и его при желании тоже можно подключить к django-compressor, но он не позволит делать такие манипуляции, как циклы и перегруппировки аргументов.

Стили можно вкладывать один в другой:

.class1 font-weight: bold > .class2 font-style: italic

Результат:

.class1 { font-weight: bold; } .class1 > .class2 { font-style: italic; }

Object Oriented CSS — замечательный проект Николь Салливан, в котором она сумела обуздать разростающиеся, как плесень, правила, объединила и обобщила некоторые базовые приёмы и получила очень компактную разметку. Если вы не знакомы с OOCSS, посмотрите её выступления (на английском) и примеры кода с сайта проекта.

Вот самые ходовые заготовки. Таблицы (в разметке HAML):

.line .unit.size1of3 левая колонка .unit.size1of3 центральная колонка .unit.size1of3.lastUnit правая колонка

«Медиа-блок», то есть картинка слева и текст, не обтекающий картинку, справа:

.media %img.img{'src': '{{ message.author.picture.url }}'}/ .bd= message.text

Есть также заготовка шаблона страницы, блок контента (прямоугольник с шапкой, телом и основанием). В моём проекте OOCSS встроен как суб-репозиторий, и его можно периодически обновлять с ГитХаба.

Что добавить

Пока что проект представляет собой репозиторий Mercurial, и ваш новый проект будет привязан к моему репозиторию. Я советую удалять hgrc. Возможно, следует сделать более удобный инсталлятор. Чтобы исправить этот недостаток, клонируйте проект и присылайте ваши запросы на слияние.

В ближайших планах:

Буду рад отзывам, форкайте проект, присылайте запросы на слияние.

Добавление: на ВедреБитов попросили добавить инструкции по установке сторонних компонент. Отвечаю: сторонние компоненты вручную устанавливать не надо. SASS, Pyflakes и другие приложения установит buildout.

habr.com

Интеграция Django CMS – G-Core Labs

Перед тем, как предпринимать какие-либо шаги создайте резервные копии файлов и базы данных. Плагин интеграции с CDN предназначен только для сайтов работающих по стандартным шаблонам CMS. Если вы вносили изменения в логику работы CMS, плагин может не cработать.

Сконфигурируйте файл urls.py для указания статических файлов в нужной директории (также как в директории media).

Было:

# This is only needed when using runserver. if settings.DEBUG: urlpatterns = patterns('', url(r'^media/(?P<path>.*)$', 'django.views.static.serve', # NOQA {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), ) + staticfiles_urlpatterns() + urlpatterns # NOQA #urlpatterns = static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Стало:

# This is only needed when using runserver. if settings.DEBUG: urlpatterns = patterns('', url(r'^static/(?P<path>.*)$', 'django.views.static.serve', # NOQA {'document_root': settings.STATIC_ROOT, 'show_indexes': True}), ) + urlpatterns # NOQA urlpatterns = patterns('', url(r'^media/(?P<path>.*)$', 'django.views.static.serve', # NOQA {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), ) + staticfiles_urlpatterns() + urlpatterns # NOQA #urlpatterns = static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

 Измените файл settings.py, чтобы Django использовал CDN.

Ищем следующие строки:

STATIC_URL and MEDIA_URL variables and modify them to reflect your CDN url or Zonealias similar to: STATIC_URL = 'http://CNAME/static/' MEDIA_URL = 'http:/CNAME/media/'

Вместо CNAME укажите CNAME-запись, которую задали в личном кабинете G-Core при создании ресурса. Проверьте работает ли ваш домен, прежде чем использовать ее для интеграции.

Теперь все файлы из директорий static или media будут отдаваться через CDN. Тем не менее, есть некоторые файлы, которые Django использует для работы самой CMS. Чтобы завершить интеграцию, необходимо переместить эти файлы в директорию STATIC_ROOT, определенную в файле settings.py. Для копирования этих файлов убедитесь, что все выполняется в виртуальном окружении из рутовой директории Django:

$ source env/bin/activate

После этого перейдите в директорию вашего приложения (сайта), где расположен файл manage.py, и выполните следующую команду:

$ python manage.py collectstatic

Теперь все внешние статические файлы будут перемещены в директорию STATIC_ROOT, содержимое которой отдается через CDN.

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

<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}test.css">

Интеграция с CDN завершена! Рекомендуем проверить html-код сайта, чтобы убедиться, что URL-адреса были верно изменены.

Для этого нажмите F12 или откройте «Инструменты разработчика», перейдите на вкладку Network, обновите страницу. В ссылках на статические файлы вы должны увидеть CNAME-запись из личного кабинета вместо вашего доменного имени.

support.gcorelabs.com

DTemplate — шаблон django проекта для ускорения разработки / Хабр

Доброго времени суток, уважаемый All!

Хочу представить на суд хабрасообщества проект, над которым я работал последнее время. Очень хочу получить конструктивную критику и предложения по его улучшению.

DTemplate — проект с открытым исходным кодом, который дает возможность пользователям django иметь многочисленные инструменты упрощающие работу при создании нового django проекта без необходимости настраивать их каждый раз.

DTemplate создавался для собственных целей из уже существующих приложений с открытым кодом. Публикуя данный проект я хотел бы выразить огромную благодарность людям, которые предоставили возможность доступа к своим интеллектуальным трудам.

Поддержка проекта
Работа с БД
Development режим
Production режим
Организация работы с Django проектом
Организация работы со статикой
Организация работы с файлами шаблонов
  1. Побудить разработчиков к росту числа новых проектов с открытым исходным кодом и упростить работу над ними.
  2. Поддержать и укрепить позиции существующих проектов на базе которых создан DTemplate.
Проект DTemplate находится в стадии активной разработки и не имеет фиксированных версий на текущий момент.

Адрес проекта: bitbucket.org/yureg/dtemplate Скачать DTemplate выможете выполнив комманду:hg clone [email protected]/yureg/dtemplate

Python

JavaScript

CSS

UPD: Перенес в блог Django Framework

habr.com

Архитектура шаблонов Django · Тихо, тихо… обо всем

Я решил поделиться структурой, которую я использую для шаблонов. Я ее использую как в новых проектах, так и при реструкторизации уже существующих приложений. Этот процесс направлен на получение повторно используемых приложений с сохранением гибкости. Эта структура родилась постепенно в ходе многих тысяч часов работы с шаблонами и является удобной для меня. Ваши предпочтения могут отличаться. И вы же знакомы с организацией шаблонов в поддиректориях приложений? Верно?

Перед тем, как начать, я хотел бы показать одно из моих Django приложений с шаблонами. Gazette - приложение-блог (да, еще одно), над которым я работал и которое я буду использовать в качестве примера в данной статье.

gazette/ **init**.py models.py views.py static/ ... templates/ gazette/ __base.html __l_single_col.html __l_right_sidebar.html __l_left_sidebar.html _article_full.html _article_summary.html _author_list.html _author_name.html _category_list.html _navigation.html _tag_list.html article_detail.html article_list.html author_list.html category_list.html tag_list.html

Знайте ваши шаблоны

Первый принцип процесса разработки моих шаблонов пришел прямиком из The Zen of Python:

Читаемость имеет значение. В проектировании структуры шаблонов это означает, что достаточно бросить взгляд на директорию шаблонов, чтоб мгновенно понять для каких целей служит тот или иной шаблон. И что более важно, когда ко мне приходит клиент с изменениями в его приложении, мне не нужно разбираться в каком файле находиться необходимый код. Поиск должен затрагивать не более двух шаблонов. В итоге я разделил все свои шаблоны на три общие категории: расширяемые шаблоны, включаемые шаблоны и шаблоны страниц.

Расширяемые шаблоны

Расширяемые шаблоны формируют основную структуру ваших HTML страниц. Это шаблоны, основная цель которых быть расширенными другими шаблонами с помощью тега {% extends %}. Чтоб избежать перемешивания расширяемых шаблонов с шаблонами страниц я принял за правило никогда не вызывать расширяемые шаблоны напрямую из кода представлений (view) и никогда не расширять шаблоны, которые не являются расширяемыми. По соглашению о наименовании, я начинаю все свои расширяемые шаблоны с двойного подчеркивания: __base.html. Самым важным шаблоном является __base.html, который содержит скелет HTML для всех ващих страниц. Обычно этот шаблон делается минимальным. У меня он обычно выглядит следующим образом:

{% load staticfiles i18n %} <header> {% include "gazette/_navigation.html" %} </header> <div role="main"> <div> {% block content %} {% endblock %} </div> </div>

Как вы можете заметить, я использую Bootstrap для новых проектов, но этот же подход справедлив и для проектов без Bootstrap. Когда я пишу базовый шаблон, я стараюсь делать это осторожно. Я думаю: “Когда другой программист (включая меня через полгода) прийдет в этот проект и ему понадобится создать новый шаблон, могу ли я быть уверенным, что он сможет сделать любой шаблон не меняя базовый”. Результат оборачивается большим кол-вом тегов {% block %}, которые можно переопределить или расширить при необходимости. О теге {% block %} поговорим чуть позже. Если у вас очень простое приложение, то вам многое не нужно из того, что может предоставить __base.html для вашей структуры. И вы можете перейти к написанию шаблонов страниц и включаемых шаблонов. Но если ваше приложение достаточно сложное, то вам может понадобиться создать несколько различных структурных шаблонов (layout templates). В Gazette я использую три структурных шаблона, имена которых начинаются с __l_ (и снова их назначение определяется мгновенно из названия): __l_single_col.html, __l_right_sidebar.html, __l_left_sidebar.html. Я храню их в одной директории с остальными шаблонами согласно принципу:

Плоское лучше, чем вложенное

С другой стороны, если вам необходимо более трех шаблонов, то вы можете поместить их в поддиректорию layouts/. Когда я работаю над проектов с очень сложной сеткой, то часто создаю такую поддиректорию с шаблонами: layouts/100.html, layouts/25_75.html, layouts/50_50.html и т.д. Например один из моих структурных шаблонов, __l_right_sidebar.html :

{% extends "gazette/__base.html" %} {% block content %} <div> <div> {% block main_col %}{% endblock %} </div> <div> {% block side_col %}{% endblock %} </div> </div> {% endblock %}

Это очень простой шаблон - настолько простой, что может показаться, что он и не нужен. Но, поверьте мне, этот маленький шаблон предоставляет множество преимуществ при создании ваших шаблонов страниц.

Включаемые шаблоны

Включаемые шаблоны - это шаблоны, которые планируете включать в шаблоны страниц с помощью тега {% include %}. Как и с расширяемыми шаблонами я строго слежу за применением включаемых шаблонов. Вы можете рассматривать их и как некие блоки, из которых строится ваш сайт, собираясь в шаблоне страницы. Есть две основные причины сделать часть вашего сайте включаемым:

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

Шаблоны страниц

Шаблоны страниц - ядро вашего приложения. Но если вы перед этим создали несколько хороших расширяемых шаблонов и возможно даже несколько включаемых, то вы заметите насколько просто связать все вместе. Это просто клей, который связывает ваши шаблоны вместе. Ваши шаблоны страниц - это именно то, что вызывается из кода представлений (views). Они гармонично связывают расширяемые и включаемые вместе. Например, article_detail.html :

{% extends "gazette/__l_right_sidebar.html" %} {% block title %}{{ article.title }} | {{ block.super }}{% endblock %} {% block main_col %} {% include "gazette/_article_full.html" %} {% endblock %} {% block side_col %} {% include "gazette/_tag_list.html" with tags=article.tags.all %} {% include "gazette/_category_list.html" with categories=article.categories.all %} {% endblock %}

Как вы видете, эта страница использует __l_right_sidebar.html. Главная колонка содержит полный текст статьи. Боковая колонка содержит список тегов и список категорий. Этот шаблон настолько легко читаем, насколько возможно. Я упоминал, что выделение отдельного уровня шаблонов структуры приведет к увеличению возможностей и это так. Если вы решите, что список тегов и категорий лучше расположить в левой колонке, то вам достаточно будет лишь поменять первую строку шаблона article_detail.html на:

{% extends "gazette/__l_left_sidebar.html" %}

и содержимое переместится именно туда, куда надо. Дальше больше. Если другой разработчик предпочитает структуру 75% - 25% вместо 66% - 33%, которую использую я в __l_right_sidebar.html, то от может переопределить шаблон:

{% extends "gazette/__base.html" %} {% block content %} <div> <div>{# this is now 75% of the page #} {% block main_col %}{% endblock %} </div> <div>{# this is now 25% of the page #} {% block side_col %}{% endblock %} </div> </div> {% endblock %}

и все страницы, которые его используют, изменятся нужным образом. Согласно принятому соглашению о названиях, когда это возможно, я стараюсь следовать соглашению об именях, принятому в Django generic views, т.е. _list.html, _detail.html, _form.html и т.д. Если шаблон не попадает под эти категории, то просто старайтесь давать ему название, четко определяющее то представление (view), к которому он относится.

Заметки о {% block %} и {{ block.super }}

Система наследования шаблонов в Django удивительно мощная и тут очень просто увлечься. Я часто вижу как в базовых шаблонах (т.е. расширяемых) разработчики пишут контент по-умолчанию в блоках:

{% block main %} This is content for the front page of my application. {% endblock %}

предполагая, что он будет переопределен при расширении данного шаблона в других страницах. Я хочу предостеречь вас от использования этого подхода, т.к. он смешивает ваши расширяемые шаблоны с шаблонами страниц и становиться сложнее находить то месно, которое нужно изменить в каждом конкретном случае. (“Где это ? В frontpage.html или в base.html?”). Вместо этого рассматривайте содержимое блоков в расширяемом шаблоне как текст, который может быть использован в разных шаблонах страниц с помощью {{ block.super }}. Простейший пример - это элемент страницы < title > . Я часто вижу следующую структуру в базовом шаблоне:

<title> {% block page_title %}{% endblock %} Site Title </title>

Это не только кажется мне не элегантным (Куда нужно поместить разделитель между заголовком страницы и заголовком сайта, т.е. “Заголовок страницы | Заголовок сайта” - в базовый шаблон или в шаблон страницы? А как быть со страницами, которым не нужен заголовок ?), но и ограничивает разработчика в том, что он может сделать без внесения изменений в базовый шаблон. И я гораздо реже вижу более простую структуру:

<title>{% block title %}Site Title{% endblock %}</title>

Аналогично с css или другими включениями:

<link rel="stylesheet" type="text/css" href="base.css" /> {% block styles %} {% endblock %}

или, боже упаси,

{% block styles %} <link rel="stylesheet" type="text/css" href="base.css" /> {% endblock %} {% block extra_styles %} {% endblock %}

Это запутаннее и избыточнее, чем простое:

{% block styles %} <link rel="stylesheet" type="text/css" href="base.css" /> {% endblock %}

Позже в ваших шаблонах страниц вы можете добавить другие стили следующим образом:

{% block styles %} {{ block.super }} <link rel="stylesheet" type="text/css" href="specific_page.css" /> {% endblock %}

Аналогично и с заголовком:

<title>{% block title %}Specific Page | {{ block.super }}{% endblock %}</title>

Это, на мой взгляд, элегантнее - блоки лучше названы, их меньше, они более точно выражают структуру - и если вы захотите отказаться от заголовка по-умолчанию или стилей по-умолчанию, не отказываясь от всего базового шаблона, вы свободно можете это сделать. {{ block.super }} - очень мощная штука. Используйте ее внимательно.

Несколько заметок на последок

Интернационализация

Пожалуйста, используйте интернационализацию ваших шаблонов. Особенно, если вы пишите приложения для повторного использования. Это очень просто с использованием тегов {% trans %} и {% blocktrans %}.

{% include %} и {% with %}

Довольно долгое время я писал ужасный код наподобее этого:

{% with article.categories.all as categories %} {% include "gazette/_category_list.html" %} {% endwith %}

До тех пор, пока не заметил [удобный синтаксис], который доступен с версии Django 1.3:

{% include "gazette/_category_list.html" with categories=article.categories.all %}

Для дополнительной инкапсуляции, попробуйте передать в ваши включаемые шаблоны эксклюзивный контекст:

{% include "gazette/_category_list.html" with categories=article.categories.all only %}
Закрывающиеся теги HTML и язык шаблона Django по своей природе - вложенный, что иногда снижает читаемость.

Особенно при работе с большими блоками. Язык шаблонов Django имеет дополнительный необязательный синтаксис, который помогает отслеживать ваши блоки:

{% block camelot %} Pretend this is so much content that you lose track of what block you're in before the end. {% endblock camelot %}

А в других случаях? Я часто использую комментарии для имитации этого для других тегов шаблона и HTML:

<div> A very long article. </div>{# /.article-content #}

что, как я заметил, сильно повышает наглядность кода.

Обрабатывайте HTML и теги шаблона одинаково

Я всегда считал, что отступы для HTML тегов должны обрабатываться отдельно от отступов тегов шаблона. Возможно это ошибочное мнение было основано на том, что структура результирующего HTML кода имеет большее значение. Это все приводило к тому, что большое количество кода имело вид:

{% block navigation %} <nav> {% with bookpage.book.pages.all as bookpages %} <ul> {% for page in bookpages %} {% if page != bookpage %} <li><a href="{{ page.get_absolute_url }}">{{ page.name }}</a></li> {% else %} <li>{{ page.name }}</li> {% endif %} {% endfor %} </ul> {% endwith %} </nav> {% endblock %}

Этот код можно сделать более читабельным, если рассматривать теги HTML и теги шаблона как равноправные:

{% block navigation %} <nav> {% with bookpage.book.pages.all as bookpages %} <ul> {% for page in bookpages %} {% if page != bookpage %} <li><a href="{{ page.get_absolute_url }}">{{ page.name }}</a></li> {% else %} <li>{{ page.name }}</li> {% endif %} {% endfor %} </ul> {% endwith %} </nav> {% endblock %}

Это ли не достаточная причина?

Оригинал: Architecture for Django templates

Please enable JavaScript to view the comments powered by Disqus. comments powered by

knigun.com

Создание сайтов на Django, часть 7. Совершенствуем шаблоны.

В прошлой статье создали нормальные url для нашего блока и прописали для них view. Теперь остался последний штрих — шаблоны.

Django имеет достаточно интересную систему шаблонов, которая даже вынесена в отдельный проект — Jinja. Даже отказываясь от джанги, от её шаблонов так просто отказаться не получается.

В основе шаблонов Django находятся тэги, которые размещаются в HTML-страницах. Далее страница «скармливается» методу render() (который мы использовали при создании view), выполняются инструкции, написанные в тэгах и отрендеренная страница возвращается в качестве ответа.

Тег внутри шаблона заключается в последовательность из фигурной скобки и знача процента — {% … %}. Существует другой, частный, но очень часто используемый, вид тэга — тэг вывода {{ … }} — в этот тэг передается не инструкция, а переменная для вывода.

Тэги позволяют применять конструкции for и if:{% for entry in entries %} … {% endfor %}и{% if entry.has_comments %} … {% endif %}Обратите внимание, что, в отличии от Python, в шаблонах необходимо указывать закрывающие тэги.

Для тэга вывода используется второе понятие языка шаблонов — фильтр. Указывается он как вертикальная черта после переменной для вывода и служит как-бы инструкцией для обработки переменной перед выводом. Например, {{ entry.title|upper }} превратит все буквы заголовка записи в заглавные. Фильтров может быть несколько, тогда каждый из них отделяется вертикальной чертой. Выполняются фильтры слева направо.

Напоследок следует сказать, что Django позволяет создавать свои собственные тэги и множество приложений этим пользуется. Обычно модули с тэгами располагаются внутри каталога templatetags внутри приложения.

Теперь приступим непосредственно к практике. Для начала научимся структурировать шаблоны. Для создания структуры используются тэги {% extends %} и {% bl

truecryer.wordpress.com

django - django cms [aldryn newsblog] заменить шаблон для плагина

Если я правильно понимаю ваш вопрос (он здесь поздно), вам нужно переопределить шаблоны плагинов на основе экземпляра плагина, потому что взлом шаблонов django - это не путь (я согласен).

Django CMS позволяет вам переопределять шаблоны плагинов на основе экземпляра. Как показано в http://docs.django-cms.org/en/develop/how_to/custom_plugins.html?highlight=get_render_template#the-simplest-plugin

В подклассе CMSPluginBase добавьте следующее:

def get_render_template(self, context, instance, placeholder): # criteria goes here return 'sometemplate.html'

Что касается того, как узнать, какой шаблон отображать, когда (критерии), вы можете сделать несколько вещей.

Используйте обратный идентификатор страницы:

page = instance.page templates = { 'homepage': 'plugin_home.html', 'about': 'plugin_about.html', 'contact': 'plugin_contact.html', } return templates[plugin.page.reverse_id]

Этот подход имеет несколько недостатков:

Используйте расширение страницы, чтобы установить категорию на странице:

Оформить заказ http://docs.django-cms.org/en/develop/how_to/extending_page_title.html С помощью этого подхода вы можете установить некоторую категорию на несколько страниц, и вы можете настроить таргетинг на несколько страниц одним выстрелом:

page = instance.page extension = get_page_extension(page) # Check out docs for this templates = { 'category_1': 'plugin_category_1.html', 'category_2': 'plugin_category_2.html', 'category_3': 'plugin_category_3.html', } return templates[extension.category.name]

Плюсы:

Минусы:

Используйте переменную контекста шаблона: в ваших шаблонах, в зависимости от того, как вы создаете свои плагины, вы можете предоставить переменную контекста так:

{% with category='category_1' %} {% placeholder 'content' %} {% endwith %}

или

{% with category='category_1' %} {% render_plugin yourplugin %} {% endwith %}

Затем в вашем методе get_render_template вы можете получить доступ к этой переменной контекста и сделать следующее:

# Use .get() to provide fallback category = context['category'] templates = { 'category_1': 'plugin_category_1.html', 'category_2': 'plugin_category_2.html', 'category_3': 'plugin_category_3.html', } return templates[category]

Плюсы:

Минусы:

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

Возможно, вы можете сделать логику всего шаблона выше в mixin для использования во всем своем проекте.

qaru.site


Prostoy-Site | Все права защищены © 2018 | Карта сайта