Верстаем с помощью технологии XSLT

Верстаем с помощью технологии XSLT

В рубрике CMS - верстка, на момент написания статьи Верстка элементов центрального контента был сделан каркас будущей CMS и сверстана центральная часть нашей системы. Теперь сделаем тоже самое, но уже с использованием технологии XML / XSLT.

Для начала необходимо определиться что мы будем преобразовывать с помощью технологии XSLT и во что мы это будем преобразовывать. Вообще, XSLT - это технология, позволяющая преобразовывать XML-документ в другой XML-документ, HTML-документ, PDF-документ, просто текст и т.д. Из википедии: «При применении таблицы стилей XSLT, состоящей из набора шаблонов, к XML-документу (исходное дерево) образуется конечное дерево, которое может быть другой XML-структурой, HTML-документом или обычным текстом. Правила выбора (и, отчасти, преобразования) данных из исходного дерева пишутся на языке запросов XPath».

Таким образом для начала нам необходим XML-документ. Где его взять? Вся информация у нас хранится в базе данных (ну, это у нас). Надо взять эту информацию и оформить ее в виде XML-документа, и делать это будем мы в недалеком будущем на стороне сервера с помощью PHP. А сейчас предположим, что мы уже имеем XML-документ следующего вида:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='index.xsl'?>

<root>
  <header>
    <exit href="http://www.fancode.ru/">Выход на сайт</exit>
    <fio>ФИО пользователя</fio>
  </header>
  <menu>
    <folders>
      <folder>Страницы сайта</folder>
      <links>
        <link href="#">Каталог страниц</link>
        <link href="#">Новости</link>
      </links>
    </folders>
    <folders>
      <folder>Настройки</folder>
        <links>
        <link href="#">Пользователи</link>
        <link href="#">Группы пользователей</link>
        <link href="#">Настройки</link>
        <link href="#">Изменение пароля</link>
      </links>
    </folders>
  </menu>
  <title_table>Заголовок таблицы</title_table>
  <pagination>
    <select>
      <sel>5</sel>
      <sel>10</sel>
      <sel>20</sel>
      <sel>50</sel>
    </select>
  </pagination>
  <tbody>
    <tr>
      <count>1</count>
      <name>Страница 1</name>
      <desc>Название 1</desc>
      <inner>0</inner>
      <on_off>0</on_off>
      <show href="#">0</show>
      <edit href="#">0</edit>
      <dell>0</dell>
    </tr>
    <tr>
      <count>2</count>
      <name>Страница 2</name>
      <desc>Название 2</desc>
      <inner>1</inner>
      <on_off>1</on_off>
      <show href="#">0</show>
      <edit href="#">0</edit>
      <dell>0</dell>
    </tr>
    <tr>
      <count>3</count>
      <name>Страница 3</name>
      <desc>Название 3</desc>
      <inner>1</inner>
      <on_off>1</on_off>
      <show href="#">0</show>
      <edit href="#">0</edit>
      <dell>0</dell>
    </tr>
  </tbody>
  <footer> </footer>
</root>

Комментарии к XML-коду:

  • вторая строка - подключение XSLT-файла со стилями;
  • содержимое тега header - данные заголовка;
  • содержимое тега menu - данные меню, где folders - раздел меню, folder - заголовок раздела, links - группы ссылкок меню и link - ссылки;
  • pagination - постраничная навигация;
  • в теге table_tr - содержимое центрального контента;
  • и footer - подвал.

Теперь рассмотрим XSLT-файлы со стилями, приводящие данные XML к нужному виду . Сначала подключается index.xsl:

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

<xsl:include href="main.xsl"/>

<xsl:template name="thead">
  <tr class="header">
    <th class="center" width="40px">№</th>
    <th class="left">Название</th>
    <th class="left" width="160px">Виртуальный каталог</th>
    <th class="center" width="30px">Вл.</th>
    <th class="center" width="30px">Пок.</th>
    <th class="center" width="30px">См.</th>
    <th class="center" width="30px">Ред.</th>
    <th class="center" width="30px">Уд.</th>
  </tr>
</xsl:template>

<xsl:template match="tbody">
  <xsl:apply-templates select="tr"/>
</xsl:template>

<xsl:template match="tr">
  <tr class="tr_body">
    <td class="center"><input id="sort_" name="sort[]" type="text" class="t_text small_text" value="{normalize-space(count)}" /></td>
    <td class="left"><xsl:value-of select="name"/></td>
    <td class="left"><xsl:value-of select="desc"/></td>
    <xsl:if test="inner=0">
      <td class="center"><a href="#" title="Нет вложенных страниц или каталогов"><img src="img/forward_off.gif" alt="Нет вложенных страниц или каталогов" width="15" height="12"/></a></td>
    </xsl:if>
    <xsl:if test="inner=1">
      <td class="center"><a href="#" title="Перйти к вложеннм страницам или каталогам"><img src="img/forward.gif" alt="Перйти к вложеннм страницам или каталогам" width="15" height="12"/></a></td>
    </xsl:if>
    <xsl:if test="on_off=0">
      <td class="center"><a href="#" title="Включить"><img src="img/off.gif" alt="Включить" width="15" height="15"/></a></td>
    </xsl:if>
    <xsl:if test="on_off=1">
      <td class="center"><a href="#" title="Выключить"><img src="img/on.gif" alt="Выключить" width="15" height="15"/></a></td>
    </xsl:if>
    <td class="center"><a href="{@href}" target="_blank" title="Просмотреть страницу"><img src="img/edit_pages_thumb.png" alt="Просмотреть страницу" width="16" height="16"/></a></td>
    <td class="center"><a href="#" title="Редактировать"><img src="img/fileexport.png" alt="Редактировать" width="16" height="15"/></a></td>
    <td class="center"><input id="dell[]" name="dell[]" type="checkbox" value="" /></td>
  </tr>
</xsl:template>

</xsl:stylesheet>

В этом файле, после объявления заголовков, формата вывода и DOCTYPE результирующего документа идет строка подключения основного шаблона main.xsl. Ниже находится именованный шаблон для оформления заголовков таблицы thead и шаблон для тела таблицы tbody, в котором, для каждого элемента исходного XML-файла tbody вызывается шаблон для строки таблицы tr. Таким образом в index.xsl находятся изменяемые данные - заголовки столбцов и строки таблицы.

Код основного шаблона main.xsl:

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output encoding="utf-8" />

<xsl:include href="header.xsl"/>
<xsl:include href="menu.xsl"/>
<xsl:include href="pagination.xsl"/>
<xsl:include href="btn.xsl"/>
<xsl:include href="footer.xsl"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Верстка CMS с помощью технологии XML / XSLT</title>
  <link rel="stylesheet" type="text/css" href="style.css" />
  <link rel="stylesheet" type="text/css" href="table.css" />
  <link rel="stylesheet" type="text/css" href="tree.css" />
  <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
  <script type="text/javascript" src="js/jquery.simple.tree.js"></script>
  <script type="text/javascript" src="js/table.js"></script>
</head>
<body>
<div class="container">
  <!-- header -->
  <xsl:apply-templates select="/root/header"/>
  <!-- menu -->
  <xsl:apply-templates select="/root/menu"/>
  <!-- content -->
  <div id="cont_admin_content">
  <div id="admin_content" class="admin_content">
  <div id="admin_content" class="admin_content">
    <!-- title table -->
    <div class="path"><xsl:value-of select="/root/title_table"/></div>
    <!-- pagination -->
    <xsl:apply-templates select="/root/pagination"/>
    <table class="maintable" cellspacing="1">
      <!-- thead -->
      <thead>
        <xsl:call-template name="thead"/>
      </thead>
      <!-- tbody -->
      <tbody id="admin_table_body">
        <xsl:apply-templates select="/root/tbody"/>
        <xsl:call-template name="btn"/>
      </tbody>
    </table>
  </div>
  </div>
  <!-- footer -->
  <xsl:apply-templates select="/root/footer"/>
</div>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

Вначале идет подключение файлов с шаблонами шапки, меню, постраничной навигации, кнопок управления и подвала нашей CMS. Далее формируется HTML-документ, где в разделе HEAD подключаются CSS стили и JavaScript. В теле страницы с помощью правил apply-templates и call-template происходит подключение соответствующих шаблонов.

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

XSLT-шаблон  шапки header.xsl, который пожалуй не требует комментарив:

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output encoding="utf-8" />
<xsl:template match="header">
  <div id="header"> 
  <p class="menu_top">
    <a id="id_admin_exit" href="{exit/@href}"><xsl:value-of select="exit"/></a>
  </p>
  <h1>FAN<span>CODE</span>.CMS</h1>
  <p class="person_top">
    Пользователь: 
    <span class="fiospan">
      <xsl:value-of select="fio"/>
    </span>
  </p>
  </div>
</xsl:template>
</xsl:stylesheet>

XSLT-шаблон  меню menu.xsl:

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="menu">
  <div id="menu_left">
  <div class="top"></div>
  <div class="midle">
    <ul class="simpleTree">
      <li class="root">
        <span><a id="id_main_menu" href="#/main_menu" class="admin_menu_on first_a">Главная страница</a></span>
        <ul class="first_ul">
          <xsl:apply-templates select="/root/menu/folders"/>
        </ul>
      </li>
    </ul>
  </div>
  <div class="bottom"></div>
  </div>
</xsl:template>

<xsl:template match="folders">
  <xsl:if test="position()=1">
    <li class="open">
      <span>&#160;<xsl:value-of select="folder"/></span>
      <ul>
        <xsl:apply-templates select="links"/>
      </ul>
    </li>
  </xsl:if>
  <xsl:if test="position()!=1">
    <li>
      <span>&#160;<xsl:value-of select="folder"/></span>
      <ul>
        <xsl:apply-templates select="links"/>
      </ul>
    </li>
  </xsl:if>
</xsl:template>

<xsl:template match="links">
  <xsl:apply-templates select="link"/>
</xsl:template>

<xsl:template match="link">
  <li><span>&#160;<a href="{@href}" class="admin_menu_off"><xsl:value-of select="."/></a></span></li>
</xsl:template>

</xsl:stylesheet>

HTML-код берем из статьи Делаем основное меню. Внутри списка ul class="first_ul" задаем правило apply-templates select="/root/menu/folders", которое обращается к шаблону folders, в котором происходит проверка на номер позиции элемента в списке, и если позиция равна 1, то элементу списка присваивается CSS - стиль "open". Это необходимо, чтобы в первая папка меню при загрузке страницы была открытой. Далее применяем правило apply-templates select="links", и к каждому элементу списка links применяется правило преобразования template match="link". В итоге получаем требуемый вид меню.

XSLT-шаблон  постраничной навигации и поиска pagination.xsl:

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output encoding="utf-8" />

<xsl:template match="pagination">
  <table class="maintable" cellspacing="1">
    <tr class="pag">
      <td class="td_form_show_str">
        Показать: 
        <select class="aselect" id="select_pag" >
          <xsl:for-each select="/root/pagination/select/sel">
          <option value=""><xsl:value-of select="."/></option>
            </xsl:for-each>
        </select>
      </td>
      <td class="td_pagination_page"><div id="Pagination" class="pagination" >Постраничная навигация</div></td>
      <td class="td_field_search">
        <p><span class="search" style="float:left"> </span>
          <input type="text" class="text_field corner-all" name="search" id="search" value="" /> </p>
      </td>
      <td class="center"><a href="#" title="Обновить страницу" class="reset"> </a></td>
    </tr>
  </table>
</xsl:template>

</xsl:stylesheet>

XSLT-шаблон  кнопок управления btn.xsl:

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output encoding="utf-8" />

<xsl:template name="btn">
  <tr class="tr_body tr_border_top">
    <td colspan="5"></td>
    <td class="center"><a href="#" title="Добавить" ><img src="img/add.png" alt="Добавить" width="22" height="22"/></a></td>
    <td class="center"><a href="#" title="Сохранить все" ><img src="img/save_all.png" alt="Сохранить все" width="22" height="22"/></a></td>
    <td class="center"><a href="#" title="Удалить выделенное" ><img src="img/delete.png" alt="Удалить выделенное" width="22" height="22"/></a></td>
  </tr>
</xsl:template>

</xsl:stylesheet>

И наконец, XSLT-шаблон  подвала footer.xsl:

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output encoding="utf-8" />

<xsl:template match="footer">
  <div id="admin_footer">
    <p><!-- содержимое footer --></p>
  </div>
</xsl:template>

</xsl:stylesheet>

Подведем итоги.

Чего мы добились. В первую очередь - это полное разделение данных и представления. В этом заключается основное преимущество преобразования XML с помощью технологии XSLT. Действительно, данные могут формироваться на сервере каким угодно способом, с помощью любого языка программирования, может использоваться любая база данных, а дальше формируется документ XML, соответствующий общепринятому стандарту и посылается браузеру. Т.е. для XSLT - преобразования не важен источник данных.

В данной статье приведены лишь простейшие операции с помощью технологии XSLT. В следующих статьях будут рассмотрены примеры более продвинутого использования этой технологии.

Похожие пубикации

CodeIgniter начало

CodeIgniter начало

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

Верстка элементов центрального контента

Центральная часть CMS будет содержать в основном табличные данные. Следуя принципам семантической верстки, необходимо сверстать просто таблицу, а потом ее приукрасить стилями и JavaScript. В верхней части таблицы необходимо предусмотреть место для общих заголовков, элементов управления, таких как постраничная навигация и форма поиска, и заголовков столбцов таблицы. Внизу, под таблицей будут кнопки управления для добавления, сохранения и удаления содержимого таблицы.
Делаем основное меню

Делаем основное меню

В левой части админки будет находиться основное меню, с помощью которого мы будем осуществлять навигацию по страницам системы управления контентом. Меню реализуем с помощью jQuery плагина раскрывающееся дерево - jQuery SimpleTree Drag&Drop;.
Комментарии (3):
Денис | 17.12.2009 10:43
0
Здравствуйте, как я понял по настоящим и будущим статьям как вами уже было ранее написано что будете разбирать свой движёк (http://www.fancode.ru/admin.php). По понятным причинам это будет постепенно, но хотелось уже посмотреть его сразу, изучить в действующем виде, было бы очень интересно и познавательно, если вы выложили его в целом в архиве, если можно конечно.

Алексей | 18.12.2009 08:26
0
Выкладывать весь архив я считаю пока несвоевременным по причине того, что в процессе написания статей приходят новые идеи, в соответствии с которыми вносятся изменения, а также исправляются баги и чистится код. Так что придется потерпеть пару месяцев. И весь архив обязательно будет предоставлен.

Денис | 18.12.2009 08:57
0
спасибо, буду не с терпением ждать и следить за новыми уроками

Добавить комментарий:



Back to Top