ENGLISH | | | БЛОГ

Занятие 3. Сборка страниц: Tiles

Очень часто мы используем на разных страницах сайтов повторяющийся код. Это может быть навигационное меню, рекламные блоки, стандартные формы поиска или входа на сайт. Такие фрагменты могут повторяться на множестве страниц, а иногда и на всех. Было бы нерационально на каждую страницу включать одинаковый код, который теоретически может измениться (например, в меню добавляется один пункт, следовательно, мы вынуждены корректировать код меню на каждой странице).
Любая серверная технология позволяет «собирать» страницы по фрагментам, чтобы не писать повторяющийся код много раз. То есть многократно используемый код выносится в отдельный файл, а затем в нужном месте включается в основной файл. Фреймворк Struts 2 предоставляет аналогичную возможность, которая реализована при помощи технологии Tiles («черепица»). Поясним на конкретном примере (см. иллюстрацию).

На разных страницах используется форма входа на сайт: поля для логина и пароля и кнопка Submit. На другой части страниц, не видимых неавторизованному пользователю, есть блок с информацией о пользователе. Располагаются же они на одном и том же месте, поскольку никогда не встречаются вместе. Очевидно, что нет смысла повторять код с формой или информацию о пользователе в разных шаблонах: достаточно создать два файла, которые будут подключаться в зависимости от каких-то условий. Условие следующее: главная страница и страница с формой регистрации видны неавторизованным пользователям, при запросе же остальных страниц (экшнов) Struts перенаправляет браузер на страницу с формой входа (главную, например, login.action).
Мы создаём два файла: один с формой входа, второй с обработкой сценария, запрашивающего данные о пользователе. В основном шаблоне определяем место для включения одного из этих файлов. Затем при обработке экшнов в зависимости от результата используется то или иное включение в основной шаблон.
В основном шаблоне находится основная вёрстка — неизменные фрагменты кода — и указания (Struts-тэги) позиций, которые будут заполняться содержимым конкретных файлов. В конфигурационном файле tiles.xml для каждого конкретного экшна описывается заполнение этих позиций файлами. (Для каждого экшна есть набор описаний: какие позиции заполняются какими файлами. Если же описание пропущено, то вступают в силу описания, заданные как правила по умолчанию.) При обращении к тому или иному экшну производится серверная замена Tiles-тэга на результат включения указанного файла. В итоге окончательный файл собирается, как конструктор или черепица, но в зависимости от правил, указанных в tiles.xml. А то, что интерпретатор кода должен обращаться к файлу tiles.xml, косвенно указано в конфигурационном файле struts.xml. Рассмотрим процесс подробнее.
Сервер обращается к файлу struts.xml. Его содержание по сравнению с предыдущими занятиями изменено (приводится фрагмент):

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration
2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="common" extends="tiles-default">
  <global-results>
    <result type="redirect" name="redirectToLogin">
      login.action</result>
  </global-results>
  <action name="login" class="mymovieteach.action.LoginAction"
   method="input">
    <result type="tiles">login</result>
  </action>
  <action name="loginSubmit" class="mymovieteach.action.LoginAction"
   method="loginSubmit">
    <result type="tiles" name="input">login</result>
    <result type="redirect">home.action</result>
  </action>
  <action name="home" class="mymovieteach.action.HomeAction"
   method="show">
   <result type="tiles">home</result>
  </action>
</package>
</struts>

Строка <package name="common" extends="tiles-default"> указывает на то, что для обработки экшнов используется пакет (package) common, наследующий функциональность tiles-default.
Благодаря такому наследованию в качестве типа результата можно указать значение tiles.
Рассмотрим пример. Происходит обращение к экшну login (детально процесс рассмотрен в предыдущих занятиях):

<action name="login" class="mymovieteach.action.LoginAction"
 method="input">
   <result type="tiles">login</result>
</action>

Выполняется метод input класса LoginAction (как мы помним, метод input не требует валидации); он возвращает SUCCESS, а значит, используется результат по умолчанию (он же единственный для данного экшна). Тип результата — tiles; значение — login.
В файле tiles.xml (приведен фрагмент) —

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
        "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
        "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
  <definition name="defaultLayout" template="/WEB-INF/jsp/layout/default.jsp">
    <put-attribute name="title" value=""/>
    <put-attribute name="leftTopPanel" value="/WEB-INF/jsp/inc/def_left_top_panel.jsp"/>
    <put-attribute name="leftBottomPanel" value=""/>
    <put-attribute name="rightTopPanel" value=""/>
    <put-attribute name="rightBottomPanel" value="/WEB-INF/jsp/inc/find_form_panel.jsp"/>
  </definition>
  <definition name="login" extends="defaultLayout">
    <put-attribute name="title" value="Login"/>
    <put-attribute name="leftBottomPanel" value="/WEB-INF/jsp/inc/join_left_bottom_panel.jsp"/>
    <put-attribute name="rightTopPanel" value="/WEB-INF/jsp/login_form.jsp"/>
  </definition>
  <definition name="home" extends="defaultLayout">
    <put-attribute name="title" value="Home"/>
    <put-attribute name="leftBottomPanel" value="/WEB-INF/jsp/inc/home_left_bottom_panel.jsp"/>
    <put-attribute name="rightTopPanel" value="/WEB-INF/jsp/inc/welcome_panel.jsp"/>
  </definition>
</tiles-definitions>

— содержатся строки, отвечающие за обработку данного типа результата:

<definition name="login" extends="defaultLayout">
  <put-attribute name="title" value="Login"/>
  <put-attribute name="leftBottomPanel" value="/WEB-INF/jsp/inc/join_left_bottom_panel.jsp"/>
  <put-attribute name="rightTopPanel" value="/WEB-INF/jsp/login_form.jsp"/>
</definition>

В этом фрагменте видно, что с помощью определений описываются три Tiles (title, leftBottomPanel и rightTopPanel). Но это описание наследует более общее описание Tiles по умолчанию (extends="defaultLayout"), в котором присутствуют пять атрибутов:

<definition name="defaultLayout" template="/WEB-INF/jsp/layout/default.jsp">
  <put-attribute name="title" value=""/>
  <put-attribute name="leftTopPanel" value="/WEB-INF/jsp/inc/def_left_top_panel.jsp"/>
  <put-attribute name="leftBottomPanel" value=""/>
  <put-attribute name="rightTopPanel" value=""/>
  <put-attribute name="rightBottomPanel" value="/WEB-INF/jsp/inc/find_form_panel.jsp"/>
</definition> 

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

<definition name="login" template="/WEB-INF/jsp/layout/default.jsp">
  <put-attribute name="title" value="Login"/>
  <put-attribute name="leftTopPanel" value="/WEB-INF/jsp/inc/def_left_top_panel.jsp"/>
  <put-attribute name="leftBottomPanel" value="/WEB-INF/jsp/inc/join_left_bottom_panel.jsp"/>
  <put-attribute name="rightTopPanel" value="/WEB-INF/jsp/login_form.jsp"/>
  <put-attribute name="rightBottomPanel" value="/WEB-INF/jsp/inc/find_form_panel.jsp"/>
</definition>

Видно, что в качестве основного шаблона используется файл /WEB-INF/jsp/layout/default.jsp:

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
  <title><tiles:insertAttribute name="title"/></title>
</head>
<body>
  <div id="general">
    <div id="mainboard" class="mainpage">
      <tiles:insertAttribute name="leftTopPanel"/>
      <tiles:insertAttribute name="leftBottomPanel"/>
    </div>
    <div id="dashboard">
      <tiles:insertAttribute name="rightTopPanel"/>
      <tiles:insertAttribute name="rightBottomPanel"/>
    </div>
    <div id="footerbar">
      © <a href="http://www.magicwebsolutions.co.uk" target="_blank">
           Magicwebsolutions.co.uk</a>
      | <a href="/terms.action">Terms and Conditions</a>
      | <a href="/privacy.action">Privacy Policy</a>
      | <a href="/bugreports.action">Reports and Comments</a>
    </div>
  </div>
</body>
</html>

В нём содержатся:
1. Включения программных библиотек для обработки Struts-тэгов и Tiles.
2. Основная вёрстка (те фрагменты кода, которые не изменяются никогда, например, основные тэги и включения стилей и скриптов).
3. Struts-тэги для вызова серверных включений файлов или значений.

Третий пункт наиболее важен для рассмативаемой темы.
Синтаксис включения Tiles таков: <префикс:insertAttribute name="имя"/>. Префикс указан в самом начале файла в директиве <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> — это значит, что в данном документе вид Tiles-вызовов будет таким: <tiles:insertAttribute name="имя"/>. В качестве имени указываются те имена атрибутов, которые использованы в файле tiles.xml. То есть если мы встречаем вызов <tiles:insertAttribute name="title"/>, то будет использовано значение, указанное в <put-attribute name="title" value="Значение"/> в определении того экшна, который актуален в данный момент.
Если описать это в виде процесса: запрашивается экшн, данные передаются серверу, в struts.xml описывается, что нужно сделать с данными (какой метод какого класса вызывается), экземпляр класса создаётся и заполняется данными, в случае успешного прохождения валидации (при необходимости) выполняется указанный метод, а в зависимости от того, что возвращается, используется тот или иной результат для данного экшна; в качестве результата, если его тип — tiles, — может быть указано имя для вызова Tiles; по этому имени из tiles.xml используется нужное определение (definition).
Внутри определений есть наборы тэгов <put-attribute name="имя" value="значение"/>, из которых и будет производиться выбор во время вызова <префикс:insertAttribute name="имя"/>. В зависимости от значения тэга <put-attribute name="имя" value="значение"/> и типа этого значения и будет производиться замена <префикс:insertAttribute name="имя"/> на конкретное содержимое внутри основного шаблона, который указан в Tiles-определении как шаблон по умолчанию: <definition name="defaultLayout" template="/WEB-INF/jsp/layout/default.jsp">, то есть файл /WEB-INF/jsp/layout/default.jsp.
С точки зрения вложенности шаблонов есть несколько файлов, иерархия которых определяется в tiles.xml, а конкретные случаи включений описываются с помощью struts.xml.
Но с помощью Tiles можно не только собирать страницы из файлов-фрагментов. Можно, например, заполнять вызовы простыми строковыми значениями. В тэгах <put-attribute name="имя" value="значение"/> можно указывать тип передаваемого значения: <put-attribute name="имя" value="значение" type="тип"/>. Типов четыре: string (строка), template (включаемый файл-шаблон), definition (вызов уже описанного определения) или object (объект). На самом деле тип указывать необязательно: Struts в большинстве случаев определяет тип корректно. В качестве строки можно указать обычное слово (как и происходит в случае с <put-attribute name="title" value="Login"/>), а если в начале значения стоит слэш (как в <put-attribute name="rightBottomPanel" value="/WEB-INF/jsp/inc/find_form_panel.jsp"/>), то Struts определяет тип данных как template и ищет ресурс по указанному пути, а если не находит, то выдаёт предупреждение. В нашем примере используются типы string и template.

Исходный код к уроку

VN:F [1.0.9_379]
Рейтинг: 5.0/5 (голосов: 3)

Метки: ,

Комментарии (2) на “Занятие 3. Сборка страниц: Tiles”

  1. Ru говорит:

    Предидушие уроки были по доходчевее, где-то даже через чур. А вообше спасибо, очень мало инфы на эту тему.

    VA:F [1.0.9_379]
    Rating: 0.0/5 (0 голоса cast)
  2. Coder говорит:

    Спасибо, постоянно практикуюсь на ваших уроках

    VA:F [1.0.9_379]
    Rating: 0.0/5 (0 голоса cast)

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

CAPTCHA Image Audio Version
Reload Image

 

E-mail :: Телефон: (8452) 22-89-40
Copyright © 1999–2010 LAR