Для создания контента в шаблоне используется элемент <action>, который должен быть либо сестринским узлом элемента query
либо прямым дочерним узлом элемента <rule>. Для каждого результата содержимое блока копируется и вставляется в документ. Давайте для начала рассмотрим простой пример.
<vbox datasources="https://www.xulplanet.com/ds/sample.rdf" ref="https://www.xulplanet.com/rdf/A"> <template> <query> <content uri="?start"/> <triple subject="?start" predicate="https://www.xulplanet.com/rdf/relatedItem" object="?relateditem"/> </query> <action> <button uri="?relateditem" label="?relateditem"/> </action> </template> </vbox>
Здесь элемент rule
не "обрамляет" элемента action
, поскольку мы хотим, чтобы контент был создан безусловно. Вместо этого, элемент action
помещён внутри элемента template
- сразу после запроса. Блок action содержит всего один элемент управления, но вы можете использовать сколь угодно много элементов по-своему усмотрению. В данном случае, для каждого результата будет создана кнопка. Поскольку мы имеем три результата, будет создано три кнопки. Если вы запустите [пример] в своём браузере, вы увидите что-то в этом роде:
Конструктор шаблонов последовательно обрабатывает содержимое блока action для каждого из трёх результатов. Атрибут кнопки uri используется для ссылки на значение конечной переменной (ending or member variable). В данном примере мы можем использовать только одну переменную ?relateditem, поскольку ?start - это начальная вершина, а конечная и исходная вершины не могут совпадать. Давайте снова посмотрим на имеющиеся результаты:
(?start = https://www.xulplanet.com/rdf/A, ?relateditem = https://www.xulplanet.com/rdf/B) (?start = https://www.xulplanet.com/rdf/A, ?relateditem = https://www.xulplanet.com/rdf/C) (?start = https://www.xulplanet.com/rdf/A, ?relateditem = https://www.xulplanet.com/rdf/D)
Конструктор начинает обрабатывать первый набор данных. При этом элемент <button> будет скопирован и вставлен в документ - сразу же после тела шаблона. Атрибут id нового элемента получит значение ?relateditem. Вы можете мысленно представить замену атрибута uri на id, заменяя при этом переменную. Поскольку в первом наборе данных переменная ?relateditem имеет значение 'https://www.xulplanet.com/rdf/B', атрибут id получит это значение.
После этого обрабатываются все остальные атрибуты элемента и, если нужно, в них подставляются значения переменных. Так, вместо строки ?relateditem атрибута label получим 'https://www.xulplanet.com/rdf/B' (для первого набора данных). Убедитесь, что первая кнопка действительно имеет такую надпись. Таким образом, обработка первого результата завершена, и поэтому конструктор переходит к следующим. Для второго результата, которому соответствует узел B, конструктор создаст следующий контент:
<button id="https://www.xulplanet.com/rdf/B" label="https://www.xulplanet.com/rdf/B"/>
В блоках action фиксированные, заранее определенные значения атрибута id не используются - они игнорируются. Тем не менее, вы можете использовать предопределённые идентификаторы в других частях шаблона, например, в запросе. Для получения доступа к созданному шаблоном элементу используется, конечно же, метод getElementById. Так можно получить доступ ко второй созданной кнопке: document.getElementById("https://www.xulplanet.com/rdf/C").
После окончания работы конструктора шаблонов документ имеет вид:
<vbox datasources="https://www.xulplanet.com/ds/sample.rdf" ref="https://www.xulplanet.com/rdf/A"> <template> <query> <content uri="?start"/> <triple subject="?start" predicate="https://www.xulplanet.com/rdf/relatedItem" object="?relateditem"/> </query> <action> <button uri="?relateditem" label="?relateditem"/> </action> </template> <button id="https://www.xulplanet.com/rdf/B" label="https://www.xulplanet.com/rdf/B"/> <button id="https://www.xulplanet.com/rdf/C" label="https://www.xulplanet.com/rdf/C"/> <button id="https://www.xulplanet.com/rdf/D" label="https://www.xulplanet.com/rdf/D"/> </vbox>
Поскольку тэг <template> скрыт, вы увидите только три кнопки с надписями, полученными из источника данных.
Дополнительный контент
В предыдущем примере в блоке action были задействованы только кнопки. Но мы можем добавить рядом с ними надписи:
<action> <hbox uri="?relateditem"> <label value="Related Item:"/> <button label="?relateditem"/> </hbox> </action>
Таким образом, для каждого набора данных будет создан элемент <hbox>; при это атрибут id получит значение ?relateditem; внутри будут добавлены надпись и кнопка. Надпись на кнопке образована переменной ?relateditem. В данном случае атрибут id используется только для одного элемента, поскольку каждому результату соответствует лишь один блок <hbox>.
Не смотря на то, что атрибут uri используется лишь для одного элемента, этим элементом не обязан быть внешний элемент - прямой потомок элемента action. Вы можете "обернуть" этот элемент другим; таким образом вы получите контейнер, внутри которого и создаётся контент. Этот контейнер создаётся один раз для всех наборов данных. Таким образом для каждого результата копируется только тот элемент, который имеет атрибут uri. Изменив предыдущий пример, получим:
<action> <toolbar> <button uri="?relateditem" label="?relateditem"/> </toolbar> </action>
В данном случае для каждого результата будет скопирована только кнопка; панель инструментов будет создана лишь один раз. Таким образом, будет создана панель инструментов с тремя кнопками. Естественно, в таком простом примере было бы лучше поместить шаблон внутрь панели инструментов, имеющей атрибут datasource, а не наоборот.
До сих пор мы использовали только переменную ?relateditem, поскольку это единственная полезная переменная. Можно использовать также переменную ?start. Посмотрим на результаты ещё раз:
(?start = https://www.xulplanet.com/rdf/A, ?relateditem = https://www.xulplanet.com/rdf/B) (?start = https://www.xulplanet.com/rdf/A, ?relateditem = https://www.xulplanet.com/rdf/C) (?start = https://www.xulplanet.com/rdf/A, ?relateditem = https://www.xulplanet.com/rdf/D)
Можно отобразить значение переменной ?start:
<action> <hbox uri="?relateditem"> <button label="?start"/> <button label="?relateditem"/> </hbox> </action>
Для первой кнопки значение переменной ?start будет вычислено в выходных данных, тогда как вторая кнопка использует значение переменной ?relateditem. Поскольку все результаты используют одно и тоже значение переменной ?start, первая кнопка в каждом ряду имеет одну и ту же надпись. Запустите этот [this пример] и удостоверьтесь, что всё работает правильно.