Да, мощные готовые программные пакеты, использующие для хранения информации серверные базы данных — это хорошо. Заплатил соответствующую сумму денег — и живи спокойно. Но довольно часто этот вариант обзаведения «движком» сайта не подходит. Во-первых, конечно, стоимость: заплатить даже тысячу долларов для открытия персонального или небольшого контент-проекта могут далеко не все (при этом большинство «движков» стоят гораздо больше 1000$). Во-вторых — гибкость: коммерческие «движки» основываются на закрытых технологиях, то есть самостоятельно поменять что-то в их «внутренностях» никто не позволит, и за самыми простыми дополнениями и исправлениями придется обращаться к разработчику «движка» — естественно, снова платя деньги. В-третьих — требования к системным ресурсам: некоторые проекты, которые должны обновляться «движком», могут размещаться на тарифных планах хостинга, не предусматривающих поддержку PHP и MySQL.
В общем, вы поняли, к чему я клоню :-). В конце 1999 года мне понадобился «движок» для собственных веб-проектов: обновлять существовавший тогда около года E-notes.ru (в то время — Pro.Net.ru) вручную надоело просто смертельно, а впереди маячило открытие при моем участии еще пары сайтов — было очевидно, что при такой организации работы по обновлению веб-серверов мне придется оставить все остальные занятия и посвятить всю свою жизнь ковырянию в коде страниц.
Сторонний «движок» я использовать не мог — мне нужен был инструмент, который я имел бы право ставить на любой сайт по своему усмотрению. Коммерческие же продукты нужно лицензировать для каждого сайта отдельно — и, как я уже говорил — за немалые деньги. В результате я решил написать собственный «движок».
Итак, как в начале любого проекта — постановка задачи.
1. «Движок» должен работать на любом хостинге — и выделенном сервере за $200 в месяц, и на пятидолларовом тарифе виртуального сервера начального уровня. Это исключает применение в качестве хранилища информации базы данных MySQL. В качестве базы данных подойдут текстовые файлы формата «с разделением полей», который, кстати, раньше широко использовался в небольших системах управления базами данных.
2. Делать веб-интерфейс для загрузки материалов на сервер не нужно. Во-первых, слишком много работы (больше, чем собственно программирование процедуры генерации страниц) — нужно предусмотреть многочисленные варианты «защиты от дурака» (то есть обработку неправильных действий пользователя) а также отслеживать ошибки сервера, «железа» на стороне пользователя, сетевых протоколов; во-вторых, этот интерфейс фактически не нужен: обновлять сайты будет человек, хорошо знакомый с FTP и предпочитающий его веб-интерфейсам хотя бы потому, что FTP-клиент позволяет отслеживать процесс загрузки файлов на сервер, тогда как в веб-интерфейсе такое практически невозможно. В то же время, нужно попытаться максимально уменьшить число файлов, переписываемых на сервер при каждом обновлении сайта.
3. Материалы сайта должны храниться в виде, как можно более приближенном к обычному тексту, то есть с минимальным включением тегов HTML: текст материалов должен форматироваться в HTML «движком», а не автором. Чем меньше приходится набирать тегов HTML — тем быстрее будет закончена работа над текстом. Кроме того, это позволит в будущем легко переносить сайт на другие платформы, в том числе и на более «продвинутые» системы управления сайтами.
4. Веб-страницы сайта должны генерироваться непосредственно на диске сервера, а не «на лету», чтобы адреса страниц всегда были понятны пользователям: www.site.ru/razdel/material.html, а не длиннющий URL с кучей параметров. Конечно, таких малопонятных адресов вроде www.site.ru/razdel/page?p=18&id=7362 в некоторых случаях не избежать — например, в форуме и гостевой книге, — однако в этих разделах это не особенно мешает. Главное, чтобы непосредственно материалы сайта (новости, заметки, статьи, обзоры) имели понятные адреса, так как именно на эти страницы будут больше всего ставить ссылок и именно их будут рекомендовать в конференциях и форумах.
Учитывая то, что «движок» должен работать на любых тарифных планах хостинга и он должен обрабатывать текстовые файлы, то для решения поставленной задачи идеально подходит старый добрый Perl. В нем очень удобно реализованы функции разбора текста с разделителями полей (функция split), поиска/замены с помощью регулярных выражений, чтения/записи файлов и, в отличие от PHP, он разрешен в любых тарифах хостинга (кроме разве что тех, на которых запрещен CGI, но тут уж никакой «движок» не будет работать).
Каждый раздел сайта описывается в отдельном текстовом файле, имеющем такой вид:
Каждая строка описывает отдельный материал, параметры описания разделены символом «|». Параметры идут в таком порядке:
1) Идентфикатор записи (он не используется — просто в базах данных так заведено: каждая запись имеет свой уникальный идентификатор); 2) Имя файла, из которого берется текст материала (для «Обзоров» он совпадает с идентификатором); 3) Дата публикации материала; 4) Краткое описание материала (имеется не всегда); 5) URL сайта, которому посвящен материал; 6) Числовой параметр (используется для внутренних целей ;)).
Как видите, редактировать файл с описанием раздела довольно удобно и в обычном текстовом редакторе. Для добавления нового материала нужно всего лишь вставить новую строку в начало файла и ввести значения требуемых параметров, разделяя их символами «|».
Структура файлов для других разделов примерно такая же; кое-где только отличается назначение некоторых параметров.
Внимательный читатель спросит: «А почему среди параметров материала нет параметра «Название»? Спокойствие, сейчас оно появится :-).
Второй параметр в каждой строке с описанием материала — имя файла, из которого берется текст материала. Это — обычный текстовый файл с некоторыми вкраплениями HTML:
Конечно, полностью без тегов HTML здесь не обойдешься: нужно, в конце концов, как-то выделять ссылки, отдельные фрагменты текста (например, тегом ) а также описывать иллюстрации. Однако в остальном текст пишется обычным образом: первая строка — заголовок материала (он затем используется в теге
Отдельная песня — форматирование специальных символов и некоторых знаков препинания. Как известно, использовать для набора текста стандартные клавиатурные символы, например, «дефис» вместо «длинного тире», а вместо пары кавычек «» — знаки дюйма "" — нарушение правил верстки. Поэтому при наборе текста нужно вместо дефиса писать — (код «длинного тире»), а вместо знаков дюйма — коды „ “, обозначающие на левые и правые «лапки» («»). При этом в версии для печати кавычки меняются на «елочки» (« » — («»), так как они более удобны для чтения текста с бумаги, чем «лапки», предназначенные для вывода текста на экран.
Если писать все эти коды прямо при наборе текста, то это, во-первых, очень утомительно, во-вторых — страдает читабельность текста для автора. Для решения этой проблемы применяется такой прием: автор пишет текст как обычно — с дефисами вместо длинного тире и знаками дюйма вместо кавычек, а при генерации веб-страниц «движок» заменяет эти символы на соответствующие коды.
Также при написании материалов может использоваться специальное выделение абзацев, содержащих важные замечания и комментарии, которое может быть достаточно сложным — например, с использованием таблиц и графики. Абзацы, которые нужно выделить таким образом, обрамляются комментариями <--special--><--/special-->, а «движок» заменяет их «нормальными» HTML-тегами позже, также в процессе генерации веб-страниц.
Для добавления нового материала на сайт нужно переписать на сервер следующие файлы:
1) текстовый файл раздела, например, reviews.txt (куда было добавлено описание нового материала); 2) текстовый файл раздела «Новости», с аналогичным добавлением; 3) файл с текстом нового материала; 4) файлы с картинками-иллюстрациями (если они имеются).
Еще раз обращаю внимание — при обновлении содержания и структуры сайта не приходится иметь дело с HTML (за исключением некоторой разметки файла с текстом материалов). Все изменения вносятся только в текстовые файлы, что обеспечивает гораздо меньшие затраты как на редактирование файлов, так и тестирование результата. Ведь при редактировании HTML нужно найти соответствующий фрагмент кода, отредактировать его, тратя время на написание тегов, а затем проверить, не были ли допущены ошибки (например, забыли закрыть тег).
Дизайн сайта зафиксирован в отдельном файле-шаблоне. Он мог бы быть HTML-страницей, но я сделал его как простейший скрипт на Perl. Дело в том, что статическими страницами часто обойтись нельзя — нужно, например, чтобы панель навигации меняла свой вид в зависимости от текущего раздела (скажем, ссылка на этот раздел не подчеркивалась) или чтобы в страницу вставлялся блок новостей.
После того, как файлы записаны на сервер, я открываю в браузере страницу, имеющую адрес вида /cgi-bin/update.cgi. Это — CGI-скрипт на Perl, который осуществляет непосредственно генерацию страниц. Он «пробегается» по файлам разделов, читает информацию из текстовых файлов с материалами, форматирует текст в HTML (как было описано выше), «присобачивает» дизайн, взятый из шаблона, создает на диске сервера в каталогах, соответствующих каждому разделу, HTML-файлы с материалами сайта, а также файлы их «версий для печати». Кроме того, для каждого раздела создается файл index.html со списком материалов, а также, если нужно, файл со списком из 10 последних материалов для вставки в главную страницу. Для раздела «Новости», помимо индексного файла, формируются файлы со списками из четырех последних новостей для главной страницы и трех — для всех внутренних.
Вот, собственно, и все. Этот «движок», написанный за два вечера, хотя и прост, но довольно эффективно обеспечивает работу небольшого контент-проекта, обновляющегося несколько раз в неделю или даже несколько раз в день. При более частом обновлении, когда материалы поступают на сайт несколько раз в час, нужен более мощный «движок» — например, тот же TreeGraph, о котором было рассказано в первой части этой заметки.