SSI сайт: HTML, XML, XSLT

image
Достопочтенное Ретро! Благо ты или зло?
Вздохом какого ветра к нам тебя занесло?
© Роберт Рождественский

Есть вещи, которые просто нравятся, их приятно держать в руках, они просты, они понятны. Время их расцвета ушло, но сами они не канули в лету, и к ним возвращаются снова и снова. Это касается не только предметов материального мира. Всегда найдётся программист, которому интересно писать на ассемблере, или прямо в машинных кодах, любитель простоты, минимализма, ретро. Попробуем вернуться к SSI, благо, это и проще ассемблера, и значительно моложе.

Технология SSI в своё время позволяла (и сейчас позволяет), делать сайты, в которых часть контента выносилась в отдельный файл, включаемый сервером «на лету». Обычно в отдельные файлы выносились: хидер, сайдбар, футер. Для обычного сайта с простой структурой этого хватало с лихвой. Выигрыш же состоял в том, что использовались простые, быстрые и надёжные решения, которые фактически без программирования реализовывали функционал CMS. Да и вообще, минимальный стек технологий — это любопытно.

Типичная страница сайта «на инклудах» выглядела так:

<html>
<head>
	<title>Название страницы</title>
</head>
<body>
	<div id="header"><!--#include virtual="/header.html" --></div>
	<div id="sidebar"><!--#include virtual="/sidebar.html" --></div>
	<div id="footer"><!--#include virtual="/footer.html" --></div>
</body>
</html>

Но работа с множеством страничек вызывала некоторое неудобство. Появились CMS, которые снимали одни вопросы, и ставили другие. Интересным решением было хранение базы данных в виде одного html файла, в котором страницы обозначались тегами Н1, Н2, Н3. При этом цифра тега говорила в вложенности страницы. Идею эту я наблюдал в CMSimple cmsimple.org, хотя возможно, кто-то это придумал и ранее. На базе этой идеи наверняка создано достаточно много CMS (да и сам пробовал, каюсь, чего уж там).

Главный недостаток такого решения — необходимость ворочать большой html файл. Есть конечно возможность сделать индекс, но по большому счёту это уже не так интересно. Одно дело редактировать десяток статей в одном файле, другое — тысячи. Примем как данность, что такой движок уместен для небольшого сайта, и не важно, СДЛ это, или сателлит — мы ведь обсуждаем технологию.

SSI и БД в HTML


Что за изгибы моды? Время сошло с ума:
Бабушкины комоды в блочные лезут дома!

Вспомнив о SSI, я задался вопросом: а нельзя ли подобный подход реализовать с помощью этой технологии? Сказано — сделано. Прямо в html файле можно создать переменную, значением которой и будет база данных сайта:

<!--#set var="db" value="Your html db">

Осталось научиться делать выборку из этой базы данных. Для этого пригодится переменная QUERY_STRING, которая хранит строку запроса к сайту. Настроив реврайты в htaccess и используя возможность условных выражений с поддержкой регулярных выражений (сорри за тавтологию), сервер сможет делать выборку нужной статьи из базы.

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

<!--#set var="db" file="db.html">

Такая опция позволила бы базу данных поместить в отдельный файл, соответственно код «движка» был бы более чистым и читаемым. Так что «лапша-код», это наше всё.

Для эксперимента решил сделать простой сайт, чтобы попробовать в деле предлагаемое решение. Темой выбран латино-американский танец Румба (исходники ниже). Первое впечатление — сайт работает быстро. Поскольку размер «движка» вместе с базой данных чуть больше 10 килобайт, это не удивительно. Запишем это в плюс. Плюс этот будет оставаться таковым до тех пор, пока размер БД не вырастет к примеру до мегабайта. При этом необходимость формирования меню вручную остановит от ваяния большого сайта гораздо раньше. Кроме того, копипастя что-либо в БД, необходимо не забывать заменять двойные кавычки на одинарные.

Ничего необычного и сложного. Вполне возможное решение. Важно, что странички благодаря реврайтам поисковые системы будут индексировать как отдельные, а не как одну целую. Этим конечно никого не удивишь, но упомянуть не помешает. Также в плюс запишем малую нагрузку на сервер. Не самый важный фактор для маленького сайта, но пусть будет. Если есть желание прикрутить дескрипшены — это также не проблема, достаточно ввести ещё один тег в состав разметки записей-статей.

Эти файлы нужно создать на сайте, чтобы увидеть пример в действии:

.htaccess
AddDefaultCharset utf-8

AddType text/html .html
AddHandler server-parsed .html
DirectoryIndex rumba.shtml?query=start

RewriteEngine on
RewriteRule ^([a-zA-Z0-9-]+)\.html$ rumba.shtml?query=$1


rumba.shtml
	<!--#set var="rumba_title" value="" -->
	<!--#set var="rumba_content" value="" -->
	<!--#set var="rumba_menu" value="" -->
	<!--#set var="rumba_error_title" value="Страница не найдена" -->
	<!--#set var="rumba_error_text" value="<h2>404</h2>Страница не найдена" -->	
	
	<!--#set var="rumba_menu" value="<ul>
		<li><a href='./'>Главная</a></li>
		<li><a href='./history.html'>История румбы</a></li>
		<li><a href='./cha-cha-cha.html'>Румба и Ча-ча-ча</a></li>
		<li><a href='./types.html'>Виды румбы</a></li>
		<li><a href='./emotion.html'>Эмоциональное содержание танца</a></li>
		<li><a href='./hits.html'>Хиты румбы</a></li>
	</ul>" -->

	<!--#set var="rumba_db" value="<articles>
		<article id='start'>
			<h2>Румба — парный кубинский танец африканского происхождения</h2>
			<text>
				<a href='https://ru.wikipedia.org/wiki/Румба'>Ру́мба</a> (исп. rumba) — у этого слова есть два различных значения:
				<ol>
				<li>Одно из них относится к направлению танцев и музыке, родившихся на Кубе. Наиболее известным из них является rumba Guaguanco. Так же популярными являются rumba Yambu и rumba Columbia. Каждый из этих видов румбы имеет свою стилистику музыки и танцевания, но в целом они очень близки.</li>
				<li>Другое значение появилось сравнительно недавно и относится к танцу из программы бальных танцев, который входит в программу соревнований. В этом значении румба является самым медленным из пяти танцев соревновательной латино-американской программы (остальные четыре — пасодобль, самба, ча-ча-ча и джайв). Танец и музыка румбы из соревновательной программы латино-американских танцев происходят от кубинских музыкальных стилей и танцев болеро и сон.</li>
				</ol>
			</text>
		</article>
		<article id='history'>
			<h2>История румбы</h2>
			<text>
				Румба появилась в Гаване в 19-м веке в комбинации с европейским контрдансом. Название «Rumba», возможно, происходит от названия танцевальных групп в 1807 году — «rumboso orquestra», хотя в Испании слово «rumbo» означает «путь» (в русском морской аналог — «румбы», то есть направление). Замечание - российская морская терминология аккуратно заимствована у Нидерландов, поэтому 'направление' очевидно не в русском, а в голландском не так.
			</text>
		</article>
		<article id='cha-cha-cha'>
			<h2>Румба и Ча-ча-ча</h2>
			<text>
				<p>Изначально не существовало четкого разделения танцев румба дансона и ча-ча-ча, из-за чего вся музыка, характерным образом обыгрывавшая первую долю (несколько ударов из затакта, приводящих к первой доле), подпадала под категорию румбы. Со временем танцы четко разделились. Музыка румбы дансона приобрела более медленный темп, стала сочиняться, как правило, в минорном ладу, и приобрела свое обыгрывание первой доли (ударные: восьмая, восьмая, восьмая, четверть — первая доля). Музыка ча-ча-ча стала быстрее, сочиняется как в мажорном, так и в минорном ладу и имеет собственное, очень выраженное и подчеркнутое обыгрывание первой доли (восьмая, восьмая, четверть — первая доля, так называемое — «ча-ча-ча» или «ча-ча-раз»).</p>
				<p>В связи с этим многие знаменитые в прошлом румбы с современной точки зрения следует считать скорее ча-ча-ча или даже вообще невозможно четко классифицировать как один из этих танцев. Так, например, знаменитая мелодия «Кукарача», считавшаяся румбой, не является ни ею, ни ча-ча-ча с современной точки зрения. «Guantanamera» более известна в варианте ча-ча-ча, а не румбы.</p>
				<p>Таким образом, румба обязана своим рождением религиозным ритуалам, развивалась она на базе ярко выраженных ритмов и хоровых голосов. Также можно сказать, что румбой в какой-то степени являются все те танцы, которые были созданы кубинцами. В настоящее время этот танец известен на всех континентах. Сначала он пришел в кабаре, а затем на телевидение. Существует бальная румба, но она существенно отличается от аутентичного кубинского варианта.</p>
			</text>
		</article>
		<article id='types'>
			<h2>Виды румбы</h2>
			<text>
				<p>В начале XIX века на Кубе существовало три варианта румбы, но широкую известность получила румба Гуагуанко (Guaguanco), танец, во время которого кавалер следует за дамой в поисках соприкосновения бедрами, а дама старается этого избежать. В этом танце дама как бы является объектом дерзкого ухаживания и старается сдержать страсть своего партнера. Возможно из-за этого за румбой и закрепилось название - «танец любви».</p>
				<p>Так-же на Кубе существовали различные виды румбы, которые танцевались на праздниках и просто сборищах людей на улице. Ярким представителем является Румба Миметика, в которой изображаются различные сцены из жизни простых людей (Papilote, Mama'buela, Gavilan)</p>
				<p>Коренную эволюцию румба претерпела, будучи вывезенной в США. Наравне с экспансивной, эротичной кубинской появилась Румба американская – с более сдержанными движениями и стилем. Именно этот вариант румбы и распространился по всему миру, завоевав сердца нескольких поколений танцоров и просто ценителей латиноамериканской культуры. Гуагуанко в основном состоит из ритмов африканских барабанов, которые накладываются на ритм клавэ (clave), представляющий смещенный акцент, известный как 3-2. Пение без музыкального сопровождение напоминает старинные испанские мелодии, которые накладываются на ритмы африканских барабанов. Исполняется гуагуанко одним или несколькими солистами, тему и слова придумывают по ходу исполнения песни. Структура ритма гуагуанко основывается чаще всего на ритме румбы сон (Rumba Son).</p>
			</text>
		</article>
		<article id='emotion'>
			<h2>Эмоциональное содержание танца</h2>
			<text>
				Среди всех бальных танцев румба характеризуется наиболее глубоким эмоциональным содержанием. В ходе своей эволюции румба приобрела многие черты, характерные для блюза. Существует расхожий штамп, что «румба — танец любви». Контраст ярко выраженного эротического характера танца и драматического содержания музыки создаёт неповторимый эстетический эффект. Вопреки всеобщему мнению о том, что движения в румбе — это танцевальное воплощение эротических чувств, румба изначально была свадебным танцем, а ее движения обозначали не что иное как семейные обязанности супругов. Немногочисленные современные румбы, написанные в мажоре, имеют свою изюминку, но не оставляют такого глубокого впечатления.
			</text>
		</article>
		<article id='hits'>
			<h2>Хиты написанные в ритме румбы</h2>
			<text>
				<ul>
				<li>La Media Vuelta — Эйди Горме (Eydie Gorme)</li>
				<li>Manana</li>
				<li>Cantinero de Cuba</li>
				<li>Reflection — Кристина Агилера</li>
				<li>Fairy tale — Тони Брэкстон</li>
				<li>Don't Know Why — Нора Джонс</li>
				<li>Falling Into You — Celine Dion</li>
				<li>When the blue bird sings</li>
				<li>Gipsy Kings — La Rumba-De Nicolas</li>
				<li>Gipsy Kings — Una Rumba Por Aqui</li>
				<li>Gipsy Kings — Rumba Del Stud</li>
				</ul>
			</text>
		</article>
	</articles>" -->

	<!--#if expr="$QUERY_STRING = /^query=([a-zA-Z0-9-]+)/" -->
		<!--#set var="rumba_query" value="$1" -->
		<!--#if expr="${rumba_db} = /<article id='${rumba_query}'>[\\s\\S]*?<h2>(.*)<\/h2>[\\s\\S]*?<text>([\\s\\S]*?)<\/text>[\\s\\S]*?<\/article>/" -->
			<!--#set var="rumba_title" value="$1" -->
			<!--#set var="rumba_r1" value="$1" -->
			<!--#set var="rumba_r2" value="$2" -->
			<!--#set var="rumba_content" value="${rumba_content}<h2>${rumba_r1}</h2>${rumba_r2}" -->
		<!--#else -->
			<!--#set var="rumba_title" value="${rumba_error_title}" -->
			<!--#set var="rumba_content" value="${rumba_error_text}" -->
		<!--#endif -->
	<!--#else -->
			<!--#set var="rumba_title" value="${rumba_error_title}" -->
			<!--#set var="rumba_content" value="${rumba_error_text}2" -->
	<!--#endif -->
	
<html>
<head>
	<title><!--#echo encoding="none" var="rumba_title" --></title>
	<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
	<link rel="stylesheet" href="twocolumn.css">
</head>

<body>
	<br/>
	<div id="header"><h1>Латино-американский танец Румба</h1></div>
	<div id="sidebar"><!--#echo encoding="none" var="rumba_menu" --></div>
	<div id="content"><!--#echo encoding="none" var="rumba_content" --></div>
</body>
</html>


twocolumn.css
body {
	margin: 0 auto;
	width: 640px;
	font:17px/20px Arial,Helvetica,sans-serif;
	overflow-y: scroll;
}
a {
	color: #777;
}
#header {
	padding: 10px;
	text-align: center;
}
#content {
	margin-left: 230px;
}
#content h2{
	color: #E6B03E;
}
#sidebar {
	padding: 10px;
	background: #B44E29;
	float: left;
	width: 180px;
}
#sidebar ul {
	padding: 0px;
}
#sidebar li {
	padding: 5px;
	list-style-type: none;
	list-style-position: inside;
}
#sidebar a {
	color: #fff;
	text-decoration: none;
}
#sidebar a:hover {
	color: #ccc;
	text-decoration: none;
}



SSI и БД в XML


Вещи нездешней формы, люстры, шкатулки, бра.
Медные пра-телефоны, чайники — тоже «пра»...

Минимализм языка SSI конечно не даст сильно развернуться. Но как же выкрутиться? Если немного прищуриться, глядя на html, он становится похож на xhtml, а если вообще закрыть глаза… Ну, вы уже поняли, что попробуем скрестить SSI с XML. Этот формат одним людям нравится, другие его люто ненавидят, но он «имеет место быть». Почему бы не попробовать?

Сделать из html-базы предыдущего примера xml файл — дело двух минут. Мы можем скормить его поисковой системе: Гуглу, Яндексу, Рамблеру, но не Мэйлу (предлагаю mail.ru начать индексировать xml файлы, кто за?). Поисковик воспримет файл как одну страничку и будет её учитывать именно так. С точки зрения предыдущего варианта с множеством страниц это скорее минус, но раз существует понятие Single-Page Application (SPA или Одностраничное приложение), значит эта xml страница может иметь право на жизнь*.

Однако xml файл как-то не очень похож на сайт, и показывать его в таком виде посетителю не резон. Вот тут и появляется необходимость подключения XSLT преобразования. Это обычный xsl файл, который также, как и предыдущий вариант движка, получает посредством QUERY_STRING с помощью SSI запрос и трансформирует xml файл. Результатом становится оформленная страничка, привычная посетителю. Хочу подчеркнуть, что XSLT-трансформация происходит на клиенте, т.е. её делает браузер, а не сервер.

Важно, что «одним движением руки» боковое меню со списком страниц генерируется автоматически. Кроме того, очень легко добавить в этот прототип движка разделы (категории) статей и теги (метки). Эта задача прямо-таки просится в xsl, и при желании можно нафантазировать много чего.

Поскольку сайт на XSLT версии SSI движка мы называем SPA, то с точки зрения SEO это важно. Это значит, что поисковая система видит одну страничку (ПС могут больше, так что я утрирую), и продвигать её необходимо как сайт-одностраничник. Это скорее минус, но с оговоркой. Xsl файл может при трансформации изменять контент. Это интересно. Допустим, с позиции SEO мы вынуждены добавить на сайт текст именно для ПС. Его можно задвинуть далеко в футер, а можно… просто не показывать посетителю. Насколько далеко в этом стоит заходить и стоит ли это делать вообще — это тема отдельного разговора, здесь же разговор только о технической возможности.

Теперь о трансформации на клиенте: аргумент переноса нагрузки с сервера на клиент я особо не рассматривал, кто-то это посчитает плюсом, кто-то скажет, что это экономия на спичках. Моё мнение — если возможно, лучше всё делать на сервере, но если нет, то тут выбор не велик. У браузеров к сожалению есть некоторые особенности в реализации XSLT (фичи или баги), которые надо знать и учитывать, разрабатывая xsl. Также, мне видится перспективным попробовать использовать не Апач, а Nginx, в этом случае есть вариант с использованием модуля ngx_http_xslt_module При этом сайт из SPA можно превратить в многостраничник, проводящий XSLT трансформацию на стороне сервера.

Эти файлы нужно создать на сайте, чтобы увидеть пример в действии:

.htaccess
AddDefaultCharset utf-8

AddType text/xml .xml
AddHandler server-parsed .xml
AddType text/xsl .xsl
AddHandler server-parsed .xsl
DirectoryIndex rumba.xml?query=start

RewriteEngine on
RewriteRule ^([a-zA-Z0-9-]+)\.html$ rumba.xml?query=$1 [L]


rumba.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"  href="rumba.xsl?<!--#echo encoding="none" var="QUERY_STRING" -->"?>
<html>
<head>
	<title>Латино-американский танец Румба</title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
	<meta name="Description" content="Описание сайта"/>
</head>
<body>
	<h1>Латино-американский танец Румба</h1>
	<article id='start'>
		<h2>Румба — парный кубинский танец африканского происхождения</h2>
		<text>
			<a title='Оригинал статьи на Википедии' rel='canonical' href='https://ru.wikipedia.org/wiki/Румба'>Ру́мба</a> (исп. rumba) — у этого слова есть два различных значения:
			<ol>
			<li>Одно из них относится к направлению танцев и музыке, родившихся на Кубе. Наиболее известным из них является rumba Guaguanco. Так же популярными являются rumba Yambu и rumba Columbia. Каждый из этих видов румбы имеет свою стилистику музыки и танцевания, но в целом они очень близки.</li>
			<li>Другое значение появилось сравнительно недавно и относится к танцу из программы бальных танцев, который входит в программу соревнований. В этом значении румба является самым медленным из пяти танцев соревновательной латино-американской программы (остальные четыре — пасодобль, самба, ча-ча-ча и джайв). Танец и музыка румбы из соревновательной программы латино-американских танцев происходят от кубинских музыкальных стилей и танцев болеро и сон.</li>
			</ol>
		</text>
	</article>
	<article id='history'>
		<h2>История румбы</h2>
		<text>
			Румба появилась в Гаване в 19-м веке в комбинации с европейским контрдансом. Название «Rumba», возможно, происходит от названия танцевальных групп в 1807 году — «rumboso orquestra», хотя в Испании слово «rumbo» означает «путь» (в русском морской аналог — «румбы», то есть направление). Замечание - российская морская терминология аккуратно заимствована у Нидерландов, поэтому 'направление' очевидно не в русском, а в голландском не так.
		</text>
	</article>
	<article id='cha-cha-cha'>
		<h2>Румба и Ча-ча-ча</h2>
		<text>
			<p>Изначально не существовало четкого разделения танцев румба дансона и ча-ча-ча, из-за чего вся музыка, характерным образом обыгрывавшая первую долю (несколько ударов из затакта, приводящих к первой доле), подпадала под категорию румбы. Со временем танцы четко разделились. Музыка румбы дансона приобрела более медленный темп, стала сочиняться, как правило, в минорном ладу, и приобрела свое обыгрывание первой доли (ударные: восьмая, восьмая, восьмая, четверть — первая доля). Музыка ча-ча-ча стала быстрее, сочиняется как в мажорном, так и в минорном ладу и имеет собственное, очень выраженное и подчеркнутое обыгрывание первой доли (восьмая, восьмая, четверть — первая доля, так называемое — «ча-ча-ча» или «ча-ча-раз»).</p>
			<p>В связи с этим многие знаменитые в прошлом румбы с современной точки зрения следует считать скорее ча-ча-ча или даже вообще невозможно четко классифицировать как один из этих танцев. Так, например, знаменитая мелодия «Кукарача», считавшаяся румбой, не является ни ею, ни ча-ча-ча с современной точки зрения. «Guantanamera» более известна в варианте ча-ча-ча, а не румбы.</p>
			<p>Таким образом, румба обязана своим рождением религиозным ритуалам, развивалась она на базе ярко выраженных ритмов и хоровых голосов. Также можно сказать, что румбой в какой-то степени являются все те танцы, которые были созданы кубинцами. В настоящее время этот танец известен на всех континентах. Сначала он пришел в кабаре, а затем на телевидение. Существует бальная румба, но она существенно отличается от аутентичного кубинского варианта.</p>
		</text>
	</article>
	<article id='types'>
		<h2>Виды румбы</h2>
		<text>
			<p>В начале XIX века на Кубе существовало три варианта румбы, но широкую известность получила румба Гуагуанко (Guaguanco), танец, во время которого кавалер следует за дамой в поисках соприкосновения бедрами, а дама старается этого избежать. В этом танце дама как бы является объектом дерзкого ухаживания и старается сдержать страсть своего партнера. Возможно из-за этого за румбой и закрепилось название - «танец любви».</p>
			<p>Так-же на Кубе существовали различные виды румбы, которые танцевались на праздниках и просто сборищах людей на улице. Ярким представителем является Румба Миметика, в которой изображаются различные сцены из жизни простых людей (Papilote, Mama'buela, Gavilan)</p>
			<p>Коренную эволюцию румба претерпела, будучи вывезенной в США. Наравне с экспансивной, эротичной кубинской появилась Румба американская – с более сдержанными движениями и стилем. Именно этот вариант румбы и распространился по всему миру, завоевав сердца нескольких поколений танцоров и просто ценителей латиноамериканской культуры. Гуагуанко в основном состоит из ритмов африканских барабанов, которые накладываются на ритм клавэ (clave), представляющий смещенный акцент, известный как 3-2. Пение без музыкального сопровождение напоминает старинные испанские мелодии, которые накладываются на ритмы африканских барабанов. Исполняется гуагуанко одним или несколькими солистами, тему и слова придумывают по ходу исполнения песни. Структура ритма гуагуанко основывается чаще всего на ритме румбы сон (Rumba Son).</p>
		</text>
	</article>
	<article id='emotion'>
		<h2>Эмоциональное содержание танца</h2>
		<text>
			Среди всех бальных танцев румба характеризуется наиболее глубоким эмоциональным содержанием. В ходе своей эволюции румба приобрела многие черты, характерные для блюза. Существует расхожий штамп, что «румба — танец любви». Контраст ярко выраженного эротического характера танца и драматического содержания музыки создаёт неповторимый эстетический эффект. Вопреки всеобщему мнению о том, что движения в румбе — это танцевальное воплощение эротических чувств, румба изначально была свадебным танцем, а ее движения обозначали не что иное как семейные обязанности супругов. Немногочисленные современные румбы, написанные в мажоре, имеют свою изюминку, но не оставляют такого глубокого впечатления.
		</text>
	</article>
	<article id='hits'>
		<h2>Хиты написанные в ритме румбы</h2>
		<text>
			<ul>
			<li>La Media Vuelta — Эйди Горме (Eydie Gorme)</li>
			<li>Manana</li>
			<li>Cantinero de Cuba</li>
			<li>Reflection — Кристина Агилера</li>
			<li>Fairy tale — Тони Брэкстон</li>
			<li>Don't Know Why — Нора Джонс</li>
			<li>Falling Into You — Celine Dion</li>
			<li>When the blue bird sings</li>
			<li>Gipsy Kings — La Rumba-De Nicolas</li>
			<li>Gipsy Kings — Una Rumba Por Aqui</li>
			<li>Gipsy Kings — Rumba Del Stud</li>
			</ul>
		</text>
	</article>
</body>
</html>


rumba.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!--#if expr="$QUERY_STRING = /^query=([a-zA-Z0-9-]+)/" -->
	<!--#set var="rumba_query" value="$1" -->
<!--#else -->
	<!--#set var="rumba_query" value="error" -->
<!--#endif -->
	
<xsl:param name="query"><!--#echo encoding="none" var="rumba_query" --></xsl:param>

<xsl:template match="/">
	<html>
	<head>
		<xsl:apply-templates select="/html/head"/>
		<link rel="stylesheet" href="twocolumn.css"/>
	</head>
	<body>
		<div id="header">
			<xsl:apply-templates select="/html/body" mode="header"/>
		</div>
		<div id="sidebar">
			<ul>
				<xsl:apply-templates select="/html/body/article"/>
			</ul>
		</div>
		<div id="content">
			<xsl:choose> 
				<xsl:when test="count(/html/body/article[@id = $query]) = '0'"> 
					<xsl:apply-templates select="/html/body" mode="error"/>
				</xsl:when> 
				<xsl:otherwise> 
					<xsl:apply-templates select="/html/body" mode="page"/>
				</xsl:otherwise> 
			</xsl:choose> 
		</div>
	</body>
	</html>
</xsl:template>

<xsl:template match="/html/head">
	<title><xsl:value-of select="/html/body/article[@id = $query]/h2"/></title>
	<xsl:copy-of select="meta"/>
</xsl:template>

<xsl:template match="body" mode="header">
		<xsl:copy-of select="h1"/>
</xsl:template>

<xsl:template match="/html/body/article">
     <xsl:choose> 
          <xsl:when test="@id = 'start'"> 
               <li><a href="./">Главная</a></li>
          </xsl:when> 
          <xsl:otherwise> 
               <li><a href="{@id}.html" rel="nofollow"><xsl:value-of select="h2"/></a></li>
          </xsl:otherwise> 
     </xsl:choose> 
</xsl:template>

<xsl:template match="/html/body" mode="page">
	<xsl:for-each select="/html/body/article[@id = $query]">
		<xsl:copy-of select="h2"/>
		<div>
		   <xsl:copy-of select="text"/> 
		</div>
	 </xsl:for-each> 
</xsl:template>

<xsl:template match="/html/body" mode="error">
	<h2>Ошибка 404</h2>
	Страница не найдена
</xsl:template>

</xsl:stylesheet>


twocolumn.css
body {
	margin: 0 auto;
	width: 640px;
	font:17px/20px Arial,Helvetica,sans-serif;
	overflow-y: scroll;
}
a {
	color: #777;
}
#header {
	padding: 10px;
	text-align: center;
}
#content {
	margin-left: 230px;
}
#content h2{
	color: #E6B03E;
}
#sidebar {
	padding: 10px;
	background: #B44E29;
	float: left;
	width: 180px;
}
#sidebar ul {
	padding: 0px;
}
#sidebar li {
	padding: 5px;
	list-style-type: none;
	list-style-position: inside;
}
#sidebar a {
	color: #fff;
	text-decoration: none;
}
#sidebar a:hover {
	color: #ccc;
	text-decoration: none;
}


Субъективный вывод


Кто-нибудь — между прочим — скажет о наших годах:
«Всё тогда было проще… Господи, нам бы так!..»

Применения описанных решений на SSI однозначно не подходят для широкого применения. Но сугубо с технической точки зрения они могут быть применены, и по сути это очень простые и весьма надёжные решения, о которых не лишним будет помнить. Альтернативой им служат современные CMS и SPA, использующие JavaScript, PHP и пр. которые скорей всего и будут решать поставленные по созданию сайта задачи.

Кстати говоря, вполне можно реализовать xslt трансформацию и в РНР и в JavaScript (не сомневаюсь, что и в других языках тоже), но я рассматривал решение с SSI с минимальным стеком технологий, этакий аскетический и минималистический вариант, когда есть сервер, или даже шаред хостинг и… всё. Я не рассмотрел версию с JS, хранящим данные без всякого Ajax: этот вариант не только может существовать, но и когда-то был использован мной в начале двухтысячных, но это по сути очень близко к современному SPA с каким-нибудь AngularJS на борту, и думаю, статей на эту тему и так хватает.

Если нет желания собирать сайты из приведённых примеров, вот ссылки на SSI HTML и SSI XML.

* Термины SPA и одностраничник мной в некоторой степени приравнены, хотя это конечно разные вещи.
Поделиться публикацией
Похожие публикации
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 10
  • 0
    А может просто сделать одностраничный сайт и не мучать никого?
    • 0
      Полагаю, вы подразумеваете одностраничный сайт с внутренними ссылками. Можно сделать и так. Даже правильно сказать — именно так обычно и делается. Вполне распространённое решение, без сложностей, без заморочек. Если сравнивать с вариантом SSI-HTML, то тут главная разница в наличии страниц. Если не нужна многостраничность, то SSI-HTML вариант опускаем и забываем. Сравнивая же с SSI-XML, мы можем увидеть, что в конечном итоге и одностраничник и xml сразу отдают весь контент поисковому роботу. Т.е. если не считать отсутствия индексации в mail.ru, всё в принципе похоже.

      При таком раскладе, если сайт должен быть совсем простой, обычный, то предпочтение и надо отдавать классическому html одностраничнику с внутренними ссылками — это и просто, и надёжно. Но если вы хотите реализовать разделы-подразделы, теги, может быть авторов, или ещё что-то в этом духе, то xml с xslt преобразованием могут пригодиться. Ну и момент с добавлением-удалением контента при xslt-трансформации тоже помнить будет не лишним (с точки зрения SEO).

      Важно отметить, что то же самое при желании можно сделать с помощью JS. При этом конечно, количество фреймворков и величина сообщества JavaScript очень велики. Этот подход сейчас активно развивается. Так что я точно не против JS, мне просто интересно сравнить разные подходы. Например, одного и того же изменения страницы мы можем добиться и с применением JS, и с применением XSLT. Тогда вопрос — если результат одинаковый, то в чём собственно говоря, разница?

      Разница в распространённости языка, в развитии его поддержки. Но если отодвинуть все холиварные сравнения, то остаётся только одно весомое противоречие подходов: декларативный у XSLT и императивный у JS (хотя можно на нём и функционально программировать). Императивный распространён, его понимают все, а декларативный редок. Но забывать его всё-же не стоит.

      P.S. Не хотелось бы разжечь тут холивара
    • 0
      Как-то расточительно выдавать по запросу всю огромную страницу.

      Вообще, в SSI вроде как можно делать сделать цикл через рекурсивные инклуды.

      Ещё удобно втыкать куски страниц через cgi-инклуды. Чтобы не писать на ЦГИ всю страницу.
      • 0
        Цикл упрётся в LimitInternalRecursion, т.е. количество рекурсий ограниченное, и оно маленькое, дефолтно — 10.
        Как-то расточительно выдавать по запросу всю огромную страницу.
        Согласен, если сайт большой. Но, если ваш xml файл будет 100 килобайт, то… вполне приемлемо. Для сравнения сейчас посмотрел размер html кода главной страницы хабра — 134 килобайта. Я думаю, это как-раз те размеры, на которые можно ориентироваться. Т.е. десяток средних статей, или два десятка маленьких.
      • +1
        А чего это у вас пример в начале с php-инклюдами, а не SSI? Это нечестно
        • 0
          Тут нет РНР инклюдов. Если не сложно, процитируйте строку из кода.
          • +1
            Старый добрый include virtual (ибо Apache): <!--#include virtual="/footer.html" -->

            Этак и всякие счетчики с гостевыми книгами подключали (это были адские CGI-скрипты на Perl), а у вас какой-то целиком интерпретируемый софткор :)
            • 0
              Согласен, вариант впихивания сайта в SSI инструкцию обычным никак не назовёшь. Но я удивлён, что такой вариант никто не использовал. Для эпохи активного использования инклюдов это было бы вполне актуальное решение — как минимум, для сателлитов, ну и для всяких сайтов-визиток и проч.
            • 0
              <?php include («header.php»);?>

              А это?
              • 0
                Первый вариант (кода в статье) — классический в плане использования SSI. Простой вариант с
                <!--#include virtual="/header.html" -->
                
                , более продвинутый с
                <?php include («header.php»);?>
                
                . Он дан для примера. Чтобы не было сомнений, исправил на вариант с включением статического контента.
                Спасибо за внимательность!

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое