Server Side Includes

Автор: Topol Воскресенье, Апрель 15th, 2012 Нет комментариев

Рубрика: Программирование

Для начала о причинах, побудивших написать меня эту статью: в обсуждениях членов Всероссийского Клуба Вебмастеров не раз возникали споры о том, что лучше применять в случае повторяющейся разметки (информации) на большом количестве страниц — фреймы, JavaScript или SSI (Server Side Includes). Моим глубоким убеждением является то, что фреймы следует использовать только там, где без этого действительно никак не обойтись, 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» —>)
Такая конструкция используется на веб-узле компании Дункан Сервис (http://www.duncan.ru/catalog/price.html).

Борьба с <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>

Подобная конструкция используется на веб-узле Всероссийского Клуба Вебмастеров (http://www.webclub.ru/).

Борьба с пунктами меню
Предположим, у нас есть несколько разделов веб-узла, документы, относящиеся к разделам, лежат в разных директориях. Задача — сделать так, чтобы в меню навигации по этим разделам пропадала (или не подсвечивалась, выделялась другим цветом и т.д.) ссылка на тот раздел, в котором находится пользователь в данный момент. Для этого можно использовать переменную 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 (http://www.web2000.ru/).

Контекстный вывод текста в зависимости от условий
Предположим, у нас стоит задача менять внешний вид первой страницы узла в зависимости от того, откуда пришел пользователь. Для реализации этой задачи используется следующая конструкция:

<!—#if expr=»$HTTP_REFERER=/www.zzz.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) на веб-узле журнала «ОМ» (http://www.om.ru/).

Борьба с оформлением результатов работы скриптов
Самая большая проблема со скриптами заключается в том, что если есть большое количество наработанного ПО — при смене дизайна требуется их перенастройка. Хорошо, если ПО сделано правильно и изменение шаблонов отображения не касается самой математики, однако и в таких случаях существуют проблемы. Например, на странице поиска было бы неплохо крутить баннеры и рекламных сетей, но директивы 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» —>

Баннеры, кэширование и SSI
Прислал Кирил Хлопов (NewTech)
Как известно, баннерные системы предлагают включать в код некоторую случайную величину в 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://www.linkexchange.ru/users/some_id/goto.map 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 (как среди некоторых пользователей сейчас это модно) может быть выключен. На мой взгляд вполне радужно :-)
Все это проверено и применяется нашим администратором на http://www.j2.ru/

Один шаблон отображения — разное содержание
Прислал Евгений Беспальчиков (KADIS)
Часто шаблоны используют таким образом:
есть только один файл, который описывает структуру страницы, а основное содержание включается директивой

<!—#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 — страница корневого индекса (оглавления) и просто заглушка.

Источник: webcorp.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты