Сайтостроительство

       

Server Side Includes


Server Side Includes - включения на стороне сервера. SSI представляет механизм включения одних документов внутрь других. Чем-то это схоже с фреймами по функциональному назначению, но есть существенные отличия. Во-первых, включать в один HTML-документ можно любой файл с HTML-кодом, совершенно не обязательно, чтобы он(HTML-код) представлял собой законченный HTML-документ. Например, у вас часть таблицы может быть в одном файле, часть в другом, а еще часть в третьем. Во-вторых, включать можно программы, которые, в свою очередь, могут связываться с базами данных, вызывать внутри себя другие программы и выдавать какие-либо отчеты и таблицы. Естественно, что эти программы выдают на STDOUT( поток стандартного вывода, для не программистов это экран монитора с командной строкой ) HTML-код, который затем и включается внутрь нашего исходного HTML-документа. И в третьих, SSI поддерживают переменные и элементарные инструкции языка программирования: if, elif и else. Server Side Includes работают следующим образом. У вас на сервере находится html-файл с командами SSI.

<!--#include virtual="/cgi-bin/head.pl?name=О нас" --> <p align=justify> Веб-студия ITSoft состоит из молодых специалистов, работающих в области информационных технологий более пяти лет. Мы занимаемся веб-дизайном, разработкой программного обеспечения, предоставляем услуги хостинга и создания локальных сетей. <!--#include virtual="/include/footer.inc"-->

Когда броузер клиента запрашивает у веб-сервера этот документ, то веб-сервер, прежде чем отдать его броузеру проверяет его на наличие SSI-команд. Когда веб-сервер встретит <!--#include virtual="/cgi-bin/head.pl?name=О нас" --> он запустит программу /cgi-bin/head.pl и передаст ей параметр name=О нас. Программа head.pl выдаст HTML-код с заголовком для нашего HTML-документа, в котором будет содержаться меню и название раздела. О том, как писать такие программы вы узнаете в третей части книги. Когда веб-сервер натолкнется на <!--#include virtual="/include/footer.inc"-->, то он просто включит HTML-код из файла /include/footer.inc в наш HTML-документ.
Там, собственно, хранится код завершающий любую HTML-страницу нашего веб-сайта. Таким образом, SSI позволяет избежать избыточности. Общий код для всех HTML-страниц нашего сайта хранится в одном месте. Теперь, если нам захочется добавить пункт меню или поменять что-либо еще, то нам не придется бегать по всему сайту и изменять каждый файл отдельно. Достаточно будет внести изменения в один файл. Для того чтобы начать экспериментировать с SSI-командами надо внести изменения в файл httpd.conf и перезапустить веб-сервер Apache. Найдите и раскомментируйте следующие две строчки в файле httpd.conf. Они указывают веб-серверу, что файлы с расширением shtml надо обрабатывать прежде, чем выдавать пользователю.

AddType text/html .shtml AddHandler server-parsed .shtml

Если вы собираетесь повсеместно использовать SSI, то добавьте еще и такую строчку. У нас SSI-команды присутствуют в большинстве HTML-документов, поэтому на нашем веб-сервере такая строчка присутствует в файле httpd.conf

AddHandler server-parsed .html

HTML-код для включения в HTML-документы обычно хранится в файлах с расширением inc. Включите и для этих файлов обработку SSI-директив. Это позволит делать рекурсивную обработку SSI-директив. Если в файле footer.inc будет SSI-директива, то она будет обработана.

AddHandler server-parsed .inc

Еще может потребоваться добавить опцию Includes в следующий раздел.

<Directory /> Options FollowSymLinks Indexes MultiViews Includes AllowOverride All </Directory>

На нашем сервере под управлением FreeBSD такая опция стоит. У меня дома на Windows98 ее нет и SSI работают. Возможно тут дело в различных версиях Apache.



Теперь перезапустите веб-сервер. Давайте рассмотрим SSI еще на одном примере, заодно разберем одну из самых распространенных структур организации HTML-документов. На большинстве сайтов, документы состоят из трех частей: заголовок, тело и завершающая часть. Для эксперимента создайте директорию на вашем веб-сайте и назовите ее ssi. В этой директории создайте head.inc со следующим содержанием:



<html> <body>

<table bgcolor=#0000FF width=600 height=100> <tr><td> Здесь будет заголовок и главное меню нашего вебсайта </table>

<table width=600 height=200> <tr><td width=120 bgcolor=#CCCCCC> Левое меню<br> пункт1<br> пункт2<br> пункт3<br> пункт4<br> пункт5<br> <td>

Все SSI-директивы имеют следующую семантику <!--#команда параметр="значение" параметр="значение"--> Создайте index.html:

<!--#include virtual="head.inc"--> Основное содержание HTML-документа. <!--#include virtual="footer.inc"-->

И footer.inc:

</table>

<table bgcolor=#0000FF width=600> <tr><td> Здесь будет завершающая часть HTML-документа, обычно это реклама </table>

</body> </html>

В результате, при запросе этого документа, веб-сервер выдаст:

<html> <body>

<table bgcolor=#0000FF width=600 height=100> <tr><td> Здесь будет заголовок и главное меню нашего вебсайта </table>

<table width=600 height=200> <tr><td width=120 bgcolor=#CCCCCC> Левое меню<br> пункт1<br> пункт2<br> пункт3<br> пункт4<br> пункт5<br> <td>

Основное содержание HTML-документа. </table>

<table bgcolor=#0000FF width=600> <tr><td> Здесь будет завершающая часть HTML-документа, обычно это реклама </table>

</body> </html>

Это одно из самых основных применений SSI. Теперь давайте рассмотрим использование переменных и условных операторов. Команда <!--#printenv --> выводит все переменные окружения, которые доступны по умолчанию. Ниже приведен результат действия этой команды на моем домашнем компьютере.

COMSPEC=C:\WINDOWS\COMMAND.COM DOCUMENT_ROOT=c:/projects/www/web-tehnolog HTTP_ACCEPT=*/* HTTP_ACCEPT_ENCODING=gzip, deflate HTTP_ACCEPT_LANGUAGE=ru HTTP_CONNECTION=Keep-Alive HTTP_COOKIE=testparam=testvalue HTTP_HOST=web.ru HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt) PATH=C:\Program Files\Apache Group\Apache;C:\WINDOWS;C:\WINDOWS\COMMAND; C:\ARCH;C:\JDK12\BIN;C:\PROGRA~1\ULTRAE~1 REMOTE_ADDR=127.0.0.1 REMOTE_PORT=1546 SCRIPT_FILENAME=c:/projects/www/web-tehnolog/chapter6.html SERVER_ADDR=127.0.0.1 SERVER_ADMIN=igor@itsoft.ru SERVER_NAME=web.ru SERVER_PORT=80 SERVER_SIGNATURE=Apache/1.3.12 Server at web.ru Port 80



SERVER_SOFTWARE=Apache/1.3.12 (Win32) WINDIR=C:\WINDOWS GATEWAY_INTERFACE=CGI/1.1 SERVER_PROTOCOL=HTTP/1.1 REQUEST_METHOD=GET QUERY_STRING= REQUEST_URI=/chapter6.html SCRIPT_NAME=/chapter6.html DATE_LOCAL=Monday, 26-Feb-2001 19:26:02 Московское время (зима) DATE_GMT=Monday, 26-Feb-2001 16:26:02 GMT LAST_MODIFIED=Monday, 26-Feb-2001 19:25:58 Московское время (зима) DOCUMENT_URI=/chapter6.html DOCUMENT_PATH_INFO= DOCUMENT_NAME=chapter6.html

Для того чтобы вывести значение отдельной переменной дайте команду <!--#echo var="var_name" -->. Например, <!--#echo var="LAST_MODIFIED" --> выдаст Monday, 26-Feb-2001 19:25:58 Московское время (зима).

Также вы можете определять и использовать свои собственные переменные. В файл index.html, который мы рассматривали выше, вставьте самой первой строкой <!--#set var="title" value="Заголовок нашего веб-сайта." -->. В head.inc добавьте следующую строчку <title><!--#echo var="title" --></title> после команды <html> и где идут слова "здесь будет заголовок" вставьте <h1><!--#echo var="title" --></h1>

В результате у вас должно получится для index.html

<!--#set var="title" value="Заголовок нашего веб-сайта." --> <!--#include virtual="head.inc"--> Основное содержание HTML-документа. <!--#include virtual="footer.inc"-->

и

<html> <title><!--#echo var="title" --></title> <body>

<table bgcolor=#0000FF width=600 height=100> <tr><td><h1><!--#echo var="title" --></h1> главное меню нашего веб-сайта </table>

<table width=600 height=200> <tr><td width=120 bgcolor=#CCCCCC> Левое меню<br> пункт1<br> пункт2<br> пункт3<br> пункт4<br> пункт5<br> <td>

Таким образом можно передавать параметры во включаемые куски HTML-кода.



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

Пример для графического меню с подсветкой:

<!--#if expr="$DOCUMENT_URI!=/\/about.html/" --><a href=/about.html onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('about','','/about2.gif',0)" ><!--#endif --><img src=/about1.gif width=212 height=38 border=0 name=about ><!--#if expr="$DOCUMENT_URI!=/\/about.html/" --></a ><!--#endif -->

Данный SSI-код используется на сайте .

Другой не менее важный SSI-код применяется для организации версии страниц для печати. Версия страницы сайта для печати отличается от обычной страницы отсутствием колонститулов, навигации, баннеров и прочей лишней информации. Рассмотрим, как организована версия для печати на примере сайта .

===Файл /include/head.inc === <html> <head> <title><!--#echo var="title"--></title> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <link rel=stylesheet href=/styles.css> </head>

<body bgcolor=FFFFFF text=474C54 link=566A89 vlink=96A7C1 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0> <basefont face=Arial>

<!--#if expr="$QUERY_STRING!=/for_printing/" --> ...здесь навигационный блок, графика, Flash-анимация и т.д. ...

<p > <a href=?for_printing=1&<!--#echo var="QUERY_STRING"-->> Версия для печати </a></p> <!--#endif -->

При нажатии на гиперссылку "версия для печати" страница, на которой находится пользователь, перегружается.


Но поскольку в строке запроса присутствует параметр for_printing, то лишний HTML-код не включается на страницу. Обратите внимание <!--#echo var="QUERY_STRING"-->. Это строка запроса CGI-параметров. В обычном случае, у вас никаких параметров, кроме for_printing нет, но когда появляются на сайте CGI-модули, то появляются и дополнительные параметры. Забегая вперед расскажу, как делать "Версию для печати" В CGI-программе. Пока веб-сервер Apache не может обрабатывать на SSI-директивы вывод CGI-программ. Такую возможность обещают в новых версиях Apache. У CGI-программистов есть два пути либо самим разобрать SSI-директивы в файле head.inc либо, что значительно проще, создать ручками файл phead.inc и подключать его в CGI-программах.

Условные операторы записываются следующим образом:

<!--#if expr="условие1" --> <!-- Здесь HTML-код1 --> <!--#elif expr="условие2" --> <!-- Здесь HTML-код2 --> <!--#else --> <!-- Здесь HTML-код3 --> <!--#endif -->

Для примера приведу SSI-код для вывода времени последней модификации документа в приемлемом виде. Как вы уже видели, команда <!--#echo var="LAST_MODIFIED" --> выдает совершенно не приемлемую строчку - Monday, 26-Feb-2001 19:25:58 Московское время (зима), для размещения ее на солидном веб-сайте. Нам бы хотелось получить что-нибудь, вроде 26 Февраля 2001 года. Для этого существует команда config с параметром timefmt, которая задает формат вывода даты. Например, в нашем случае нам требуется следующий вариант <!--#config timefmt="%e %B %Y"-->, тогда результат <!--#echo var="LAST_MODIFIED" --> будет 26 February 2001. Но это пока все равно не то, что бы нам хотелось. Для определения месяца мы воспользуемся условными операторами. Вот, как будет выглядеть этот код:

<!--#config timefmt="%m" --> <!--#set var="NUM_MONTH" value="$LAST_MODIFIED"--> <!--#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 -->



Соответственно, чтобы получить дату в формате 26 Февраля 2001.

<!--#config timefmt="%e"--><!--#echo var="LAST_MODIFIED" --> <!--#echo var="month" --> <!--#config timefmt="%Y"--><!--#echo var="LAST_MODIFIED" -->

Вот полный список значение параметра timefmt:
Формат Описание Пример
%a Аббревиатура названия дня недели Sun
%A Полное название дня недели Sunday
%b Аббревиатура названия месяца Jan
%B Полное название месяца January
%d День месяца 01 (не 1)
%D Дата в формате "%m/%d/%y" 01/31/90
%e День месяца 1
%H Часы в 24-часовом формате 13
%I Часы в 12-часовом формате 01
%j День года 235
%m Номер месяца 01
%M Минуты 03
%p AM|PM AM
%r Время в формате "%I:%M:%S %p" 11:35:46 PM
%S Секунды 34
%s Время в секундах с 01.01.1970 957228726
%T Время в формате "%H:%M:%S" 14:05:34
%U Неделя года 49
%w Номер дня недели 5
%y Год в формате ГГ 95
%Y Год в формате ГГГГ 1995
%Z Временная зона MSK
Далее приведены несколько полезных SSI-директив. Допустим, вы распространяете какие-либо утилиты и выкладываете ссылки на файлы для скачивания. Например, такие ссылки вы найдете на сайте . Для удобства пользователей неплохо было бы указать размер файла и иногда, дату его последней модификации. Каждый раз после выкладывания на сервер новых версий файла, модифицировать самому ручками все размеры и даты долго и мучительно. Server Side Includes приходят на помощь.

<a href=0.gif>Прозрачный gif-файл</a><br> Дата модификации:<!--#config timefmt="%d %B %Y" --> <!--#flastmod file="0.gif" --><br> Размер:<!--#config sizefmt="bytes"--> <!--#fsize file="0.gif" --> байта<br>


Дата модификации: 12 February 2002

Размер: 43 байта

Если у вас файлы больших размеров, то информацию лучше выводить в килобайтах.


Для этого установите формат вывода размера файла следующим образом.

<!--#config sizefmt="abbrev"-->

При возникновение какой-либо ошибки, например, при попытки включить в HTML-документ файл, которого не существует веб-сервер выдаст следующее сообщение:

[an error occurred while processing this directive]

Сообщение не слишком информативно и пугает пользователя, не так ли? Давайте изменим сообщение об ошибке следующей SSI-директивой

<!--#config errmsg="<b>На сервере произошла ошибка связанная с SSI, пожалуйста, напишите </b> <a href=mailto:igor@itsoft.ru>администратору</a>."-->

Теперь сообщение об ошибке вылядит так:

На сервере произошла ошибка связанная с SSI, пожалуйста, напишите .






Содержание раздела