SSI в прикладах

Для початку про причини, що спонукали написати мене цю статтю: в обговореннях членів Всеросійського Клубу Вебмастеров не раз виникали суперечки про те, що краще застосовувати в разі повторюваної розмітки (інформації) на великій кількості сторінок - фрейми, 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" ->) 

Така конструкція використовується на веб-сайті компанії Дункан Сервіс

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

Контекстний висновок тексту залежно від умов

Припустимо, у нас стоїть завдання міняти зовнішній вигляд першої сторінки вузла залежно від того, звідки прийшов користувач. Для реалізації цього завдання використовується наступна конструкція:

  <! - # 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) на веб-сайті журналу "ОМ"

Боротьба з оформленням результатів роботи скриптів

Найбільша проблема зі скриптами полягає в тому, що якщо є велика кількість напрацьованого ПО - при зміні дизайну потрібно їх перенастроювання. Добре, якщо ПО зроблено правильно і редагування шаблонів відображення не стосується самої математики, однак і в таких випадках існують проблеми. Наприклад, на сторінці пошуку було б непогано крутити банери і рекламних мереж, але директиви 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 (як серед деяких користувачів зараз це модно) може бути виключений. На мій погляд цілком райдужно Smile happy
Все це перевірено і застосовується нашим адміністратором на 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 - сторінка кореневого індексу (змісту) і просто заглушка.