create html php template
Creating html templates using PHP
Im learning a lot about how MVC frameworks work by looking around and studying existing ones. It seems that every framework I see has a layout where each method in each controller has its own template file. So there will be a login template, a logout template, register, so on and so on.
My question is, how and why would you create a template for the entire page all within one file. Lets say you wanted to show the login form on more than one page, wouldn’t you have to create the login form for each template that you want it to display on? Doesn’t that go against the don’t repeat yourself rule (DRY)?
The way i’ve been doing things so far is I’ve been creating liitle chunks of templates and then combining them to create each page. So instead of doing something like this,
I’ve been doing this
As alway, I would just like to know the proper way to do it, along with how and why. It just seems to go against the DRY rule.
4 Answers 4
You should check out the concepts of ‘layouts’ and ‘view helpers’. While I’ve linked to the Zend Framework version of those concepts, other MVC frameworks (and the MVC concept) should have them as well.
To include something like a login form on all pages, a view helper can be used. That view helper could display the current user, or display a login form, depending on the login status. View helpers may be included in the layout, or included by the specific controller (as long as MVC framework allows some kind of named render segments).
Веб-компоненты. Часть 3: html шаблоны и импорты
Вступление
Приветствую коллеги. Данная статья является третьей и последней статьей в серии статей о веб-компонентах.Первые две статьи доступны по ссылкам:
В данной статье речь пойдет о элементе а также об HTML импортах.
HTML Templates элемент
Элемент представляет собой инструмент, позволяющий хранить контент на стороне клиента без его рендеринга на страницу, однако с возможностью его отображения в процессе исполнения посредством JavaScript.
Содержимое элемента при парсинге страницы обрабатывается исключительно в части валидации содержимого, но без его рендеринга (согласно спецификации, при рендеринге этот элемент ничего не представляет). Содержимое элемента можно клонировать и вставлять в документ из скриптов, что и используется как самостоятельно для шаблонизации так и при создании веб-компонентов.
Содержимое
однако, вне элемента такой синтаксис валидным не является. При этом пропуск закрывающего тега
Все элементы указанные внутри тега в html коде не являются его дочерними элементами.
Бразуеры при создании элемента создают DocumentFragment чьим документом является т.н. approptiate template contents owner document, определяемый по этому алгоритму, документа в котором указан и указывает значением свойства .content созданный DocumentFragment.
То есть свойство .content у элемента template содержит DocumentFragment, и элементы, которые в html коде были указаны внутри тегов являются дочерними элементами именно этого DocumentFragment.
Клонирование шаблона
Show me the code ©
Использование шаблонов действительно очень простое. Я продолжу пример компоненты таб, с кодом которых я работала в примерах предыдущих статей.
В конструкторе каждого класса я сохраню свойство template. Для TabNavigationItem это будет:
a для TabContentItem:
Получившийся код можно посмотреть тут
В этом примере оба шаблона указаны в html, что выглядит громозким и не есть гуд. Это плавно переводит нас к теме:
HTML импорты
Импорты представляют собой HTML документы которые подключены в качестве внешних ресурсов другим HTML документом. Система взаимоотношений между документами хорошо описана в черновике спецификации и не является предметом данной статьи.
Общая схема видна на изображении:
.
Для того чтобы реализовать импорты был добавлен новый тип в HTML link types (значения атрибута rel).
Расширения, предлагаемые черновиком спецификации предлагаются в АПИ HTMLLinkElement: добавляется свойство import, доступное только для чтения и содержащее импортируемый документ.
В спецификации отдельно указано что один и тот же объект должен будет возвращаться всегда.
В контексте импортов, есть так называемый мастер-документ (master document), которым является тот документ, который импортирует ресурсы одновременно не являясь при этом чьим либо импортируемым ресурсом.
ContentSecurityPolicy такого документа должна ограничивать все импорты. Так, если Content Security Header Field поставлен в значение импорта, браузер должен принудительно исполнять политику именно мастер-документа к импортируемому документу.
На практике
Для компонента таб, я создаю папку templates. В ней я создам два файла, в которые я перенесу разметку компоненты.
В файла index.html я импортирую шаблоны:
Финальную версию можно взять тут.
О поддержке
Поддержка HTML templates: Edge c 16, Firefox c 59, Chrome c 49, Safari c 11.
С поддержкой импортов печальнее: Chrome c 49.
Потому примеры из этой статьи можно посмотреть только в последних Chrome.
Почтитать подробнее о шаблонах и импортах:
На этом все, спасибо за внимание,
Таня
Перевод: Шаблонизаторы в PHP
Первод статьи, автором которой является Fabien Potencier, ведущий разработчик и идеолог Symfony. Статья поднимает обсуждение о шаблонизаторах PHP в целом и представляет Twig — быстрый и функциональный шаблонизатор.
————————————————————————
Итак, вы считаете что PHP это уже шаблонизатор? Так думал и я… и очень долго. Но недавно я передумал. Несмотря на то что PHP может использоваться как шаблонизатор, его синтаксис ужасен для этих целей.
На протяжении нескольких лет я продвигал наиболее успешные концепции веб-разработки, одной из которых является практика отделения отображения от логики приложения. Под моим влиянием, как ведущего разработчика Symfony, все проекты в Sensio спроектированы с учетом MVC архитектуры. Несомненно, это упрощает работу нескольких человек над одним проектом. Программисты работают над кодом (контроллеры и модель) и веб-дизайнеры (верстальщики) над отображением.
Шаблонизатор должен способствовать выполнению концепции разделения. Язык шаблонизатора должен быть достаточно гибким и мощным чтобы упростить внедрение логики отображения, не дав возможности травмировать логику приложения расширенными возможностями.
И когда я несколько дней назад спросил о лучших и популярных шаблонизаторах на PHP в Твиттере, некоторые, естественно, ответили «сам PHP». Это было вполне предсказуемо, ведь несколько недель назад я бы ответил так же.
Так почему же PHP (уже) не является удобным шаблонизатором?
Почему люди до сих пор думают что PHP это шаблонизатор? По-большей части, потому что PHP начал свое существование как язык-шаблонизатор, но в последнее годы он развивался другим путем. Если вы считаете что PHP до сих пор является шаблонизатором, расскажите мне хотя бы об одном изменении в языке, которое улучшило его как шаблонизатор? Я не могу вспомнить ни одого.
Шаблонизаторы стремительно развивались начиная с 1995 года, когда вышел первый релиз PHP/FI:
И значимым фактом является то, что PHP не поддерживает множество возможностей современных шалонизаторов.
Я буду использовать Django как пример современного шаблонизатора в своих примерах по причинам которые вы поймете позже.
Ниже описано то что я хочу видеть в современном шаблонизаторе:
Краткость
PHP многословен. Только для того чтобы просто вывести переменную необходимо не менее 14 символов (нет, использование более компактного непреемлемо):
И PHP становиться нелепо многословен при необходимости экранировать вывод (да, экранирование данных полученных из небезопасного источника является обязательным)
Сравнити это с двумя примерами написанными на Django:
Синтаксис ориентированный на шаблоны
По больше части это дело вкуса, но шаблонизаторы должны иметь красивые решения частых случаев. Для примера предположим, что необходимо отобразить массив и вывести текст по умолчанию, если этот массив пуст. Это очень распространенный случай, но версия на PHP не очень читаема:
Версия на Django гораздо лучше — спасибо конструкции else для тега for :
Повторное использование
PHP развивался с учетом возможности повторного использования кода. Начиная с 5-й версии реализация объектов сделала шаг вперед и, после того как в следующей версии будут поддерживаться типажи, мы получим язык программирования удовлетворяющий наши требования. Я действительно рад всем этим изменения т.к. это помогает мне писать программы лучше, но это не имеет значения когда все что тебе нужно — это написать шаблон.
В Django ввели наследование шаблонов несколько лет назад, пытаясь повторить наследование классов в шаблонах:
Это элегантно, просто для восприятия и действительно мощно. Настолько мощно, что многие шаблонизаторы сейчас поддерживают эту возможность «из-коробки».
Безопасность
Я не говорю что PHP небезопасен. Но я хочу сказать что экранирование переменных в шаблоне это просто кошмар, как и продемонстрировал ранее:
Конечно, вы можете написать свою функции и сделать ее котороче, но это не то о чем я говорю:
Я считаю что безопасность должа быть на уровне по умолчанию, особенно для шаблонов, которые зачастую пишут не программисты, которые не обращают внимания на возможные XSS и CSRF уязвимости.
Насколько я знаю, Symfony был самым первым фреймворком поддерживающим автоматическое экранирование в шаблонах (2006); и все основные фреймворки пошли тем же путем: в Django по умолчанию включено экранирование начиная с версии 1.0, и в Ruby on Rails это тоже появится с версии 3.
Включенное автоматическое экранирование так же означает что аудировать(?) приложение гораздо проще. Взгляните на примеры с отключенным экранированием:
Конечно, я в курсе возможных проблем с автоматическим экранированием. Вам все так же нужно быть внимательными при экранировании переменных в JavaScript, но это гораздо проще чем экранировать абсолютно все вручную.
Режим «Песочницы»
Эта возможность особенно необходима в том случае когда пользователи могу сами редактировать шаблоны сайта (например, из системы управления сайтом). Это не является необходимость, однако бывает важно. Исполнение шаблонов в «песочнице» означает возможность ограничить то что может быть выполенно: методы/функции которые можно вызывать, теги которые можно использовать и т. д.
Ни у PHP, ни у Django нет такого режима, так что продолжайте читать эту статью для дальнейшего объяснения этой секции.
Альтернативные шаблонизаторы для PHP
Итак я приступил к поиску шаблонизатора который имел бы все возможности упомянутые выше. Я нашел много разных шаблонизаторов, но ни один из них не удовлетворил все мои нужды. Следующий раздел о некоторых из них, среди которых есть и рекомендованные мне ответами в Твиттер.
На PHP написан миллион шаблонизаторов, я тестировал только самые «популярные». И т. к. я их не использую мной могут быть допущены ошибки использования того или иного шаблонизатора.
Smarty и Smarty 3
Это то что первым пришло в голову. И сам язык шаблонов Django был «навеян» Smarty. Smarty это стандарт де-факто для PHP.
PHPTAL
PHPTAL очень приятный проект, использующий синтаксис шаблонов Zope. Очень хорошо спроектирован, имеет большое количество возможностей, но не умеет работать с не-HTML шаблонами, что может стать проблемой, если вы хотите использовать один язык шаблонов также для писем и RSS лент.
Еще я думаю что синтаксис может оказаться непонятным веб-дизайнерам, особенно при использовании расширенных возможностей, таких как наследование шаблонов:
Одним из важных достоинств можно назвать автодополнение в среде разработки и гарантировано «правильно сформированный» HTML код.
eZ Components Templates
Компонент шаблонов в составе eZ Components так же предоставляет очень удачный языком шаблонизатора. Здесь присутвуют почти все возможности шаблонизаторов… даже чресчур, если вы хотите знать мое мнение:
Наследование шаблонов не поддерживается, и меня беспокоит скорость работы. Это самая медленная библиотека что я тестировал, и сильно медленне остальных.
Dwoo — это, прежде всего, интересный проект. Он позиционирует себя как альтернативу Smarty. И их работа стоит внимания:
Dwoo подражает Smarty, но также вносит и свои дополнения, например, наследование шаблонов, и работает гораздо быстрее Smarty.
К сожалению, у Dwoo нет «песочницы» и ядро библиотеки недостаточно гибкое.
Calypso
Calypso это реализация шаблонизатора Django на PHP. Я упоминаю о нем т.к. он клон Django и на него ссылались в Твиттере. Но сам автор считает что его реализация неудачна.
Когда я приступил к поиску PHP шаблонизатора, я сосредоточился на библиотеках копирующих поведение Django. Спустя несколько часов «гугления» был найден Twig. Его автором является Armin Ronacher, известный по проекту of Jinja (шаблонизатор для Python). Несомненно я испытываю крайнее уважение к Армину за его замечательную работу над Jinja. Twig скорее похож на Jinja, чем на Django, как описано в реализации.
Он написал Twig в 2008 году для платформы блогов Chypr. Но больше не возвращался к разработке и больше занимался разработкой на Python.
Когда я взглянул на код, я сразу понял что это то что я ищу. Главное отличие от Calypso в том что Twig компилирует шаблоны в обычный PHP-код. Я начал использовать эту библиотеку и в конце этой недели спросил у Армина не желает ли он дать своему проекту новую жизнь. Его ответ был полон энтузиазма, и я приступил к изучению кода. Моя версия сильно отличается от версии Армина, но «лексер» и «парсер» практически оригинальные.
| Библиотека | Время (сек) | Память (Кб) | Шаблонов в секунду |
|---|---|---|---|
| Twig | 3 | 1 190 | 3 333 |
| PHPTAL | 3.8 | 2 100 | 2 632 |
| Dwoo | 6.9 | 1 870 | 1 449 |
| Smarty 2 | 12.9 | 2 350 | 775 |
| Smarty 3 | 14.9 | 3 230 | 671 |
| Calypso | 34.3 | 620 | 292 |
| eZ Templates | 53 | 5 850 | 189 |
Я тестировал простые шаблоны содержащие 1 вывод и итерацию трех элементов, декорируя простым макетом. Время — среднее для 10 запусков; состоящее из 1 компиляции и 10 000 отображений (рендеринга). Для библиотек, не поддерживающих наследование был использован шаблон подключающий шапку (header) и подвал (footer) отдельно и, в библиотеках не поддерживающих автоматического экранирования, экранирование было выполнено вручную.
В случае запуска с уже скомпилированными шаблонами потребление памяти, конечно, гораздо меньше для всех шаблонизаторов, и Twig использует меньше всех памяти.
| Библиотека | Память без компиляции (Кб) |
|---|---|
| Twig | 383 |
| PHPTAL | 598 |
| Dwoo | 1 645 |
| Smarty 2 | 1 634 |
| Smarty 3 | 1 790 |
| Calypso | 614 |
| eZ Templates | 2 783 |
Если вы хотите узнать больше, то посетите сайт, также можете принять участие в обсуждении или стать одним из разработчиков подписавшись на список рассылок для разработчиков.
————————————————————————
Это мой первый перевод. Не только для хабра, а вообще. Поэтому приветствуются комментарии не только про шаблонизаторы и Twig, но и про сам перевод.
Шаблонизация в PHP
Шаблонизация — это работа по интеграции готовой, статичной вёрстки на сайт.
Ведя работу над сайтом, написанном на PHP, мы разрабатываем логику, которая управляет представлением.
Логика — это PHP-сценарии, где происходит объявление переменных, функций, использование массивов и циклов, получение и обработка информации.
Представление — это внешний вид сайта. Сюда входят его страницы, которые содержат общие элементы оформления (шапка, меню, подвал) и контент (страницы, статьи и тому подобное).
Имея на руках готовую вёрстку, надо правильно её внедрить в работающий сайт, чтобы в определённых местах страниц информация выводилась динамически, под контролем PHP-сценариев.
Что такое «шаблон» и причём тут рыба?
Шаблон — это готовая вёрстка страницы или блока, которая состоит только из оформления, и не содержит никакого контента (полезной информации).
Шаблон по своей сути — это обычный PHP-сценарий, который на 90% состоит из HTML-кода и только на 10% из PHP-конструкций. Основная задача программиста в процессе работы над сайтом — это превратить статичные HTML-страницы в динамичные PHP-шаблоны, которые будут использоваться для показа итоговых страниц.
Но если статичная вёрстка страниц не содержит динамического контента, то что будет на его месте до начала внедрения этих страниц? Когда дизайнер или верстальщик хотят показать как будет выглядеть страница на сайте, то вместо реального контента используется так называемая «рыба».
Рыба — это заполнитель. Бессмысленный текст, который используется в вёрстке, чтобы показать как будет выглядеть страница, наполненная контентом.
Проблемы типичного процесса вёрстки
Когда верстальщик работает над несколькими страницами, ему приходится копировать бол́ьшую часть HTML-кода между страницами, так как эти страницы содержат много повторяющихся элементов: подключение стилей, шапка сайта с логотипов, футер сайта, различные меню и тому подобное.
В результате, когда дело доходит до правок, то при необходимости поменять что-нибудь в той же шапке, это изменение нужно будет сделать во всех HTML-файлах, чтобы они выглядели одинаково. Конечно, такой мартышкин труд никому не понравится.
Общие фрагменты страниц сайта
Взглянув на страницы практически любого сайта, можно заметить их сходство друг с другом. Ведь все страницы состоят из общих частей, которые не меняются, а также из областей с уникальным содержимым. И как было бы удобно редактировать общие блоки, вроде шапки сайта, отдельно, а затем вкладывать их во все страницы. Тогда при смене логотипа потребуется внести изменение только в одном месте, а все страницы сайта обновятся автоматически.
Шаблонизация — это и есть деление всей вёрстки на независимые шаблоны и дальнейшее их подключение и вкладывание друг в друга.
Сбор страницы из частей
Если поделить всю вёрстку сайта на отдельные, небольшие шаблоны мы получим сразу несколько преимуществ. Станет легче следить за единообразием интерфейса. Выделив представление сайта в шаблоны, мы также существенно упростим PHP-сценарии, ведь в них останется только PHP-код. Можно даже доверить верстальщику редактировать непосредственно шаблоны, так как в них почти нет программного кода, а тот, что есть, очень простой.
Потренируйтесь собирать страницы из фрагментов, выполнив это задание.
Термины шаблонизации
В разговоре о шаблонизации очень важно придерживаться определённых терминов, чтобы всегда было понимание, о чём идёт речь. Договоримся использовать следующую терминологию:
Лейаут — это шаблон, который содержит HTML-код, общий для всех страниц сайта. В нём могут содержаться подключение стилей, мета-теги, шапка, подвал. Также лейаут содержит область для вставки уникального содержимого каждой страницы.
Шаблон страницы — это шаблон с уникальным для одной страницы HTML-кодом. Например, для главной страницы там может быть список новостей. Также шаблон страницы может включать в себя блоки.
Блок — это шаблон очень небольшого блока страницы. Например, это может быть один элемент списка новостей. Удобство блоков в том, один блок могут включать разные страницы.
Содержимое шаблона
Что же находится внутри шаблона? Вы уже знаете, что шаблон почти полностью состоит из HTML-кода. Но помимо HTML-тегов, там также лежат данные и простая логика.
Данные в шаблоне
Шаблон показывает динамическую информацию. Прилагательное «динамическая» означает, что эти данные могут меняться и показываться в зависимости от различных условий. Сама информация, как правило, хранится в базе данных, а PHP-сценарий извлекает её оттуда и передаёт в шаблон.
Вне зависимости от источника информации есть правило, которое никогда нельзя нарушать: любой шаблон (лейаут, шаблон страницы, блок) должен иметь доступ только к тем данным, которые ему явно передали.
Такую изоляцию данных обеспечивает специальная функция-шаблонизатор, о которой пойдёт речь далее.
Логика шаблона
В шаблоне должна находиться только несложная логика. Иными словами, шаблоны не содержат «тяжёлого» PHP-кода, а только простые конструкции.
Так, в шаблоне можно показывать переменные, использовать условия, циклы, обходить массивы, вызывать функции и подключать файлы. Всё другое запрещено. Оставшаяся бизнес-логика остаётся в PHP-сценариях, которые вызывают шаблоны и передают в них информацию.
Функция-шаблонизатор
Шаблонизатор — это функция, которая подключает файл шаблона, передаёт ему данные и возвращает сгенерированный HTML.
Именно шаблонизатор является тем клеем, что скрепляет воедино отдельные шаблоны в итоговую страницу. Работает он следующим образом: PHP-сценарий страницы выполяет все действия для подготовки необходимой информации, к примеру, запрашивает записи из базы данных. Эти записи в виде массива отправляются шаблонизатору вместе с именем шаблона страницы.
Шаблонизатор подключает указанный файл шаблона и передаёт туда всю информацию. Но, вместо вывода на экран содержимого этого шаблона, он захватывает получившийся HTML-код и возвращает его.
Затем сценарий вызывает шалбонизатор ещё раз, но теперь с его помощью подключает общий лейаут, куда отправляется общая информация, а также содержимое страницы, полученное из предыдущего шага. Весь результат работы выводится на экран.
Пример использования
Посмотрим на примере, как это всё работает. Начнём с того, что определим три шаблона: лейаут, шаблон страницы и какой нибудь блок.
Напоминаю, что в лейаут выносим общий HTML-код.
[layout.php]
Теперь очередь за шаблоном страницы:
[main.php]
Здесь обрати внимание, что шаблон страницы помимо интерации по массиву, для каждого его элемента вызывает функцию-шаблонизатор. Шаблонизатор получает контент из шаблона блока и показывает его внутри списка.
So, I’m making a site about WWI as a school assignment, and I want this to appear in every document:
I think it’s kind of stupid to copy-paste all this into each document, and painstakingly go in and change each page separately if I just want to change one word or tag. Is there a way I can put this in template.htm (or something similar) and have php or javascript code take this and insert everything from the requested file inside of the tag? I don’t know a lot of php, so this is probably a piece of cake for you gurus, but I would appreciate the help.
4 Answers 4
Using php includes:
Save this as top.php
Save this as bottom.php
Then your individual pages would be like this:
You could consider one of these popular template engines :
Smarty (becoming outdated)
Latte (used mostly by the Nette community)
Twig (used mostly by the Symfony community)
Mustache (official implementations of this templating engine exist in more than two dozen proramming/scripting languages)
I tend to favor Mustache, mostly because it has an official JS version, an official Ruby version, an official Java version, etc. It allows you to use the same templates frontend and backend, which is very useful for widgets that are first rendered in background and rerendered in foreground at updates.
