Семантическая разметка данных

В этой главе мы продолжим заниматься генерируемым содержимым и создадим раздел "См. также" для каждой Web-страницы нашего Web-сайта. В новый раздел мы поместим гиперссылки на Web-страницы со связанными материалами: описаниями тегов HTML и атрибутов стиля CSS, имеющих сходное назначение, и примерами использования того или иного тега или атрибута стиля. Раздел "См. также" будет генерироваться программно.

Также познакомимся с принципом семантической разметки данных и научимся создавать ее средствами JavaScript.

Введение в семантическую разметку данных

Создадим на всех Web-страницах раздел "См. также". Этот раздел будет включать гиперссылки на Web-страницы, хранящие описания тегов HTML и атрибутов стиля CSS, имеющих аналогичное назначение, и тексты примеров использования данного тега или атрибута стиля, т. е. гиперссылки на Web-страницы со сведениями, которые так или иначе связаны с текущей Web-страницей.

Такие данные, связанные друг с другом, в Web-дизайне и Web-программировании встречаются очень часто. Это не обязательно Web-страницы — связанными могут быть и данные, обрабатываемые Web-сценариями.

В таком случае говорят, что между данными установлены семантические связи. Такие связи указывают, что эти данные имеют отношение "главный — подчиненный", "метка — собственно данные", являются составными частями большой структуры данных или цепочки связанных данных. А процесс установки семантических связей между данными называется семантической разметкой.

Примером данных, связанных отношениями "главный — подчиненный", можно назвать набор Web-страниц, одна из которых содержит оглавление большого текста, а остальные — отдельные главы этого текста. Оглавление представляет собой набор гиперссылок, указывающих на Web-страницы с отдельными главами, причем гиперссылки и выступают в качестве семантических связей.

Web-дизайнер может создать на каждой Web-странице, хранящей отдельную главу, гиперссылку на Web-страницу, где представлена следующая глава. Это пример семантической связи данных в цепочку, где в качестве связи выступают также гиперссылки.

Реализация семантической разметки средствами JavaScript

Еще раз перечислим, что попадет в раздел "См. также" каждой Web-страницы.

• Гиперссылки на Web-страницы, описывающие теги HTML и атрибуты стиля CSS со сходным назначением.

• Гиперссылки на Web-страницы с примерами применения данного тега или атрибута стиля.

• Гиперссылки на Web-страницы с описаниями тегов и атрибутов стиля, присутствующих в данном примере.

Раздел "См. также" будет генерироваться программно, специальным Web-сценарием. Генерироваться он будет на основе каких-то данных — это очевидно. Но каких?

Ранее мы создали базу данных, хранящую список всех Web-страниц нашего Web-сайта с их интернет-адресами и краткими названиями. На ее основе создаются вложенные списки в полосе навигации; краткие названия Web-страниц превращаются в тексты пунктов, а их интернет-адреса становятся интернет-адресами гиперссылок, помещаемых в эти пункты.

Напрашивается решение: для каждой Web-страницы создать подобную, но "локальную" базу данных, которая будет хранить список связанных Web-страниц. Тогда мы сможем написать Web-сценарий, который "просмотрит" эту базу данных и в итоге создаст раздел "См. также".

Мы не будем хранить в "локальной" базе данных полное описание этих Web-страниц, с краткими названиями и интернет-адресами. Лучше хранить в ней индексы соответствующих элементов "глобальной" базы данных, хранящейся в файле data.js, и какой-либо признак, указывающий, в каких именно массивах, составляющих "глобальную" базу данных, находятся эти элементы. Тогда мы избежим многократного повторения одних и тех же сведений в разных базах данных.

А если (как в нашем случае) элементы "глобальной" базы данных хранят конфигураторы, или вообще экземпляры объектов, задача значительно упрощается. Вспомним, что говорилось в главе 14: переменная с экземпляром объекта фактически хранит ссылку на него, а при присваивании ее значения другой переменной выполняется присваивание именно ссылки — экземпляр объекта при этом не дублируется. Значит, мы можем присвоить элементам "локальной" базы данных экземпляры объектов, которые извлечем из соответствующих элементов "глобальной" базы данных.

Фактически мы реализуем семантическую связь между "локальными" и "глобальной" базами данных средствами JavaScript. Это будет связь типа "метка — собственно данные".

"Локальную" базу данных мы также оформим в виде Web-сценария, который объявляет соответствующий массив (или массивы), и сохраним его в том же файле, в котором хранится HTML-код Web-страницы (точнее, подгружаемого фрагмента содержимого). Так будет проще — на одну Web-страницу будет приходиться один файл, а не два.

Но тут возникает большая проблема. Дело в том, что средства подгрузки содержимого, предоставляемые Web-обозревателем, не выполняют ни хранящиеся в подгружаемом фрагменте внутренние Web-сценарии, ни привязанные к нему внешние. Это сделано ради безопасности.

Что же нам делать?

Поместить связанные данные, на основе которых будет формироваться раздел "См. также", прямо в "глобальную" базу данных. Для этого мы создадим в конфигураторах, описывающих отдельные Web-страницы, еще одно свойство — related. Оно будет хранить массив элементов массивов aHTML, aCSS и aSamples, описывающих связанные Web-страницы. Это свойство мы сделаем необязательным, т. е. в каких-то случаях его можно не указывать, и Web-сценарий, создающий раздел "См. также", сработает правильно.

Так мы создадим семантические связи типа "главный — подчиненный". В качестве связи будет выступать механизм массивов JavaScript.

Откроем файл Web-сценариев data.js, найдем в нем место, где заканчивается код, который объявляет массивы aHTML, aCSS и aSamples, и вставим туда такое выражение:

aHTML[0].related = [aHTML[4], aHTML[7], aHTML[10]];

Мы взяли первый элемент массива aHTML (с индексом 0), добавили к хранящемуся в нем конфигуратору свойство related и присвоили этому свойству массив из трех конфигураторов, хранящихся в пятом, восьмом и одиннадцатом элементах (индексы 4, 7 и 10) того же массива. Таким образом мы указали, что для Web-страницы с описанием тега <!DOCTYPE> связанными являются Web-страницы с описаниями тегов <HEAD>, <META> и <TITLE>.

Но почему мы написали это выражение после кода, объявляющего все элементы массивов aHTML, aCSS и aSamples? Да потому, что перед тем, как присваивать какой-либо переменной или элементу массива экземпляр объекта, его нужно создать. Иначе данная переменная или элемент массива получит значение undefined, что нам совсем не нужно.

После этого выражения добавим такое:

aHTML[8].related = [aHTML[3], aHTML[9], aCSS[0]];

Здесь мы указали, что для Web-страницы с описанием тега <P> (именно эту Web-страницу описывает элемент массива aHTML с индексом 8) связанными являются Web-страницы с описаниями тегов <EM> и <STRONG> и атрибута стиля border.

Аналогично укажем связанные данные для остальных Web-страниц нашего Web-сайта. Необязательно для всех — хотя бы для нескольких, чтобы только проверить, как все это работает.