Динамические страницы через SSI и PHP
Posted on 14 Март 2013 in Веб разработка by wakh
Во всех манулах по SSI рекомендуется создать файлы заголовка, футера и т.д. а потом инклудить (включать) из в каждую страницу. Мало того что это муторно и некрасиво, так ещё и создаёт дополнительные проблемы при при серьёзных изменениях на сайте.
Логичнее было бы автоматически вставлять шаблон во все страницы сайта с определённым (дабы не портить текстовые и прочие не HTML страницы на сайте) расширением. Я расскажу вам как это сделать.
Способ одинаково работает как на X-SSI так и на PHP. Он дико прост и мне странно, что я не смог нагуглить готовое решение, возможно плохо искал, но вместо того чтобы тратить время на поиск, я сделал всё сам.
С помощью него очень удобно делать сайты на шаблонах (не для CMS), достаточно порезать шаблон на footer, header и body, расставить переменные мета и, по необходимости, доработать логику включения дополнительных элементов. При смене шаблона контентные файлы не придётся трогать вообще.
Простейщее использование шаблонов на SSI и PHP
Я последовательно приведу листинги необходимых файлов с пояснениями.
Файлы шаблонов:
footer.html
Любой HTML фрагмент - подвал сайта
header.html
Любой HTML фрагмент - шапка сайта
Файл(ы) контента
index.html
Любой HTML фрагмент - чистый контент, без инклюдов и т.п.
Обработчики
engine.html - вариант на SSI
<!--Define template names and physical page ext--> <!--#set var="ext" value=".html"--> <!--#set var="header" value="config${ext}"--> <!--#set var="header" value="header${ext}"--> <!--#set var="footer" value="footer${ext}"--> <!--#set var="mypage" value="${QUERY_STRING}${ext}"--> <!--including templates and page--> <!--#include virtual="$config" --> <!--#include virtual="$header" --> <!--#include virtual="$mypage" --> <!--#include virtual="$footer" -->
engine.php - вариант на PHP
<? #Define template names and physical page ext $ext=".html"; $header="config".$ext; $header="header".$ext; $footer="footer".$ext; $mypage = $_SERVER['QUERY_STRING'].$ext; #including templates and page include ($config); include ($header); include ($mypage); include ($footer); ?>
В обоих обработчиках важно обратить внимание на переменную ext. Как вы догадались, это расширение файлов контента, физических файлов на сервере. В ссылках на сайте мы будем использовать другое расширение. Конечно вы можете использовать свои расширения, важно лишь то чтобы расширение физических файлов и ссылок сайта не совпадали. Варианты: htm, html, shtml, phtml, php. Вы можете использовать любые другие, но внесите изменения в конфигурацию сервера и настройку обработчика. Расщирение файла обработчика может быть любым, но оно не должно совпадать с расщирением ссылок на сайте. Во второй версии оно может совпадать, но зачем?
Конфигурация сервера (первая версия)
.htaccess
Options -Indexes DirectoryIndex index.phtml AddHandler server-parsed .html .htm #AddHandler application/x-httpd-php .php .html .htm RewriteEngine On RewriteBase / #uncoment for site on SSI #RewriteRule ^$ engine.html?index [QSA,L] #RewriteRule ^(.*)/$ engine.html?$1/index [QSA,L] #RewriteRule ^(.*).(shtml)$ engine.html?$1 [QSA,L] #uncoment for site on PHP RewriteRule ^$ engine.php?index [QSA,L] RewriteRule ^(.*)/$ engine.php?$1/index [QSA,L] RewriteRule ^(.*).(phtml)$ engine.php?$1 [QSA,L]
Вторая версия (фрагмент) - с обработчиком ошибок на уровне .htaccess. При использовании PHP, можно использовать первую версию и ошибки ловить скриптами, это более гибко.
# Don't loop. RewriteCond %{ENV:REDIRECT_FINISH} !^$ RewriteRule ^ - [L] RewriteRule ^$ _engine.html?index [E=FINISH:1,QSA,L,S=5] RewriteCond %{REQUEST_URI} ^(.*)/$ RewriteCond %{REQUEST_FILENAME} !-d [OR] RewriteCond %{REQUEST_FILENAME}/index.html !-f RewriteRule ^ _engine.html?404 [E=FINISH:1,QSA,L,S=4] RewriteRule ^(.*)\/$ _engine.html?$1/index [E=FINISH:1,QSA,L,S=3] RewriteRule ^(.*)\.shtml$ $1.html RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ _engine.html?404 [E=FINISH:1,QSA,L,S] RewriteRule ^(.*)\.html$ _engine.html?$1 [E=FINISH:1,QSA,L]
Это самое интересное, поясню построчно (для первой версии):
Options -Indexes - отключаем возможность просматривать листинг каталога
DirectoryIndex index.phtml - важный параметр, расширение должно соответствовать расширениям в ссылках вашего сайта, не физическим файлам.
AddHandler server-parsed .html .htm - только для SSI включаем обработку файлов .html .htm, как .shtml, можете добавить свои.
#AddHandler application/x-httpd-php .php .html .htm - раскомментируйте, если вы используете PHP версию и у вас "не работает", хотя обычно серверы по умолчанию на обработку этих файлов.
RewriteEngine On - активируем модуль для преобразования средствами Апача
RewriteBase / - необязательная строка, зависит от настроек сервера, необходима, например, для доменов 3го уровня (поддоменов).
Далее следуют группы правил преобразования для SSI и PHP, конечно оба блока вам не нужны, поэтому можно оставить только нужный, а другой удалить или закомментировать (символом # в начале строки). Обратите внимание, в примере закомментированна SSI версия.
Правил по 3, они действуют на корень сайта, каталоги и файлы с указанным (shtml или phtml) расширением соответственно. Если в ссылках на сайте другое расширение, измените его тут и в директиве DirectoryIndex.
В новой версии добавлены обрабочик ошибки 404 и защита от зацикливания (первые 2 директивы).
Для проверки работоспособности создайте файлы с указанными именами, скопирйте в них содержимое, загрузите на сервер. Вы увидите результат config.html, footer.html, header.html и index.html как единой HTML страницы.
config.html
В оригинальном посте не был упомянут config.html. В этом файле я храню (или подгружаю из CSV) метаданные, а так же укороченные версии переменных окружения. В версии на PHP здесь также размещается весь функционал.
Накладные расходы
Если вы осуществляете переезд сайта с инклюдов встроенных в страницы, как былов моём случае, то помимо переименовки файлов, необходимо внести изменение в логику. Например, переменная $DOCUMENT_NAME перестанет отображать текущую страницу, однако она легко заменяется переменной $mypage из обработчика.
Так же мне пришлось изменить расширения в инклудах внутри шаблона - привести в соответствии с физическими файлами.
Ну и конечно, вычистить все инклуды в отдельных страницах, оставив чистый контент.
Используйте свои шаблоны шапки и подвала сайта, и добавляйте функционал в обраточик. Например вывод дополнительных блоков типа сайдбара, можно также вынести в engine.*.
Удачи!