Возможности по представлению сложных объектов реальности с помощью модели данных XS2 были бы весьма ограничены, если бы они сводились исключительно к конструированию произвольных полей и построению деревьев узлов. Один из основных элементов модели данных XS2 - это ссылки между узлами. Ссылки реализованы как особый тип поля под названием lnk, который позволяет указать в качестве значения поля узел заранее заданного типа. Приведем пример.
У нас имеется два типа узлов: "Книга" и "Автор". Мы хотим сделать так, чтобы в узле "Книга" указвался бы ее автор (или авторы), и это указание представляло бы собой просто ссылку на объект типа "Автор". Для этого достаточно создать в типе "Книга" поле с произвольным названием, скажем, "Автор книги", и, указывав для него тип "lnk", настроить параметры поля так, чтобы в нем можно было выбрать один или несколько узлов типа "Автор". Попробуем воспользоваться ссылками на практике.
Наша задача на этот раз будет следующей: необходимо создать в системе тип "Автор", который будет хранить информацию обо всех редакторах, пишущих новости на стайте. Кром того, в узлах типа "Новостное сообщение" необходимо добавить поле для указания автора или авторов новости. На главной странице необходимо выводить ФИО автора рядом с заголовком.
Начнем с создания типа "Автор". В поле "NName" мы будем хранить ФИО автора, остальные поля для нас сейчас не важны - вы можете добавить их по собственному усмотрению. Например, вы можете хранить в создаваемом типе телефон, электронный адрес, номер ICQ и т.п. Теперь необходимо добавить новое поле "Авторы" в тип "Новостное сообщение". В форме редактирования типа нажмем на кнопку "Добавить поле". Назовем наше поле "NewsAuthors" с псевдонимом "Авторы новости". В выпадающем списке типов поля выберем тип "lnk". Далее необхоидимо указать дополнительные параметры поля. Для этого нажмем на небольшую кнопку справа от выпадающего списка. В открышемся окне мы увидим следующие поля и секции:
Единственная ссылка - если выставить этот флажок, то в поле можно будет указать только один узел. Поскольку мы хотим, чтобы у новости можно было указать несколько автором, мы оставим этот флажок неотмеченным.
Показывать в виде выпадающего списка - если отметить этот флажок, то выбор объекта в форме редактирования узла будет выглядеть как выпадающий список. При небольшом количестве узлов этот способ выбора очень удобен, поскольку требует всего два клика. Однако он становится неэффективным при большом количестве узлов. В этом случае удобнее использовать форму подбора узлов. Мы оставим этот флажок неотмеченны.
Линкуемые типы - это список все типов, имеющихся в проекте. Отмечая галочками различные типы, вы сообщаете системе узлы какого типа можно будет указывать в данном поле. Мы отметим только недавно созданный тип "Автор".
Сохранив тип, перейдем к созданию тестовых узлов. В модуле "Новости" добавим несколько узлов типа "Автор". Пока им можно разместить непосредственно в корне модуля, рядом с объектами типа "Новостная лента". Теперь укажем авторов для нескольких произвольных новостей. В форме редактирования новости в поле "Авторы" нажмите на кнопку "+". В открывшемся окне подбора узлов можно выбрать узел из списка всех узлов - для этого нужно просто нажать на кнопку "Поиск", - или же найти нужные узлы по полю. Если вы хотите найти, скажем, узел, у которого в поле "ФИО" указано "Толстой", то нажмите на название поля "ФИО" и в появившемся поле введите "Толстой". После нажатия на кнопку "Поиска" появится список узлов, в которых в названии встречается введенная подстрока. Обрастите внимание, что в поле "Авторы" вы можете указать несколько узлов типа "Автор".
Закончив с созданием тестовых объектов, перейдем к модификации шаблона первой страницы.
Строки №№14-16 выводят список авторов новости. Несложно догадаться, что поле "Author" типа "lnk" представляет собой обычный массив, в котором хранятся все те узлы, которые контент-менеджер указал в этом поле в интерфейсе. Таким образом, чтобы вывести всех авторов, мы просто организовали цикл по этом массиву ($my_news_post.Authors). На каждой итерации цикла для каждого автора мы выводим его ФИО, следом за которыми ставим запятую, если текущая итерация цикла не последняя (более подробно о конструкции проверки последней итерации см. описание foreach в документации Smarty). У разработчика может возникнуть справедливый вопрос: а как будет выглядеть поле "Authors" в узле, если в нем допускается указание всего одного узла (т.е. у поля в параметрах отмечена галочка "Единственная ссылка")? Поле будет выглядеть точно также - это будет массив. Просто у него будет всего один элемент с индексом 0. Если бы у новости мы допускали бы указание только одного автора, то код строк №№14-16 Листинга 10 выглядел бы вот так:
В строке №4 мы вывели ФИО первого автора, хранящегося в поле "Author" текущей новости. Таким образом, разработчику важно помнить, что независимо от того, сколько узлов можно указывать в поле типа "lnk", в шаблоне и процессоре узел содержит в соответствующем поле массив минимум из одного элемента. Часто встречается ошибка, когда доступ к полям связанного узла пытаются получить вот так - {$my_news_post.Author.NName}, когда как правильное обращение выглядит следующим образом - {$my_news_post.Author[0].NName}.
Открыв первую страницу сайта в браузере, вы должны увидеть, что для тех новостей, у которых указаны авторы, они выводятся под заголовком через запятую.