ZPT

Введение в Zope Page Templates, прекрасно написанное Эван Симпсон(Evan Simpson). Перевод: Игорь Митин

Zope Page Templates - Основы

Введение в Zope Page Templates, прекрасно написанное Эван Симпсон(Evan Simpson). Оригинал статьи опубликован на zope.org.

by Evan Simpson

Введение

Шаблоны страницы являются инструментом для генерации веб страниц. Они помогают сообществам программистов и дизайнеров в производстве динамических веб страниц для веб приложений Zope. Дизайнеры используют их для поддержания страниц без отказа от привычных своих инструментов, и в тоже время предохранить от работы по внедрению этих страниц в приложение. В этой статье мы обсудим основы шаблонов страниц и узнаем как вы можете использовать их в ваших веб сайтах для легкого создания динамических веб страниц.

Целью шаблонов страниц является естественный процесс публикации. Дизайнер, используя WYSIWYG HTML редактор, создает шаблон, программист редактирует его и делает частью приложения. Если требуется, дизайнер может загрузить шаблон обратно в свой редактор и продолжить изменения в его структуре и внешнем обличие. Не трогая изменений сделанных программистом, он не сможет нарушить работу приложения.

Шаблоны страниц должны удовлетворять трем основным правилам:

  1. Хорошее согласование с инструментами редактирования.
  2. Что вы видите, то вы и получаете.
  3. Хранение кода отдельно от шаблона, за исключением структурной логики.

Шаблон страницы подобен модели страниц, которые он генерирует. В частности, он является правильной HTML страницей. С тех пор как HTML стал весьма структурированным, и WYSIWYG редакторы стали тщательно предохранять их структуру, эти причины стали ограничивать пути которыми программист может изменять страницу.

Шаблоны страниц предназначены для программистов и дизайнеров работающих совместно над созданием динамических веб страниц. Если вы создаете и редактируете все ваши веб страницы в текстовом редакторе, вы можете не особо заботиться о шаблонах страниц. С другой стороны они могут стать простой альтернативой использования DTML.

Почему еще один язык шаблонов?

Сейчас существует множество систем шаблонов, некоторые из них являются весьма популярными, такие как ASP, JSP и PHP. Zope поставляется со своим языком шаблонов, называемым DTML. Зачем выдумывать еще?

Во первых ни одна из этих систем шаблонов не рассчитана на дизайнеров. Страница сконвертированная в шаблон, больше не является правильно HTML страницей и дальнейшее ее изменение в отрыве от приложения ее использующего сложно или практически не возможно. Это является нарушением первого и второго основного принципов Zope Page Templates(ZPT) системы шаблонов. Программисты не должны "отнимать" работу у дизайнеров и превращать HTML в программное обеспечение. XMLC, часть проекта Enhydra, разделяет задачи, принуждая программиста писать монолитный код поддержки на Java для каждого шаблона.

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

Правила применения

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

Шаблоны страниц используют Template Attribute Language (TAL) язык описания атрибутов заключающийся в специальных атрибутах тэга. Для примера, заголовок динамической странице выглядит подобно этому:

        <title tal:content="here/title">Page Title</title>

Здесь tal:content атрибут является оператором TAL. Он имеет XML пространство имен(часть tal:), большинство инструментов редактирования не считают его ошибочным потому что не знают его, и соответственно не удаляют этот атрибут. Этот атрибут не изменяет структуру или внешний вид шаблона при загрузке его в WYSIWYG редактор или в веб браузер. Имя content указывает на то что данный атрибут устанавливает содержимое тэга title и его значение "here/title" является выражением, предоставляющим текст для вставки внутрь тэга.

HTML дизайнеры, использующие WYSIWYG инструмент, воспринимают все это как правильный HTML и во время редактирования видят заголовок. Дизайнер не беспокоится относительно деталей применения TAL, видя только модель динамического шаблона с вставленным значением заглушкой подобно "Page Title" для заголовка документа.

Когда эти шаблоны сохраняются в Zope и просматриваются пользователем, Zope превращает этот статический контент в динамический и заменяет "Page Title" каким-либо найденным значением "here/title". В данном случае "here/title" принимает значение title объекта, который обращается к данному шаблону. Эта замена происходит динамически, когда шаблон становиться представлением.

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

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

Этот язык шаблонов не является самостоятельным языком программирования. Он основывается на использовании внутри каркасов программирования (framework)(таких как Zope), в которых другие объекты обрабатывают бизнес логику и задачи, не имеющие отношения к разметке страницы.

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

Создание шаблона страницы

Если вы разрабатываете страницы, вы вероятно захотите использовать FTP или WebDAV вместо ZMI для создания и редактирования шаблонов страниц. Смотрите инструкции администратора вашего сервера Zope. Для маленьких примеров данной статьи имеет смысл использовать ZMI, в виду его наличия у каждого. Для получения дополнительной информации относительно использования FTP или WebDAV с Zope смотрите Zope Book или Jeffrey Shell's recent WebDAV article

Если вы администратор Zope или программист, вы, вероятно, очень редко используете ZMI. В также используете emacs, cadaver, или какой либо другой клиент. Смотрите инструкции по настройке Zope для работы с множеством других клиентов в Zope Book.

Используя ваш веб браузер залогинтесь в ZMI так как вы это обычно делаете. Выберите папку (в качестве корня для экспериментов) и создайте "Page Temlate" выбрав его из ниспадающего списка. Впишите в поле Id "simple_page", нажмите кнопку "Add and Edit".

Вы сейчас видите страницу редактирования для нового шаблона страницы. Поле заголовка(title) пустое, тип контента text/html и текст шаблона по умолчанию в области редактирования.

Сейчас вы создали простую динамическую страницу. Введите фразу "a Simple Page" в поле Title. Затем отредактируйте текст шаблона подобно этому:

        This is <b tal:replace="template/title">the Title</b>.

Нажмите кнопку "Save Change". В странице редактирования появиться сообщение, информирующее вас о том, что изменения были сохранены. Если какой либо текст, начинающийся с <-- Page Template Diagnostics добавлен в шаблон, проверьте ваш пример, откорректируйте и сохраните снова. Вам незачем удалять комментарий об ошибке; после исправления ошибки он пропадет сам.

Вы увидите практически пустую страницу с единственной надписью вверху страницы "This is a Simple Page."

Вернитесь обратно и щелкните ссылку "Browse HTML source" расположенную под полем типа контента. Это покажет вам не визуализированный исходник шаблона. Вы видите "This is the Title.". Вернитесь обратно, здесь вы будете редактировать следующие примеры.

Простые выражения

Текст "template/title" в вашем простом шаблоне страницы является выражением пути(path expression). Это является одним из типов часто используемых определений выражений TAL Expression Syntax(TALES). Это выражение возвращает свойство title шаблона. Далее представлены другие часто используемые выражения пути:

  • request/URL: URL текущего запроса.
  • user/getUserName: Имя аутентифицированного пользователя(его логин).
  • container/objectIds: Список идентификаторов объектов в той же самой папке, где находится шаблон.

Любой путь начинается с имени переменной. Если значение переменной это то, что вам необходимо, то вы на этом и останавливаетесь. Иначе, вы добавляете слеш (/) и имя подъобекта или свойства. Можно также написать имена нескольких подобъектов для получения необходимого значения.

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

Вставка текста

В вашем шаблоне "simple_page", вы использовали оператор tal:replace внутри тэга b. Когда вы тестировали его, он заменил полностью весть тэг значением заголовка шаблона. Когда вы просмотрите ваш исходный текст, вы увидите, текст шаблона выделен жирным. Мы использовали тэг b с целью выделить различия.

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

      <br>
      The URL is <span tal:replace="request/URL">URL</span>.

Тэг span является структурным и не отображается визуально, в результате вы видите нечто подобное "The URL is URL.", когда просматриваете представление вашего исходника редакторе или в браузере. Когда вы просматриваете визуализированную(обработанную) версию шаблона, он выглядит подобно следующему:

      <br>
      The URL is http://localhost:8080/simple_page.

Помните, что когда вы размещаете tal:replace не в тэг span а в тэги форматирования такие как b или font, эти тэги также заменяются на результат вычисления оператора, т.е. они будут отсутствовать в тексте конечной страницы.

Если вы хотите поместить текст внутрь тэга, оставив сам тэг нетронутым, вы должны использовать оператор tal:content. Для установки заголовка вашей страницы примера в тэг title, добавьте следующие строки:

      <head>
      <title tal:content="template/title">The Title</title>
      </head>

Если вы откроете вкладку Test в новом окне, в заголовке страницы появится "a Simple Page".

Повторяющиеся структуры

Сейчас вы добавите некоторый контекст в вашу страницу, в форме списка объектов содержащихся в той же самой папке. Вы сделаете таблицу, которая имеет номер строки для каждого объекта, и столбцы с id, meta-type и title. Добавьте эти строки в самый низ вашего шаблона:

      <table border="1" width="100%">
        <tr>
          <th>#</th><th>Id</th><th>Meta-Type</th><th>Title</th>
        </tr>
        <tr tal:repeat="item container/objectValues">
          <td tal:content="repeat/item/number">#</td>
          <td tal:content="item/id">Id</td>
          <td tal:content="item/meta_type">Meta-Type</td>
          <td tal:content="item/title">Title</td>
        </tr>
      </table>

Оператор tal:repeat в строке таблицы означает "повторить эту строку для каждого элемента содержащую список свойств объекта". Оператор повторения поочередно помещает объекты из списка в переменную item, и делает копию строки, используя эту переменную. Значение item/id в каждой строке представляет Id объекта, для которого создается строка.

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

Вы также используете tal:repeat переменную для получения информации относительно текущего повторения. Размещая ее после встроенной переменной repeat в пути, вы можете получить доступ к счетчику повторений начинающегося с нуля(index), с единицы(number), с символа "A" (Letter) и в некоторых других направлениях. Таким образом, выражение repeat/item/number помещает 1 в первой строке, 2 во второй строке и т.д.

Иногда один tal:repeat цикл может размещаться внутри другого. Это объясняет, почему вы должны писать repeat/item/number вместо repeat/number. Вы должны определить, какой цикл вас интересует, для этого и включается имя цикла.

Условные элементы

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

      <table border="1" width="100%">
        <tr>
          <th>#</th><th>Id</th><th>Meta-Type</th><th>Title</th>
        </tr>
        <tbody tal:repeat="item container/objectValues">
          <tr bgcolor="#EEEEEE" tal:condition="repeat/item/even">
            <td tal:content="repeat/item/number">#</td>
            <td tal:content="item/id">Id</td>
            <td tal:content="item/meta_type">Meta-Type</td>
            <td tal:content="item/title">Title</td>
          </tr>
          <tr tal:condition="repeat/item/odd">
            <td tal:content="repeat/item/number">#</td>
            <td tal:content="item/id">Id</td>
            <td tal:content="item/meta_type">Meta-Type</td>
            <td tal:content="item/title">Title</td>
          </tr>
        </tbody>
      </table>

Оператор tal:repeat не был изменен, вы просто перенесли его в новый тэг tbody. Это стандартный HTML тэг обозначает группу объединенных строк представляющих тело таблицы, который вы и используете. Здесь две строки в теле с идентичными столбцами и одна из них имеет серый цвет фона.

Посмотрите на шаблон и вы увидите две строки. Если бы вы не добавили оператор tal:condition в эти строки, то шаблон генерировал бы обе строки для каждого элемента, это не совсем то что вы хотели бы. Оператор tal:condition в первой строке гарантирует что эта строка включает только четные повторения, в то время как условие во второй строке указывает на нечетные повторения.

Оператор tal:condition ничего не делает если его выражение имеет значение true и просто удаляет весь тэг, включая его содержимое, если значение выражения false. Свойства odd и even переменной repeat/item возвращают ноль или единицу. Число ноль, пустая строка, пустой список и встроенная переменная nothing все они имеют значения false. Противоположное значение true, включающее не нулевое число и строки с любыми символами (даже пробелы).

Определение переменных

Ваш шаблон всегда показывает хотя бы одну строку, т.е. шаблон показывает самого себя как одного из списка объектов. В другой обстановке, вы можете просчитать что таблица может оказаться пустой. В таком случае, предположим, вы решите просто опустить всю таблицу. Вы можете это сделать, добавив tal:condition в тэг table:

      <table border="1" width="100%"
             tal:condition="container/objectValues">

Сейчас, когда нет объектов, даже часть таблицы не будет включена в вывод. Когда есть объекты, то выражение "container/objectValues" будет выполнено дважды, это достаточно плохо. Также, если вы захотите изменить выражение, вам придется это сделать дважды.

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

      <table border="1" width="100%"
             tal:define="items container/objectValues"
             tal:condition="items">
        <tr>
          <th>#</th><th>Id</th><th>Meta-Type</th><th>Title</th>
        </tr>
        <tbody tal:repeat="item items">

Оператор tal:define создает переменную items и вы можете использовать ее где-нибудь в тэге table. Обратите также на то что вы можете иметь два TAL атрибута в одном и том же тэге table. В первом определяется переменная items, во втором items используется в условии, определяющем, какое из двух значений она имеет false(пустая последовательность) или true.

Сейчас, допустим, что вместо того чтобы просто пропустить таблицу, когда нет элементов, вы хотите вывести сообщение об этом. Делаем следующее, поместите следующее в таблицу представленную выше:

      <h4 tal:condition="not:container/objectValues">There
      Are No Items</h4>

Вы не можете использовать вашу переменную items здесь, потому что она еще не определена. Если вы перенесете ее определение в тэг h4, вы не сможете ее использовать в тэге table, потому что она станет локальной переменной тэга h4. Вы должны поместить определение переменной в какой-либо объемлющий тэг, который содержит внутри себя оба тэга h4 и table. Поместив ключевое слово global перед именем переменной, вы можете сделать определение в тэге h4 и переменная будет доступна до конца шаблона:

      <h4 tal:define="global items container/objectValues"
          tal:condition="not:items">There Are No Items</h4>
      <table border="1" width="100%" tal:condition="items">

Префикс not: в первом выражении tal:condition может быть размещен вначале любого выражения. Если выражение истинно, not: делает его false и наоборот.

Изменение атрибутов

Многие, если не все, объекты в списке вашего шаблона имеют свойство icon, которое содержит путь к иконке для конкретного типа объекта. Для того чтобы надлежащим образом отобразить эти иконки в столбце meta-type, вам необходимо вставить путь к ним в src атрибут тэга img, отредактируйте столбец meta-type в обеих строках подобно тому, как это показано здесь:

      <td><img src="/misc_/OFSP/Folder_icon.gif"
               tal:attributes="src item/icon">
          <span tal:replace="item/meta_type">Meta-Type</span>
      </td>

Оператор tal:attributes заменяет атрибут картинки на значение item/icon. Значение src в шаблоне работает как наполнитель для того чтобы картинка не портила представление страницы при редактировании и имела корректный размер.

С того момента как атрибут tal:content устанавливается для ячейки таблицы, при рендеринге он заменяет полностью все содержимое этой ячейки, включая картинку и текст meta-type. Вместо этого вы вставляете meta-type также как и URL показанный в данной статье выше.

Заключение

В данном кратком обзоре о шаблонах страниц Zope вы увидели как можно создавать и редактировать простые шаблоны, и как вы можете использовать языки TAL и TALES для создания динамического контента без изменения вашего HTML кода или конфликта с вашими любимыми инструментами редактирования. Как вы можете видеть шаблоны страниц создаются дизайнером и программистом веб приложений, работающих совместно и не мешающих друг другу при этом. В следующей статье этой серии мы рассмотрим некоторые из расширенных возможностей шаблонов страниц.

По материалам http://zope.org
Публикуется с разрешения переводчика:
Igor Mitin
i_mitin@mail.ru