Для начала о причинах, побудивших написать меня эту
статью: в обсуждениях членов Всероссийского Клуба Вебмастеров не раз возникали
споры о том, что лучше применять в случае повторяющейся разметки (информации) на
большом количестве страниц - фреймы, JavaScript или SSI (Server Side Includes,
внимание: приведенные примеры работают для XSSI под веб-сервером Apache). Моим
глубоким убеждением является то, что фреймы следует использовать только там, где
без этого действительно никак не обойтись, JavaScript (да и любые другие
клиентские скрипты) слишком капризен и зависит от настроек браузера, поэтому его
можно использовать только для дополнительных возможностей, но никак для
построения, допустим, системы навигации. Я не буду с пеной у рта доказывать, что
технология SSI круче всех гор и яиц, а просто приведу решения часто
встречающихся на практике задач с применением этой технологии.
(Сразу
предвижу возмущение со стороны приверженцев технологий ASP и PHP, с
использованием которых также возможны решения подобных задач, поэтому специально
для них: технология SSI значительно проще, в ней всего десяток операций, поэтому
для не программиста это более удачный выбор хотя бы потому, что ее можно быстрее
освоить)
Дата последней модификации документа, простая
директива:
<!--#echo var="LAST_MODIFIED"-->
Сегодняшнее
число в нужном формате
Если нам нужно вывести дату не в стандартном для
данной конфигурации программных средств виде, а в том, какой нам нужен
(например, "вторник, 30 мая, 2000"), то можно воспользоваться следующей
конструкцией:
Получение дня недели:
<!--#config
timefmt="%u" -->
<!--#set var="NUM_DAY"
value="$DATE_LOCAL"-->
<!--#if expr="$NUM_DAY=1"
-->
<!--#set var="DAY" value="понедельник" -->
<!--#elif
expr="$NUM_DAY=2" -->
<!--#set var="DAY" value="вторник"
-->
<!--#elif expr="$NUM_DAY=3" -->
<!--#set var="DAY"
value="среда" -->
<!--#elif expr="$NUM_DAY=4" -->
<!--#set
var="DAY" value="четверг" -->
<!--#elif expr="$NUM_DAY=5"
-->
<!--#set var="DAY" value="пятница" -->
<!--#elif
expr="$NUM_DAY=6" -->
<!--#set var="DAY" value="суббота"
-->
<!--#else -->
<!--#set var="DAY" value="воскресенье"
-->
<!--#endif -->
Получение числа:
<!--#config
timefmt="%e" -->
<!--#set var="DATE"
value="$DATE_LOCAL"-->
Получение названия
месяца:
<!--#config timefmt="%m" -->
<!--#set
var="NUM_MONTH" value="$DATE_LOCAL"-->
<!--#if expr="$NUM_MONTH=01"
-->
<!--#set var="MONTH" value="января" -->
<!--#elif
expr="$NUM_MONTH=02" -->
<!--#set var="MONTH" value="февраля"
-->
<!--#elif expr="$NUM_MONTH=03" -->
<!--#set var="MONTH"
value="марта" -->
<!--#elif expr="$NUM_MONTH=04"
-->
<!--#set var="MONTH" value="апреля" -->
<!--#elif
expr="$NUM_MONTH=05" -->
<!--#set var="MONTH" value="мая"
-->
<!--#elif expr="$NUM_MONTH=06" -->
<!--#set var="MONTH"
value="июня" -->
<!--#elif expr="$NUM_MONTH=07" -->
<!--#set
var="MONTH" value="июля" -->
<!--#elif expr="$NUM_MONTH=08"
-->
<!--#set var="MONTH" value="августа" -->
<!--#elif
expr="$NUM_MONTH=09" -->
<!--#set var="MONTH" value="сентября"
-->
<!--#elif expr="$NUM_MONTH=10" -->
<!--#set var="MONTH"
value="октября" -->
<!--#elif expr="$NUM_MONTH=11"
-->
<!--#set var="MONTH" value="ноября" -->
<!--#else
-->
<!--#set var="MONTH" value="декабря" -->
<!--#endif
-->
Получение года:
<!--#config
timefmt="%G" -->
<!--#set var="YEAR"
value="$DATE_LOCAL"-->
Собственно вывод получившейся
строки:
<!--#echo var="DAY" -->, <!--#echo var="DATE" -->
<!--#echo var="MONTH" -->, <!--#echo var="YEAR"-->
Форматы параметров для config timefmt надо смотреть
для каждой конфигурации веб-сервера отдельно. Приведенный пример - FreeBSD,
Apache. Более подробно см. man timefmt
Подобная конструкция используется на
веб-узле интернет-магазина Levingston.Ru
Дата модификации внешнего
файла: Часто на компьютерных сайтах выкладывают прайс-лист
в формате MS Excel или Word и каждый раз руками прописывают дату его
изготовления. С помощью SSI это делается примерно следующим
образом:
<a
href=pricelst.doc>Прайс-лист</a>
<!--#config timefmt="%d.%m.%y"
-->
(MS Word 6.0/95, <!--#flastmod virtual="pricelst.doc"
-->)
Такая конструкция используется на веб-узле компании Дункан
Сервис.
Борьба с <noframes>:
Как правило, в этом контейнере пишут "извините,
но вам следует обновить браузер", по идее же там должны быть альтернатива для
пользователей старых версий браузеров. Поскольку на нормальном сервере
информация часто меняется, а вебмастеру же лениво каждый раз вносить правки в
двух местах. С помощью SSI проблема решается раз и навсегда: в контейнер
<noframes></noframes> вносится директива, вставляющая тот самый
файл, в котором делаются правки или попросту линейку навигации.
Борьба
с прямыми ссылками на документы на веб-узле с фреймами:
Одним из аргументов против использования фреймовых
структур при создании веб-узлов является неудобство прямых ссылок на
содержательные файлы. Например, при ссылке из поисковых машин или на конкретный
(не корневой) документ с другого веб-узла пользователь попадает на страницу,
лишенную оформления или элементов навигации, которые обычно помещаются в
отдельный навигационный фрейм. С помощью нехитрой конструкции SSI эту проблему
можно решить. Для этого необходимо проанализировать, откуда пришел пользователь
(переменная HTTP_REFERER) Если он пришел не с нашего сервера, а извне -
построить фреймовую структуру и в качестве содержательного фрейма подставить
документ, запрошенный пользователем.
В примере ниже файл content.html -
это тот документ, на который стоит прямая ссылка (допустим, из поисковой
машины), frame.html - файл в котором строится фреймовая структура. В
QUERY_STRING подставляется значение done для того, чтобы избежать бесконечной
вложенности фреймовых структур.
Файл
content.html
<html>
<head>
...
<!--#include
virtual="frame.html"
-->
</head>
<body>
...
</body>
</html>
Файл
frame.html
<!--#if expr="$QUERY_STRING!=done &&
$HTTP_REFERER!=/your_domain\.ru/" -->
<frameset
rows="150,*">
<frame name="NAVIGATION"
src="/navigation.html">
<frame name="CONTENT" src="<!--#echo
var="DOCUMENT_URI" -->?done">
</frameset>
<!--#endif
-->
Подобная конструкция используется на веб-узле интернет-магазина
Болеро.
Версия страницы для печати:
Часто возникает прикладная задача - красивый
многоколоночный дизайн с верхней и нижней шапками, туча баннеров, но при печати
все это не нужно - лишняя бумага, ненужная информация... Поэтому хочется сделать
простой альтернативный вид страницы специально для печати. Чтобы это проделать,
достаточно подготовить два варианта верхней и нижней шапок, один --для экранного
отображения, другой - для печати. В качестве переключения между этими вариантами
используем переменную QUERY_STRING. Ниже приведены принципиальные структуры для
самой страницы (file.html) и для верхней и нижней шапок (top.html и
bottom.html).
Структура самой страницы
(file.html):
<!--#include virtual="top.html?$QUERY_STRING"
-->
здесь тело документа
<!--#include
virtual="bottom.html?$QUERY_STRING" -->
Структура top.html и
bottom.html
<!--#if expr="$QUERY_STRING == /for_printing/"
-->
шапка для печати
<!--#else -->
шапка для
просмотра
<!--#endif -->
Ссылка на каждой странице должна быть
вида:
<a href=<!--echo var="$DOCUMENT_URI"
-->?for_printing>версия для печати</a>
Подобная конструкция
используется на веб-узле Всероссийского Клуба Вебмастеров.
Борьба с
пунктами меню:
Предположим, у нас есть несколько разделов веб-узла,
документы, относящиеся к разделам, лежат в разных директориях. Задача - сделать
так, чтобы в меню навигации по этим разделам пропадала (или не подсвечивалась,
выделялась другим цветом и т.д.) ссылка на тот раздел, в котором находится
пользователь в данный момент. Для этого можно использовать переменную
DOCUMENT_URI.
<!--#if expr="$DOCUMENT_URI!=/^\/index.html/"
-->
<a href="/">Первая
страница</a><br>
<!--#endif -->
<!--#if
expr="$DOCUMENT_URI!=/\/about\/index.html/" -->
<a href="/about/">О
нас</a><br>
<!--#endif -->
<!--#if
expr="$DOCUMENT_URI!=/\/done\/index.html/" -->
<a
href="/done/">Наши работы</a><br>
<!--#endif
-->
<!--#if expr="$DOCUMENT_URI!=/\/partner\/index.html/"
-->
<a href="/partner/">Наши
партнеры</a><br>
<!--#endif -->
<!--#if
expr="$DOCUMENT_URI!=/\/client\/index.html/" -->
<a
href="/client/">Наши клиенты</a><br>
<!--#endif
-->
<!--#if expr="$DOCUMENT_URI!=/\/price\/index.html/"
-->
<a href="/price/">Наши
цены</a><br>
<!--#endif -->
<!--#if
expr="$DOCUMENT_URI!=/\/contacts\/index.html/" -->
<a
href="/contacts/">Наши координаты</a><br>
<!--#endif
-->
<!--#if expr="$DOCUMENT_URI!=/\/history\/index.html/"
-->
<a href="/history/">Наша
история</a><br>
<!--#endif -->
<!--#if
expr="$DOCUMENT_URI!=/\/search.html/" -->
<a
href="/search.html">Поиск</a><br>
<!--#endif
-->
Подобная конструкция используется веб-узле компании Веб
2000.
Контекстный вывод текста в зависимости от условий:
Предположим, у нас стоит задача менять внешний вид
первой страницы узла в зависимости от того, откуда пришел пользователь.
Например, компания Веб 2000 ставит на поддерживаемых ею проектах надпись-ссылку
Supported by Web 2000, а при клике по ней пользователь попадает на первую
страницу веб-узла компании и видит всплывющую подсказку с подробностями о
разработке именно того проекта, с которого он пришел (попробуйте нажать на
ссылку с веб-узла журнала "ОМ" - "Поддержка Веб 2000" - мелким шрифтом в левом
нижнем фрейме - увидите:-). Для реализации этой задачи используется следующая
конструкция:
<!--#if expr="$HTTP_REFERER=/om.ru/" -->
Здесь
пояснительный текст про веб-узел журнала ОМ
<!--#endif -->
т.е.
сравнивается переменная HTTP_REFERER.
Борьба с разными версиями
дизайна для разных браузеров:
Всем известно, что браузеры различных производителей
и версий по-разному отображают одну и ту же HTML-разметку документа, начиная от
специальных тагов и атрибутов и заканчивая поддержкой различных версий
JavaScript. Для того, чтобы веб-узел выглядел нормально и для одной версии
браузера и для другой или чтобы не сыпались ошибки JavaScript средствами SSI
можно сделать проверку версий или браузеров и выдавать различные варианты
HTML-разметки. Для этого анализируется переменная HTTP_USER_AGENT, в которой
содержится информация о типе и производителе браузера:
<!--#if
expr="$HTTP_USER_AGENT=/Mozilla\/4/ || $HTTP_USER_AGENT=/Mozilla\/5/"
-->
Если версия браузера не ни же 4 или 5, то вывести вариант дизайна,
использующий, например, DHTML
<!--#else -->
Здесь вывести простой
дизайн
<!--#endif -->
Подобная конструкция используется для
построения фреймовой структуры и выводе внутреннего меню (для Netscape - на
DHTML, для MSIE - на ActiveX) на веб-узле журнала "ОМ".
Борьба с
оформлением результатов работы скриптов:
Самая большая проблема со скриптами заключается в
том, что если есть большое количество наработанного ПО - при смене дизайна
требуется их перенастройка. Хорошо, если ПО сделано правильно и изменение
шаблонов отображения не касается самой математики, однако и в таких случаях
существуют проблемы. Например, на странице поиска было бы неплохо крутить
баннеры и рекламных сетей, но директивы SSI не отрабатываются в файлах .cgi.
Решить подобные проблемы можно использованием SSI следующим образом: не скриптом
обрабатывать шаблоны отображения, а вызывать скрипт из HTML-документа через SSI
(к сожалению, таким образом можно работать только с теми скриптами, которые
используют метод GET - переменная CONTENT_LENGTH не доступна в SSI) Итак, как
это делается Есть HTML-документ, который размечен в общем стиле дизайна. В него
вставляется директива:
<!--#include
virtual="/cgi-bin/script.cgi?$QUERY_STRING" -->
На первом шаге, пока
QUERY_STRING пуста - вызывается первый шаг скрипта, на последующих шагах работы
скрипта - передаются необходимые параметры. В самом скрипте важны три
строчки:
...
# определение адреса, куда направлять данные
$query
= $ENV{QUERY_STRING};
# определение места, из которого был вызван
скрипт
$uri = $ENV{DOCUMENT_URI};
...
# отправка данных в тот же
HTML-документ, из которого был вызван скрипт
print "<form action=$uri
method=get>\n";
...
Подобная конструкция использована в разделе
"Голосования" для интернет-супермаркета Levingston.Ru.
Что можно
сделать, используя Cookie и SSI:
Часто встречается конструкция на JavaScript, которая
выводит "Здравствуйте, Иван Иваныч!" при заходе на страницу веб-узла. То же
самое можно проделать с помощью SSI директивой:
<!--#echo
var="HTTP_COOKIE" -->
Как известно, баннерные системы предлагают
включать в код некоторую случайную величину в URL скрипта показа - защита от
кеширования.
Можно генерировать всю страницу скриптом, от первого до
последнего символа .
Можно сделать как советуют страницы помощи баннерных
систем - включить by SSI скрипт, генерящий случайный баннер
Динамически
записать часть документа с кодом банера JavaScrip-ом
А можно еще
так:
<!--#config timefmt="%s"-->
<!--#set var="RND"
value="$DATE_LOCAL"-->
<!-- Russian LinkExchange code START
-->
<iframe
src=http://www.linkexchange.ru/cgi-bin/erle.cgi?some_id?
<!--#echo
var="RND"-->
frameborder=0 vspace=0 hspace=0 width=468 height=60
marginwidth=0 marginheight=0 scrolling=no>
<a
href="http://wm-help.net/other_site_redirect.php?http/www.linkexchange.ru/users/some_id/goto.map" target="_blank" rel="nofollow"
target=_top>
<img
src=http://www.linkexchange.ru/cgi-bin/rle.cgi??<!--#echo
var="RND"-->
alt="RLE Banner Network" border=0 height=60
width=468></a>
</iframe>
<!-- Russian LinkExchange
code END -->
То есть как случайная величина выступит количество секунд от
1970 года. Не тратится время и память на запуск скрипта-генератора, Java-Script
(как среди некоторых пользователей сейчас это модно) может быть выключен. На мой
взгляд вполне радужно :-)
Все это проверено и применяется нашим
администратором на www.j2.ru.
Один шаблон отображения - разное
содержание:
Часто шаблоны используют таким образом:
есть только один файл,
который описывает структуру страницы, а основное содержание включается
директивой:
<!--#include
virtual="$QUERY_STRING.html"-->
ссылки, соответственно, будут иметь
вид:
href="www.your_domain.ru/index.html?page1"
href="www.your_domain.ru/index.html?page2"
...
Проблема
возникает, если пользователь набирает адрес непосредственно
http://www.your_domain.ru, т.е.
QUERY_STRING=""
Решение:
<!--#if expr="$QUERY_STRING"
-->
<!--#include virtual="$QUERY_STRING.html"-->
<!--#else
-->
<!--#include virtual="default.html"-->
<!--#endif
-->
где default.html - страница корневого индекса (оглавления) и просто
заглушка.
Пожалуй на этом пока все.
Источник: webportal.fud.ru