В реальных веб-проектах очень часто одна и та же часть повторяется практически на всех страницах сайта: например, меню, "шапка", "подвал", блок с последними новостями и т.п. В этой главе мы узнаем, как с помощью XS2 организовать повторное испльзование методов. В обычном PHP повторное использование фрагментов кода чаще всего осуществляют с помощью функции include(), которая просто вставляет код из определенного файла в место своего вызова в текущем коде. В XS2 примерно той же цели служит функция xs2Fetch(), которая выполняет произвольный метод в месте своего вызова. Для того, чтобы познакомится с ее работой поближе, реализуем следующую задачу. Мы вынесем код, который выводит на главной странице новости конкретной ленты в отдельный метод, а на главной странице будем вызывать его для каждой из выбранных лент.
Для начала мы создадим метод, в который вынесем вывод последних пяти новостей из конкретной ленты. Мы назовем его "hotnew" и прикрепим к типу "news_feed" модуля "news". Для начала мы просто скопируем строки №9-21 из Листинга 10:
Сохранив новый метод, мы на время оставим его и займемся модификацией метода главной страницы. Строки №9-21 из Листинга 10 мы заменим вызовом фукнции xs2Fetch:
Функция xs2Fetch в качестве параметров принимает те же самые данные, которые передаются в URL для доступа к определенному методу: модуль ("mod"), тип ("obj") и имя метода ("met"), который необходимо вызвать. Для наглядности приведем сравнение вариантов вызова метода xs2Fetch с вариантами URL, описанными в Главе 4:
Если метод прикреплен непосредственно к проекту, то вызов имеет вид {xs2Fetch met="имя метода"} http://имя домена/имя метода/
Если метод прикреплен к модулю, то его URL имеет вид {xs2Fetch mod="имя модуля" met="имя метода"} http://имя домена/имя модуля/имя метода
Если метод прикреплен к типу, то его URL имеет вид {xs2Fetch mod="имя модуля" obj="имя типа" met="имя метода"} http://имя домена/имя модуля/имя типа/имя метода/
Кроме этого, через атрибут "atr" можно передать в вызываемый метод параметры, разделенные "." точно так же, как и в URL, но только без конечного ".htm". Например, следующие две строки производят совершенно одинаковый вызов одного и того же метода из шаблона и из браузера соответственно:
Передача атрибутов, разделенных точкой, производится в URL и xs2Fetch аналогично, однако способы обращения к этим атрибутам в вызываемых методах различны. Обратите внимание на эту разницу.
Атрибуты, переданные через URL всегда доступны методу через массив $_THE.PARAMS.
Артрибуты, переданные через параметр "atr" при вызове xs2Fetch доступны исключительно в вызываемом методе через массив $_THE.FETCH.PARAMS.
За счет этой разницы методы, которые включаются в другие методы, имеют доступ к тем самым первоначальным параметрам, которые были переданы через URL. Для иллюстрации сказанного расмотрим следующую схему.
Если создать три изображенных на схеме метода и в каждый поместить код из соотвествующих квадратных скобок, а затем вызвать в браузере URL http://www.example.com/index/a.b.htm, то мы получим следующее:
Метод A: Параметр 1 = a, Параметр 2 = b
Метод B: Параметр 1 = a, Параметр 2 = b
Метод B: Параметр xs2Fetch 1 = c, Параметр xs2Fetch 2 = d
Метод C: Параметр 1 = a, Параметр 2 = b
Метод C: Параметр xs2Fetch 1 = e, Параметр xs2Fetch 2 = f
Как вы уже поняли, вызов xs2Fetch в шаблоне Smarty приводит к вставке результата выполнения другого метода в то месте, где стоит вызов. А что будет, если вызвать эту функцию в процессоре? Точно так же, как и при вызове в шаблоне, выполнится вызываемый метод, однако не произойдет вывод результата его выполнения непосредственно в место вызова. Однако результат выполнения xs2Fetch можно вернуть в переменную, которою затем используется для вывода. В Листинге 16 показано, что сам вызов xs2Fetch не приводит к выводу данных, а лишь к их возврату:
Вернемся к нашей задаче. В методе главной страницы в вызове xs2Fetch через параметр "atr" мы передаем идентификатор очередной ленты новостей. Теперь необходимо изменить код метода /news/news_feed/hotnews так, чтобы функция xs2GetChildren брала идентификатор ленты из переданного методу значения:
Вызвав в браузере главную страницу сайта мы должны увидеть, что несмотря на модификацю методов, ничего не изменилось - по-прежнему выводится по пять свежих новостей в каждой ленте.
Теперь мы можем использовать метод /news/news_feed/hotnews/ повторно. Например, мы можем использовать его на странице новости для вывода пяти свежих новостей из той же ленты, что и текущая новость. Для этого изменим код метода /news/news_post/show следующим образом:
В строке №14 мы передаем через параметр "atr" содержимое поля "ParId" текущей новости. Поле "ParId" является системным и обязательно присутствует в любом узле XS2. Оно содержит идентификатор родительского узла. Поскольку узлы типа "Новость" по нашей модели данных вкладываются в узлы типа "Лента новостей", то мы знаем, что поле "ParId" у каждой новости содержит идентификатор ленты, к которой она принадлежит. Если теперь с главной страницы мы перейдем на любую новость, то под текстом новости и над формой отправки комментария мы увидим блок с пятью самыми свежими заголовками.