Поиск по сайту — статичный контент (Perl)


Оглавление (нажмите, чтобы открыть):

Поиск по сайту с постраничным выводом результатов

Здравствуйте.
при создании поиска столкнулся с некоторой проблемой
При использовании поиска(скрипт указан ниже)
показываются результаты только 1 страницы
при переходе по навигации на страницу 2(или любую другую)
выдается информация без учёта переменной $search
то есть просто все записи из таблицы items.

посоветуйте пожалуйста, как можно выйти из этой ситуации
или что почитать, или куда обратить внимание
Буду благодарен за любую информацию.

Статичный и динамичный контент. Новости на сайте

Основной контент стандартной комплектации CMS Joomla, который может быть размещён на сайте — это статьи. Статьи условно можно разделить на статичные и динамичные. Так же, их называют статичный контент и динамичный контент. Эти термины на практике почти не используются, их употребляют только в теории.

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

Для создания разделов и категорий вы должны перейти в: «Материалы» > «Менеджер разделов» или «Менеджер категорий».

Для создания материала в: «Материалы» > «Менеджер материалов» необходимо нажать иконку «Создать».

Новости на сайте

Для создания новостного раздела на сайте вам потребуется создать новый раздел, затем в случае необходимости создать категории в этом разделе. Категории могут понадобиться в случае, когда требуется деление новостей по категориям, например корпоративные новости, мировые новости и др. Для статей раздела новостей нам потребует использовать так называемые динамические статьи. Рассмотрим пошагово инструкцию по созданию новостей на сайте.

Создание раздела новости

Первое, что нужно это создать раздел «новости», для этого идем в «материалы» > «менеджер разделов»и жмем кнопку «создать». При создании раздела вам необходимо заполнить следующие поля:

  • Заголовок: Новости (название раздела).
  • Псевдоним: название, которое будет использоваться в адресе ссылки на раздел.
  • Опубликовано: параметр, который отвечает за отображение на сайте. Если установлен параметр «нет» значит, раздел будет скрыт.
  • Порядок показа: новые разделы, по умолчанию, располагаются последними. Порядок может быть изменён после сохранения раздела.
  • Доступ: в случае, когда необходимо ограничить доступ пользователей к данному разделу в этом пункте можно указать какой группе пользователей будет доступен данный раздел.
  • Изображение: изображение, характеризующее данный раздел.
  • Позиция картинки: позиция для отображения картинки.
  • Описание: текст с описанием раздела.

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

Создание категории раздела новости

Для создания категорий раздела «новости» нам нужно выбрать в: «материалы» > «менеджер категорий»и нажать кнопку «создать». При создании категории вам необходимо заполнить почти такие же поля как при создании раздела, только дополнительно нужно будет выбрать раздел к которому относиться категория. Подробно по каждому полю:

  • Заголовок: Корпоративные новости (название категории новостей).
  • Псевдоним: название, которое будет использоваться в адресе ссылки на категорию.
  • Опубликовано: параметр, который отвечает за отображение на сайте. Если установлен параметр «нет» значит, категория будет скрыта.
  • Раздел: здесь из выпадающего списка необходимо выбрать раздел к которому относится данная категория (в нашем случае раздел новости).
  • Порядок показа: Новые категории по умолчанию располагаются последними. Порядок может быть изменён после сохранения категории.
  • Доступ: в случае, когда необходимо ограничить доступ пользователей к данной категории в этом пункте можно указать какой группе пользователей будет доступна данная категория.
  • Изображение: изображение, характеризующее данную категорию.
  • Позиция картинки: позиция для отображения картинки.
  • Описание: текст с описанием категории.

После того как все поля заполнены, сохраняем и переходим к созданию следующей необходимой категории из раздела новости, по той же схеме.
Когда создан раздел и категории раздела, можно перейти к материалам – статьям.
Как мы уже разобрали, для новостей мы будем использовать динамичный контент, т.е. при создании материала, будем указывать к какому разделу и категории относиться материал.

Вывод новостей в меню

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

Стандартная страница поиска

Компонент служит для создания страницы поиска. Компонент можно использовать как самостоятельно для создания страницы поиска, так и в сочетании с компонентом Форма поиска. Вне зависимости от настроек поиск в системе осуществляется в соответствии с правами пользователя.
В поставку продукта входят пять шаблонов компонента:

  • по умолчанию (.default);
  • с упрощенным оформлением страницы поиска (clear);
  • с графическим отображением содержимого результата поиска (icons);
  • с интерактивными подсказками (suggest);
  • со встроенной поддержкой облака тегов (tags).

Компонент относится к модулю Поиск.

Секции настроек компонента:

Описание параметров

Поле Параметр Описание
Источник данных
Искать без учета морфологии (при отсутствии результата поиска) RESTART [Y|N] При отмеченной опции сначала будет выполнен поиск с учетом морфологии. Если ничего не найдено, то будет запущен поиск без учета морфологии.
Отключить обработку слов как логических операторов NO_WORD_LOGIC [Y|N] При отмеченной опции слова (и, или, не) не будут использоваться как логические операторы.
Искать только в активных по дате документах CHECK_DATES [Y|N] При отмеченной опции поиск будет осуществляться только в активных по дате элементах сайта.
При ранжировании результата учитывать заголовки USE_TITLE_RANK [Y|N] По умолчанию выключена, т.к. создает дополнительную нагрузку. Если опция установлена, то при выводе результатов поиска будут учитываться заголовки новости/статьи/файла и т.п. (найденное будет отображаться сверху списка).
Сортировка по умолчанию DEFAULT_SORT Указывается порядок сортировки результатов поиска по умолчанию: по релевантности (rank) или по дате (date).
Дополнительный фильтр FILTER_NAME Задается имя переменной, в которой передается массив параметров из фильтра для фильтрации поискового индекса. Служит для определения выходящего из фильтра поискового индекса. Поле может быть оставлено пустым, тогда используется значение по умолчанию.
Ограничение области поиска arrFILTER Параметр служит для ограничение области поиска: статическими файлами (main), форумами (forum), одним из типов инфоблоков (iblock), определенных в системе, блогами (blog), социальной сетью (socialnetwork) или информацией о сотрудниках компании (intranet). Можно также выбрать несколько из перечисленных источников информации либо выбрать пункт Не ограничивать.
Если выбрать:

  • [main] Cтатические файлы — то появляется для заполнения поле Путь к файлу начинается с любого из перечисленных, в котором можно указать путь к разделу или файлу, где будет осуществлен поиск, например, /about/. Если поле пусто, то поиск осуществляется во всех статических файлах системы.
  • [forum] Форумы — то ниже отображается поле со всеми форумами, созданными на сайте. Среди них можно выбрать один или несколько форумов либо выбрать вариант (все), тогда поиск будет осуществлен во всех форумах системы.
  • [iblock_ ] — один из типов инфоблоков (например, [iblock_news] Новости), то при нажатии кнопки ОК станут доступны все инфоблоки, созданные внутри выбранного типа. Среди них можно выбрать один или несколько инфоблоков либо выбрать вариант (все), тогда поиск будет осуществлен во всех инфоблоках этого типа.
  • [blog] Блоги — то при данном ограничении поиск будет осуществлен только во всех блогах системы;
  • [socialnetwork] Социальная сеть — то при данном ограничении поиск будет осуществлен только в рамках социальной сети;
  • [intranet] Пользователи — то при данном ограничении поиск будет осуществлен только о сотрудниках компании;
  • [crm] CRM — то при данном ограничении поиск будет осуществлен только по CRM;
  • [disk] Файлы диска — то при данном ограничении поиск будет осуществлен только файлам диска.
Внешний вид
Показывать выпадающий список «Где искать» SHOW_WHERE [Y|N] При отмеченной опции в публичном разделе будет выведен выпадающий список

Значения для выпадающего списка «Где искать» arrWHERE Указываются значения, которые должны быть включены в выпадающий список формы поиска «Где искать» (форум, блоги, инфоблоки и т.д.).

с вариантами ограничения поиска, указанными в параметре arrWHERE.

Показывать фильтр по датам SHOW_WHEN [Y|N] При отмеченной опции на странице поиска будет отображен дополнительный фильтр, позволяющий отсортировать результаты поиска по заданному интервалу времени.
Количество результатов на странице PAGE_RESULT_COUNT Параметр определяет количество результатов поиска, которое будет выведено на одной странице. Все результаты будут выведены с помощью постраничной навигации.
Управление режимом AJAX
Включить режим AJAX AJAX_MODE [Y|N] При установленной опции для компонента будет включен режим AJAX.
Включить затенение AJAX_OPTION_SHADOW [Y|N] Если параметр принимает значение «Y», то при выполнении AJAX-перехода будет затенена область, которая должна измениться.
Включить прокрутку к началу компонента AJAX_OPTION_JUMP [Y|N] Если пользователь совершит AJAX-переход, то при установленой опции по окончании загрузки произойдет прокрутка к началу компонента.
Включить подгрузку стилей AJAX_OPTION_STYLE [Y|N] Если параметр принимает значение «Y», то при совершении AJAX-переходов будет происходить подгрузка и обработка списка стилей, вызванных компонентом.
Включить эмуляцию навигации браузера AJAX_OPTION_HISTORY [Y|N] Когда пользователь выполняет AJAX-переходы, то при включенной опции можно использовать кнопки браузера Назад и Вперед.
Настройки кеширования
Тип кеширования CACHE_TYPE Тип кеширования:

  • A — Авто + Управляемое: автоматически обновляет кеш компонентов в течение заданного времени или при изменении данных;
  • Y — Кешировать: для кеширования необходимо определить время кеширования;
  • N — Не кешировать: кеширования нет в любом случае.
Время кеширования (сек.) CACHE_TIME Время кеширования, указанное в секундах. По умолчанию поле содержит 3600 сек.
Дополнительные настройки
Включить автоопределение раскладки клавиатуры USE_LANGUAGE_GUESS [Y|N] При отмеченной опции будет происходить автоматическое определение раскладки, в которой набран поисковый запрос.
Показывать подсказку с поисковыми фразами USE_SUGGEST [Y|N] При отмеченной опции в строке поиска будет отображаться интерактивная подсказка с введенными ранее поисковыми фразами.
Включить рейтинг SHOW_RATING Указывается включать ли вывод рейтинга:

  • пустое_значение — по умолчанию;
  • Y — да;
  • N — нет.

Данный параметр недоступен для шаблона icons.

Вид кнопок рейтинга RATING_TYPE Указывается тип кнопки рейтинга:

  • пустое_значение — по умолчанию;
  • like — Мне нравится (текстовый);
  • like_graphic — Мне нравится (графический);
  • standart_text — Нравится / Не нравится (текстовый);
  • standart — Нравится / Не нравится (графический).

Данный параметр недоступен для шаблона icons.

Шаблон пути к профилю пользователя PATH_TO_USER_PROFILE Указывается шаблон пути к профилю пользователя.

Данный параметр недоступен для шаблона icons.

Показывать теги документа SHOW_ITEM_TAGS [Y|N] При отмеченной опции для результатов поиска будут показаны теги документа.

Данное поле доступно только для шаблонов icons и clear.

Показывать дату изменения документа SHOW_ITEM_DATE_CHANGE [Y|N] При отмеченной опции для результатов поиска будет показана дата изменения документа.

Данное поле доступно только для шаблонов icons и clear.

Показывать сортировку SHOW_ORDER_BY [Y|N] При отмеченной опции будет доступна сортировка результатов поиска.

Данное поле доступно только для шаблонов icons и clear.

Показывать облако тегов SHOW_TAGS_CLOUD [Y|N] При отмеченной опции на странице поиска будет отображаться облако тегов. Кроме того, становятся доступными дополнительные поля

Сужать область поиска* TAGS_INHERIT [Y|N] При отмеченной опции выбранные теги добавляются в фильтр поиска.
Сортировка тегов* TAGS_SORT Указывается тип сортировки тегов: по имени (NAME) или по популярности (CNT).
Количество тегов* TAGS_PAGE_ELEMENTS Параметр определяет количество выводимых тегов в облаке.
Период выборки тегов (дней)* TAGS_PERIOD Параметр определяет период выборки тегов (дней).
Путь к странице поиска (от корня сайта)* TAGS_URL_SEARCH Указывается путь к странице поиска (от корня сайта).
Максимальный размер шрифта (px)* FONT_MAX Указывается максимальный размер шрифта отображения тегов (в пикселах).
Минимальный размер шрифта (px)* FONT_MIN Указывается минимальный размер шрифта отображения тегов (в пикселах).
Цвет более позднего тега (пример: «C0C0C0»)* COLOR_NEW Указывается код цвета тегов, дата создания которых наиболее поздняя (пример: «C0C0C0»).
Цвет более раннего тега (пример: «FEFEFE»)* COLOR_OLD Указывается код цвета тегов, дата создания которых наиболее ранняя (пример: «FEFEFE»).
Период, в течение которого считать тег новым (дней)* PERIOD_NEW_TAGS Указывается период, в течение которого тег считается новым (дней).
Показывать цепочку навигации* SHOW_CHAIN [Y|N] При отмеченной опции будет показана цепочка навигации. Параметр работает, если параметр TAGS_INHERIT принимает значение Y.
Плавное изменение цвета* COLOR_TYPE [Y|N] При отмеченной опции переход между цветами COLOR_NEW и COLOR_OLD будет плавным.
Ширина облака тегов (пример: «100%» или «100px», «100pt», «100in»)* WIDTH Указывается ширина облака тегов (пример: «100%» или «100px», «100pt», «100in»).

, отмеченные *.

Данное поле доступно только для шаблонов icons и clear.

Настройки постраничной навигации
Выводить над результатами DISPLAY_TOP_PAGER [Y|N] При отмеченной опции постраничная навигация будет выведена вверху страницы поиска.
Выводить под результатами DISPLAY_BOTTOM_PAGER [Y|N] При отмеченной опции постраничная навигация будет выведена внизу страницы поиска.
Название результатов поиска PAGER_TITLE Указывается название заголовка постраничной навигации.
Выводить всегда PAGER_SHOW_ALWAYS [Y|N] При отмеченной опции навигация будет отображаться всегда, даже если результаты поиска помещаются на одной странице.
Название шаблона PAGER_TEMPLATE Указывается название шаблона постраничной навигации.

Пользовательские комментарии

Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.

Для этого нужно всего лишь авторизоваться на сайте

Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.

Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.

Поиск в Perl №1

В данной статье я попытаюсь как можно лучше объяснить что такое регулярные
выражения в Perl. Изюминкой Perl является работа с текстом — для этого он
и был создан. Регулярные выражения очень часто используются в unix системах,
например для поиска файлов по шаблону, также в sh, примеров много и всех не
перечислить, Perl не исключение. В некоторых случаях синтаксис регулярных выражений может быть немного другой, но
поняв синтаксис регулярных выражений Perl с другими проблем не будет.
Я читал много статей по этому поводу и видел много книг, но
действительно хорошо описывающего материала не нашел, потому что в одних книгах
слишком сильно растягивают материал и теряют основную нить рассказа, в других
же наоборот очень мало. Поэтому я решил написать эту статью, в которой я
постараюсь оптимально и ясно рассказать о регулярных выражениях и поиске текста.
Причем непросто на словах, а на большом количестве примеров.
Начнем с того, что в Perl имеются три основных оператора для работы с текстом:

m/. / — проверка совпадений (matching)
s/. /. / — подстановка текста (substitution)
tr/. /. / — трансляция текста (translation)

также парочка полезных функций:

Оператор m/. / пытается сопоставить шаблон указанный в качестве аргумента
с текстом с которым идет сравнение. Например:

$string = «Tasty Berry»;
if($string =

m/berry/i) <
print «This is berry string !»;
>

В данном случае будет выведена строка «This is berry string !». Для сравнения
скаляра с шаблоном нужно использовать сравнение такого вида «=

«.
Здесь оператор m/. / вернет истину или ложь (т.к. данное регулярное
выражение используется в скалярном контексте, а не в
списковом — о нем ниже), если его опустить, то оператор m/. / будет использовать специальную переменную
$_.
Буква i после второй косой черты значит
игнорирование регистра, как вы видите в шаблоне написано «berry» а в $string — «Berry», т.е. если бы не было буквы
i, то наша программа не вывела бы строку «This is berry string !». Шаблон m/berry/i
совпадет со строками «BERRY», «berry», «BeRrY» и т.д.

Данная программа открывает файл и идет по строкам (по строкам т.к. по умолчанию
переменная $/ является переносом строки, переопределяя ее — вы меняете терминатор
строки), сохраняя каждую строчку в
переменную $lines, а если в строчке встречается
слово «exit» — то выходит из цикла. Как вы уже успели заметить я пропустил букву m в начале оператора, т.к.
этот оператор используется очень часто, то можно использовать его сокращенную
форму — без первой буквы m. Также поменять смысл на противоположный можно просто сменив оператор «=

$string = «Tasty Berry»;
if($string !

/berry/i) <
print «This is NOT berry string!»;
>else <
print «This is berry string !»;
>

В данном случае будет выведена строка «This is berry string !». Но если нам
немного поменять строку, таким образом:

$string = «Tasty Strawberry»;

Логически мысля, человек ищет строчку berry (с англ. ягода), но у нас в строчке
strawberry (с англ. клубника), т.е. это нам не подходит, хотя наш шаблон все
равно сработает и выведет «This is berry string !», хотя должен вывести
«This is NOT berry string!». Это получается потому, что когда оператор получает
шаблон «berry» и другую строку, в которой он ищет, символ «b», за которым следует
«e», затем «r», «r» и «y», а все что находится до этой последовательности или после
нее, не имеет значение. Поэтому придется улучшить шаблон, подставив мнимый символ
(об этих символах ниже), вот так:


$string = «Tasty Berry»;
if($string !

/\bberry\b/i) <
print «This is NOT berry string!»;
>else <
print «This is berry string !»;
>

А вот сейчас все правильно — теперь наша программа выведет «This is NOT berry
string!». «\b» в начале шаблона это мнимый символ,
соответствующий границе слова. Как вы видите
некоторые символы имеют определенный смысл для регулярных выражений. Метасимволы
могут создавать альтернативные значения, организовывать
повторы, группировать (что позволяет запоминать часть найденной строки), создавать классы символов и
т.д. Все метасимволы начинаются с обратной косой черты (\). Если шаблон
содержи тсимволы косой черты (например анализ каталогов, или HTML тег), то лучше использовать
другие ограничители, т.к. перед каждой чертой придется ставить обратную косую черту
(\). Вот пример:

$string = «/usr/bin/perl»;
# например вы хотите заменить каталог /bin — на /local/bin
$string =

s/\/bin/\/local\/bin/ig;

Как видите перед каждой косой чертой пришлось ставить обратную косую черту — некрасиво и
очень громоздко, поэтому, заменим разделитель (символ ? и ‘ лучше не использовать в
качестве разделителей, т.к. шаблоны ограниченные этими символами обрабатываются иначе):

$string = «/usr/bin/perl»;
$string =

s%/bin%/local/bin%ig;

Или можно вот так:

Точно также можно использовать квадратные скобки.
Эти же правила можно применять и для других операторов этого класса.
Если вы успели заметить я использовал еще один модификатор регулярных выражений, а именно
g — он означает глобальную поиск и/или замену, например:

$string = «Some path /usr/bin/perl\n. and another path /usr/bin/perl»;
$string =

s%/bin%/local/bin%i;
print $string;

Вывод будет следующим:

Some path /usr/local/bin/perl
. and another path /usr/bin/perl

Путь изменился только в первом совпадении с шаблоном, после этого наш оператор
заканчивает работу, а вот если добавить модификатор g, тогда регулярное выражение будет
сопоставляться до конца текста, т.е. глобально. После добавления модификатора
g результат будет таков:

Some path /usr/local/bin/perl
. and another path /usr/local/bin/perl

Теперь рассмотрим все по порядку, начнем с модификаторов операторов s/. /. / и m/. /

i — игнорирует различие между заглавными и строчными буквами
s — метасимволу точка (.) разрешено соответствовать
\n
m — разрешает метасимволам ^ и $ привязываться к промежуточным символам \n, имеющимся в тексте
x — разрешает использовать пробелы и комментарии в регулярных выражениях
g — глобальный поиск и/или замена (т.е. по всему тексту)
с — работает только для m/. /, не позволяет сбрасывать текущую позицию поиска
o — однократная компиляция шаблонов
e — говорит о том, что правый аргумент команды
s/. /. / это исполняемый код, в
качестве подстановки будет использовано возвращаемое значение
ee — говорит о том, что правый аргумент команды
s/. /. / это строка которую нужно выполнить как фрагмент кода, с помощью функции eval(), потом значение интерполируется

Перед тем как рассмотреть метасимволы, я хочу сказать пару слов об обычных символах.
В шаблоне любой символ соответствует самому себе если не является метасимволом или мнимым
символом, или этим символом:

А теперь давайте посмотрим на все метасимволы:

\077 — восьмеричный символ
\xFF — шестнадцатеричный символ
\a — символ звонка (alarm)
\c[ — управляющие символы, т.е. CTRL + , в данном случае это ESC
\f — символ «прогона» страницы
\d — соответствует цифре
\D — соответствует любому символу, кроме цифры
\e — символ ESC
\l — следующая литера становится строчной
\L — все последующие литеры становятся строчными (вплоть до \E)
\u — следующая литера становится заглавной
\U — все последующие литеры становятся заглавными (вплоть до \E)
\r — возврат каретки (CR)
\n — символ новой строки (LF)
\t — символ горизонтальной табуляции
\v — символ вертикальной табуляции
\Q — все последующие метасимволы становятся обычными (вплоть до \E)
\E — конец действия команд \L, \U и \Q
\s — соответствует любому пробельному символу (т.е. пробел, символ
вертикальной/горизонтальной табуляции, символу новой строки, и т.д.)
\S — любой символ кроме пробельного
\w — алфавитно-цифровой символ (любая цифра, буква или символ подчеркивания)
\W — любой символ, кроме буквы, цифры или символа подчеркивания

Так же в Perl есть определенные символы, которые
соответствуют не какой-нибудь литере, а означают выполнение какого-нибудь условия, они называются — мнимые символы.
Вот они:

| — альтернатива
! — символ логического NOT
. — любой символ, кроме переноса строки
^ — начало строки текста
$ — конец строки текста
\b — граница слова
\B — отсутствие границы слова
\A — «истинное» начало строки
\Z — «истинный» конец строки или позиция перед символом начала новой строки,
расположенном в «истинном» конце строки
\z — «истинный» конец строки
\G — граница на которой остановился предыдущий глобальный поиск
(?=шаблон) — после этой точки есть фрагмент текста, который соответствует указанному регулярному выражению,
(?!шаблон) — после этой точки нет текста, который бы соответствовал указанному
регулярному выражению,
(?

быстрое создание веб-приложений на Perl: вводная

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

Хочется рассмотреть простую ситуацию, которая по моему мнению, часто имеет место быть при разработке малых и средних проектов. А ситуация такая: необходимо создать небольшой (средний) сайт, причем принимается решение отказаться от CMS, так как движок нужен небольшой, наворотов в админке не нужно, сложность примерно 16-24 человеко/часов. Для примера требуется небольшой сайт, который будет содержать статьи определенного типа (обычные текстовые статьи) и новости. Плюс небольшая админка для добавления статей и новостей. Условимся, что у нас есть «большая» разница между этими двумя типами контента в рамках этой статьи.

Проблема

В таких ситуациях довольно часто принимается решение написать свой велосипед, то есть движок. Рассмотрим именно такую ситуацию, на примере которой рассмотрим так же прелести Perl и CPAN.
Полноценную реализацию MVC не предлагаю, это слишком много для нашего маленького проекта. Для Perl написан вагон и маленькая тележка фреймворков (как MVC, так и не очень), например отличный Catalyst, который очень и очень похож на RubyOnRails (или наоборот, я не в курсе хронологии). Так же есть множество поменьше, для любопытствующих стоит взглянуть сюда.

Мы же для простоты реализуем похожий механизм, но попроще. Итак, посмотрим на составляющие нашего движка (LAMP — это as default) в виде модулей:
1. Данные — DBIx::Class
2. Отображение — Template Toolkit
3. Управление — своими руками
Небольшое отступление. Я давно не люблю папку cgi-bin и всячески стараюсь ее избегать, почти на всех хостингах (а тем более дома) разрешены файлы .htaccess. Создаем такой файл в корневой папке проекта и записываем туда:
Options +ExecCGI
AddHandler cgi-script pl
DirectoryIndex index.pl

Теперь можно исполнять скрипты с расширением .pl прям в текущей директории. Кроме того страницей по умолчанию будет наш скрипт index.pl.
Далее советую всегда создавать конфиг. Вариаций множество, каждому нравится по разному, у меня минимально это выглядит так:
package Conf;
use warnings;
use strict;

BEGIN
<
use Exporter;
our (@ISA, @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(
$DB_Host $DB_Port $DB_Name $DB_User $DB_Pass
);
>

our $DB_Host = «host»;
our $DB_Port = 3306;
our $DB_Name = «our_db»;
our $DB_User = «our_table»;
our $DB_Pass = «our_password»;
1;

Ничего военного, сюда вносятся глобальные параметры проекта и экспортируются.

Данные

Структура БД

Вернемся к движку. Пункт первый — это работа с данными, за нее у нас будет отвечать пакет DBIx::Class, который включает несколько модулей. Для начала создадим простую БД, с которой мы будем работать. Не стоит критично относится к структуре базы, она максимально простая, так же синтаксис без всего лишнего, минимизируем затраты.
create table users (
id smallint not null primary key auto_increment,
name varchar(32) not null,
pass varchar(32) not null);

create table categories (
id int not null primary key auto_increment,
name varchar(128) not null) charset cp1251;

create table articles (
id int not null primary key auto_increment,
category_id int not null,
title varchar(255) not null,
content text not null,
author varchar(128) not null comment ‘Author of article’,
added_at timestamp not null,
added_by smallint not null comment ‘Admin user ID’) charset cp1251;

create table news (
id int not null primary key auto_increment,
added_at timestamp not null,
title varchar(255) not null,
content text not null,
is_put_on_main bool not null default 0 comment ‘Show on main page?’,
added_by smallint not null) charset cp1251;

Таблица пользователей содержит самые основные данные (учет посещений и прочих нас пока не волнует), таблица categories содержит разделы статей, например «автомото», «спорт», «кулинария» и т.п., таблица articles содержит собственно статьи, а таблица news — новости. В последней есть поле is_put_on_main, которое отвечает за показ новости на главной. Так же почти в каждой таблице я задаю кодировку — это привычка, кто уверен — не делайте.

Отображение в код

Хорошо, таблицы у нас есть, теперь необходимо отобразить их в коде. Модуль DBIx::Class позволяет полностью отойти от написания SQL-кода и общаться с таблицами, как с объектами. Работать с этим модулем можно двумя способами: либо вручную описывать структуры каждой таблицы, либо воспользоваться автоматикой. Рассмотрим оба способа по порядку.

Ручной метод

Смотрим в код, далее будут пояснения. Создадим в корне нашего проекта папку с именем DB и в ней создадим четыре файла: User.pm, Category.pm, Article.pm, News.pm, вот содержимое этих файлов.
# file User.pm
package DB::User;

use base qw/DBIx::Class/;

__PACKAGE__->load_components(qw/PK::Auto Core/);
__PACKAGE__->table(‘users’);
__PACKAGE__->add_columns(qw/id name pass/);
__PACKAGE__->set_primary_key(‘id’);

# file Category.pm
package DB::Category;

use base qw/DBIx::Class/;

__PACKAGE__->load_components(qw/PK::Auto Core/);
__PACKAGE__->table(‘categories’);
__PACKAGE__->add_columns(qw/id name/);
__PACKAGE__->set_primary_key(‘id’);

# file Article.pm
package DB::Article;

use base qw/DBIx::Class/;

__PACKAGE__->load_components(qw/InflateColumn::DateTime PK::Auto Core/);
__PACKAGE__->table(‘articles’);
__PACKAGE__->add_columns(qw/id category_id title content added_by author/);
__PACKAGE__->add_columns(‘added_at’ => < data_type =>‘timestamp’ >);
__PACKAGE__->set_primary_key(‘id’);

__PACKAGE__->belongs_to(‘category’ => ‘DB::Category’,
< 'foreign.id' =>‘self.category_id’ >);
__PACKAGE__->belongs_to(‘user’ => ‘DB::User’,
< 'foreign.id' =>‘self.added_by’ >);

# file News.pm
package DB::News;

use base qw/DBIx::Class/;

__PACKAGE__->load_components(qw/InflateColumn::DateTime PK::Auto Core/);
__PACKAGE__->table(‘news’);
__PACKAGE__->add_columns(qw/id title content is_put_on_main added_by/);
__PACKAGE__->add_columns(‘added_at’ => < data_type =>‘timestamp’ >);
__PACKAGE__->set_primary_key(‘id’);

__PACKAGE__->belongs_to(‘user’ => ‘DB::User’,
< 'foreign.id' =>‘self.added_by’ >);

1;

Итак, небольшие пояснения. Имеем четыре очень похожих файла, сначала объявляем базовым модуль DBIx::Class, далее используя механизм __PACKAGE__ вызываем его методы, а именно: load_components — загружаем компоненты для нашего модуля (PK::Auto для работы с автоинкрементированными primary_key, Core — основной набор для работы со связями, строками и столбцами). Далее указываем таблицу, после чего добавляем названия столбцов. Для работы со столбцами таких типов, как datetime, date и timestamp используется небольшой модуль InflateColumn::DateTime. С помощью него поля указанных типов можно использовать в программе, как объекты типа DateTime, со всеми вытекающими удобствами. После чего указываем primary key (если он составной, то указываем несколько полей set_primary_key(qw/name1 name2/);.
Далее находятся знакомые для знающих RubyOnRails методы has_many(), belongs_to() и другие. Эти методы предназначены для создания связей между таблицами.
Документация по чудному модулю DBIx::Class, где все подробно описано, включая туториал и cookbook.

Теперь нам нужно использовать сие чудо, для этого нам нужен модуль DBIx::Class::Shema, который является абстракцией схемы данных. В корневой папке проекта создаем файл с именем, идентичным имени папки с классами, описывающими таблицы, в нашем случае это будет DB.pm Вот как он выглядит у меня.
package SDB;

use base qw/DBIx::Class::Schema/;
use Conf;

sub GetSchema()
<
my $dsn = «dbi:mysql:$DB_Name:$DB_Host»;
my $sch = __PACKAGE__->connect($dsn, $DB_User, $DB_Pass);

1;

В целом, использовать DBIx::Class::Schema можно и без функции GetShema(), метод load_classes() автоматически загружает все файлы, найденные в одноименной папке. Я дописал небольшую функцию, что бы удобнее было получать схему. Без этой функции соединение в коде выглядело бы так:
my $dsn = «dbi:mysql:$DB_Name:$DB_Host»;
my $sch = DB->connect($dsn, $DB_User, $DB_Pass);

В случае с функией можно написать их несколько либо по другому конфигурировать соединение с разными типа баз.

Автоматический метод

В «ручном» примере мы вручную задавали все связи между таблицами. Существует модуль DBIx::Class::Shema::Loader, который выполняет загрузку и создание классов автоматически. Для этого необходимо добавить в структуру БД описание внешних ключей (foreign keys). Используя их загрузчик автоматически создаст необходимые связи. Вот как это выглядит:
package DB;
use base qw/DBIx::Class::Schema::Loader/;


__PACKAGE__->loader_options(
inflect_singular => 1,
components => qw/InflateColumn::DateTime/
);

use DB;
my $sch = DB->connect( $dsn, $user, $password, $attrs);

Так же можно добавить выше функцию GetShema() (см. выше) и использовать ее. В данном случае папка DB и четыре файла в ней становятся не нужными и у нас остается один файл-описание схемы. Загрузчик поддерживает множество опций, которые задают пространство имен для создаваемых классов, параметры генерации имен классов, и другие.

Использование схемы

Теперь посмотрим, как это все вместе используется непосредственно в коде.
use DB;

my $sch = DB->GetShema();
# Поиск пользователя по id
my $user = $sch->resultset(‘User’)->find( < id =>$id >);

# Добавление новости
my $new_ >resultset(‘Category’)->populate(
[
[qw/title content is_put_on_main added_by/],
[$ntitle, $ncontent, 0, $user_id]
]);

# Удаление статьи
$sch->resultset(‘Article’)->find( < id =>$aid >)->delete;

Далее, покажем наши данные.

Отображение

Я использую систему шаблонов Template Toolkit. Есть еще несколько систем, например Mason, но так исторически сложилось, что мой выбор пал на Template Toolkit.
Template Toolkit — это система обработки шаблонов. Посмотрим ее использование сразу на примере. Для начала создадим в корне проекта папку tmpl и в ней создадим папку site. В папке tmpl/site создадим файл site следующего содержания:
Portal

Далее, сделаем там же файл start_page:
News and articles

Вот такой простой файл с одной строчкой. Это будет заготовка нашей стартовой страницы. Свяжем все вместе и получим примерно такой код нашего скрипта index.pl:
#!/usr/bin/perl -w

use CGI;
use Template;

use Conf;
use DB;

# инициализируем CGI
my $q = CGI->new;
my %p = $q->Vars;

# . шаблоны
my $tmpl = Template->new(
<
INCLUDE_PATH => ‘tmpl/site’,
INTERPOLATE => 1,
EVAL_PERL => 1
>) || die «$Template::ERROR\n»;

# . данные
my $sch = DB->GetShema();

# теперь мы готовы к работе
my $tmpl_vars = <>;
$tmpl_vars-> = ‘start_page’;

print $q->header(-type => ‘text/html’, -charset => ‘windows-1251’);
$tmpl->process(‘site’, $tmpl_vars) || die $tmpl->error(), «\n»;

Две строчки про CGI думаю всем понятны, далее идет создание объекта Template, главным параметром которого является INCLUDE_PATH — пусть к шаблонам. Чуть ниже мы создаем схему данных и соединяемся с базой. Далее мы создаем хэш, в который будем складывать все переменные, которые необходимо передать в шаблон. В нашем случае мы передаем только одну переменную content, эта переменная используется в директиве PROCESS в шаблоне site. Еще ниже мы запускаем обработку шаблона и указываем стартовый шаблон — site, а так же передаем хэш переменных.

В шаблоне site используется директива PROCESS, она запускает вложенную обработку другого шаблона, имя которого передано параметром, но так, как у нас имя хранится в переменной, то мы указываем это непосредственно — [% PROCESS $content %]. Таким образом в тело шаблона site вставится содержимое шаблона start_page. Добавим немного разнообразия. На главной странице мы должны отображать статьи и новости, но не все, а, скажем, последние десять. К тому же новости только те, которые помечены соответствующим флагом в таблице. Перед обработкой шаблона добавим в наш скрипт несколько строк:
my $articles = [$sch->resultset(‘Article’)->search(undef,
<
order_by => ‘added_at desc’,
rows => 10,
page => 1
>)];
my $news = [$sch->resultset(‘News’)->search(
<
is_put_on_main => 1
>,
<
order_by => ‘added_at desc’,
rows => 10,
page => 1
>)];
$tmpl_vars-> = $articles;
$tmpl_vars-> = $news;

Следует заметить, что мы использовали [] для создания спискового контекста, иначе в скалярном контексте функция search() возвращает объект типа ResultSet, а нам нужен именно массив данных.

Итак, подробно описывать не имеет смысла, так как все довольно явственно. Единственное, это использование параметров rows/page. Они необходимы для создания так называемых pager-ов, с помощью которых удобно организовывать постраничный вывод, а так же применяются для простого отбора записей, что является частным случаем. Так же кол-во статей и новостей можно вынести в конфиг.

Далее, изменим шаблон start_page:

Новости

[% FOREACH n = news %]
[% n.added_at.dmy(‘.’) %] [% n.title %]

[% n.content FILTER html %]

Статьи

[% FOREACH a = articles %]
[% a.added_at.dmy(‘.’) %] [% a.title %]

Раздел: [% a.category.name %]
[% a.content FILTER html %]

[% END %]

Отмечу использование поля added_at, как объекта. Для него вызывается метод dmy(), который форматирует дату в формат ДД-ММ-ГГГГ с переданным разделителем, в нашем случае точка. Объект DateTime поддерживает локали и корректно отображает дату в зависимости от текущей (или выбранной) локали. Так же он содержит множество методов для форматирования и работы с датами.

Я пока намеренно не добавлял валидные ссылки, сделаю это позже.
В целом мы видим два похожих блока, которые стоит вынести в отельный файл. Создадим файл short_note в папке tmpl/site:
[% text = node.content;
IF text.length > 512;
text = text.substr(0, 512);
END %]
[% note.added_at.dmy(‘.’) %] [% note.title %]

[% IF note.category %]
Раздел: [% note.category.name %]
[% END %]
[% text FILTER html %]

Теперь наш шаблон start_page примет такой вид:

Новости

Статьи

[% FOREACH a = articles %]
[% PROCESS short_note note = a %]
[% END %]

Теперь мы вызываем обработку шаблона short_note и передаем ему в качестве параметра note текущую новость или статью.

В шаблоне выполняется проверка на наличие поля category, что у нас будет признаком статьи, в этом случае мы выводим название раздела.

На нашем портальчике так же необходимы шаблоны для отображения полной статьи или новости, отображение списка категорий статей, поисковая форма и результаты поиска. В целом, добавится еще несколько шаблонов, которые мало чем будут отличаться от вышеприведенных в плане сложности.

Управление

Выше мы условились не применять всяческих фреймворков, попробуем сделать минимум своими руками. Для этого сделаем следующую простую структуру (ламерскую, да-да):
my $act = $p <'a'>|| ‘start’;

if ($act eq ‘start’)
<
>
elsif ($act eq ‘article’)
<
>
elsif ($act eq ‘news’)
<
>
# .
else
<
>

Итак, каждую ссылку в скрипте будет сопровождать параметр a — action. Он будет задавать текущий контекст. Таким образом, ссылки выше в шаблонах можно сменить на такие:

Далее, нужно подумать о безопасности. Сейчас нас интересует только параметр id, на данный момент других у нас не используется. Сделаем самый простой финт ушами непосредственно перед разбором контекста:
$p<' >);

То есть, если у нас есть какой-то номер, будь то статьи, новости или каталога, то мы вырежем оттуда все не-цифры. Простой и дубовый метод.

Рассмотрим далее примеры кода для контекстов.
if ($act eq ‘start’)
<
$tmpl_vars-> = ‘start_page’;
my $articles = [$sch->resultset(‘Article’)->search(undef,
<
order_by => ‘added_at desc’,
rows => 10,
page => 1
>)];
my $news = [$sch->resultset(‘News’)->search(
<
is_put_on_main => 1
>,
<
order_by => ‘added_at desc’,
rows => 10,
page => 1
>)];
$tmpl_vars-> = $articles;
$tmpl_vars-> = $news;
>
elsif ($act eq ‘article’)
<
$tmpl_vars-> = ‘full_article’;
$tmpl_vars->

= $sch->resultset(‘Article’)->find( < id =>$p <'id'>>);
>
elsif ($act eq ‘category’)
<
$tmpl_vars-> = ‘category’;
$tmpl_vars-> = $sch->resultset(‘Category’)->find( < id =>$p <'id'>>);
>
elsif ($act eq ‘news’)
<
$tmpl_vars-> = ‘full_article’;
$tmpl_vars->

= $sch->resultset(‘News’)->find( < id =>$p <'id'>>);
>
else
<
# см. ниже
>

Поиск я не рассматривал, он довольно прост, из формы мы передаем введенные данные для поиска среди статей и новостей и выводим результаты. Так же стоит помнить, что в Perl существуют удобные модули для проверки данных на валидность, переданных из форм, например HTML-CheckArgs или HTML-QuickCheck. Существую более продвинутые инструменты, например HTML-Widget или HTML-Tag. Это полноценные системы для создания виджетов и проверки данных на валидность. Очень удобны в коде, а так же удобны для повторного использования. Единожды созданный виджет можно использовать во множестве приложений.

В последнем случае есть небольшая дилемма: что делать, если задан неверный контекст. Некоторые склоняются к выводу ошибки (для этого нужно создать шаблон, например error_action, и просто указать на него), я же склонен отправлять всех на главную:
print $q->header(-location => ‘?a=start’);
exit;

Это не умно и не круто, зато безболезненно. Для тех, кто беспокоится о лишнем запросе к серверу, можно сделать следующим образом (до обработки контекста):
my %action = (
‘start’ => ‘Main page’,
‘news’ => ‘News page’,
‘article’ => ‘Full article’,
# .
);
my $act = ( $p <'act'>&& defined( $actions<$p<'act'>> )) ? $p <'act'>: ‘start’;

То есть, если задан контекст и он присутствует в списке — использовать его, иначе установить ‘start’. Хэш контекстов используется вместо массива для облегчения проверки — defined(. ).

Администрирование

Для администрирования необходимо создать некий инструмент. С точки зрения модели построения админка ничем не отличается от вышеприведенной системы, кроме авторизации и нюансов с текстом. Рекомендутеся создать отдельную папку для шаблонов, например tmpl/admin.
Для авторизации я использую два инструмента: Digest::SHA1 и CGI::Session. Первый обеспечивает шифрование, второй — сессии.
Итак, рассмотрим на простом примере применение этих инструментов. Пример намеренно упрощен до безобразия.

Шаблоны:
[%# Шаблон login %]
[% IF err %]
Wrong login
[% END %]
/>
Login: />
Password: />
/>

В скрипте админки нужно дописать вход и выход из системы, а так же сессии:
use CGI::Session;
use Digest::SHA1 qw(sha1_hex);

# . после CGI загружаем сессию
my $s = CGI::Session->load(undef, undef, < Directory =>‘ssss’ > );

# . после определения контекста
if ($s->empty && $act !

/login(_form)?|logout/)
<
print $q->header(-location => ‘?a=login_form’);
exit;
>
else
<
my $user = $sch->resultset(‘User’)->find( < id =>$s->param(‘uid’) >);
$tmpl_vars-> = $user;
>

print $s->header(-location => ‘?a=start’);
exit;
>
>
elsif ($act eq ‘logout’)
<
$s->delete;
print $q->header(-location => ‘?a=login’);
exit;
>

# и небольшая функция
sub login
<
my ($u, $p) = @_;

my $pp = sha1_hex($p);
my $res = $sch->resultset(‘User’)->search( <
name => $u,
pass => $pp
>);

my $user = $res->next;
return $user;
>

Пример сильно дубовый, но тем не менее, он показывает суть.
Модуль CGI::Session поддерживает хранение сессий как в файле, так и в БД. Так же необходимо указать срок истечения — expired. В примере использовано хранение в файлах в каталоге ssss.
Модуль Digest::SHA1 — как альтернатива MD5.

Следующий нюанс касается создания форм для ввода данных. Во-первых, необходимо создать так называемые CRUD-методы (CReate, Update, Delete). Для этого, например, существует модуль DBIx::Class::WebForm. Так же по запросу CRUD на CPAN можно найти еще несколько подобных модулей.
Во-вторых, необходимо организовать удобный ввод текста статей и новостей. Лично я использую FCKeditor, хотя есть множество других. Такие редакторы довольно просто интегрируются в страничку и дают пользователям удобство и счастье в жизни.
В-третьих, стоит позаботится о валидации данных из форм. Например, модуль DBIx::Class::Validation проверяет данные перед отсылкой в базу, так же есть всевозможные валидаторы данных из форм, которые работают совместно с виджетами или формами, например CGI::FormBuilder, CGI::QuickForm и т.д. По запросу «Form», «Validate» или «Widget» можно найти множество модулей для этих целей.

Заключение

В этой «небольшой» заметке я хотел поделиться своим небольшим опытом в создании простых приложений. Заметка вышла не маленькая, но, надеюсь, информативная. Приведенный здесь метод создания приложений очень эффективен в плане повторного использования, единожды созданные кусочки сайта можно потом использовать в других местах, почти ничего не меняя. Так же мы достаточно эффективно разделили вид и код, а так же абстрагировались от непосредственного написания SQL-запросов.

Вот архив примера, а здесь — рабочий пример. На создание примера ушло меньше часа.

Статические и динамические сайты — отличия?

Даже у новичков наверняка на слуху такие фразы «статичекий сайт» и «динамический сайт». Но что конкретно значат эти словосочетания и в чем разница между ними, каковы преимущества того или другого вида сайта?

Давайте мы с вами не будем гадать, а просто подробно разберемся и сравним их.


Статические и динамические сайты — в чем разница?

Хотя на сегодняшний день количество динамических сайтов увеличивается, нельзя наверняка сказать, окинув первым взглядом сайт, который вы открыли, статический он или динамический.

Статические сайты примеры

Предположить можно с первого взгляда, что сайт является статическим, если, например, он содержит одну или небольшое количество страниц, или, например, если это сайт-визитка какой-либо компании и информация на нем никогда не изменяется или обновляется очень редко, если на нем нет таких возможностей, как, например, комментирование или регистрация и т.п..

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

Статичные сайты стоят дешевле и занимают меньше места на хостинге, потому многие небольшие компании до сих пор предпочитают их динамическим сайтам.

Таким образом, мы можем видеть преимущества статических сайтов:

  1. Они просты и быстры в разработке
  2. Дешевы в разработке и меньше нагрузки на хостинг.

Наряду с преимуществами можно выделить и недостатки статических сайтов:

    Для обновления сайта требуется опыт вебразработки.

Чтобы обновить даже самую маленькую деталь на таком сайте, вам придется либо самому копаться в коде, либо, если вы сами не знаете HTML и CSS, вам нужно будет каждый раз прибегать к услугам вебмастера.

Из-за того, что содержимое такого сайта обновляется очень редко, контент на них «застаивается», это весьма неблагоприятным образом сказывается на трафике и продвижении сайта в поисковиках. Конечно, продвигать такой сайт можно, но преимущественно платными способами.

Динамичные сайты примеры

С другой стороны — динамические сайты могут стоить гораздо дороже, тем более, если они будут разрабатываться с самого нуля. А также хостинг будет немного дороже, так как нужно будет подключить дополнительные возможности. Но многочисленные преимущества динамических сайтов с лихвой перекрывают эти недостатки.

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

Возможности динамического сайта могут ограничиваться только нашим воображением.

Примеры динамических сайтов — это сайты на основе систем управления, интернет-магазины, сайты объявлений, форумы, сайты с возможностями для клиентов и посетителей оставлять отзывы, комментарии, загружать файлы и т.д.

Преимущества динамических сайтов:

  1. Более функциональный сайт.
  2. Намного проще его обновлять.
  3. Постоянное обновление положительно сказывается на продвижении сайта и приносит больше посетителей.
  4. Такой сайт помогает своему владельцу собирать вокруг себя сообщество посетителей и дает намного больше возможностей общаться со своей аудиторией и сделать свой сайт более интересным для посетителей за счет различных функций.

Выводы

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

Все больше и больше людей осознают неоспоримое преимущество динамических сайтов, а потому их появляется все больше в сети.

Но с другой стороны, все зависит от того, что нужно конкретно ВАМ, если вам нужен, например, одностраничный сайт, через который вы будете продавать какой-то товар, или же сайт-визитка от 1 до 5-6 страниц, который вы не планируете постоянно обновлять, то вполне естественным решением будет остановиться на статическом сайте.

Если же вы хотите чтобы ваш проект постоянно развивался и наполнялся контентом, то, несомненно, вам нужен динамический сайт.

Perl и CGI программы — особенности использования

1. Использование готовых скриптов

Если у вас уже есть написанные CGI-скрипты, то прежде чем скопировать их на сервер, вы должны сделать следующие действия:

  • Убедиться, что в скриптах указан правильный путь к интерпретатору:

Perl: /usr/bin/perl
Python : /usr/local/bin/python

  • Если вашему скрипту требуется доступ к базе данных MySQL , то необходимо указать параметры доступа (см. статью Подключение к серверу MySQL)
  • В разделе Управление веб-серверомпанели управления хостингом включить модуль CGI.

Теперь вы можете скопировать свои скрипты на сервер.
Загружать файлы необходимо в каталог ваш_домен/cgi. Файлы из данного каталога будут доступны по адресу https://ваш_домен/cgi-bin/имя_файла. Для того чтобы CGI-скрипты запускались из корневого каталога сайта ваш_домен/docs, необходимо создать в нем файл .htaccess со следующим содержимым:

На скрипты необходимо установить права доступа 755 или -rwxr-xr-x.
Права доступа можно изменить с помощью файлового менеджера панели управления.

2. Написание простейшего CGI-скрипта

Рассмотрим написание простого CGI скрипта на Perl.
Если вы работаете под управлением ОС «Windows», то для работы с кодом скриптов вам необходимо использовать специализированный текстовый редактор, например, Notepad++. Стандартную для Windows программу «Блокнот» лучше не использовать. Для демонстрации работы CGI скрипта необходимо создать два файла. Первый файл представляет собой html-документ с формой ввода текста:

HTML PUBLIC «-//W3C//DTD HTML 4.0//EN»>

Пример работы с Perl

Поиск по сайту — статичный контент (Perl)

Профиль
Группа: Участник
Сообщений: 554
Регистрация: 28.7.2006

Репутация: нет
Всего: нет

необходимо сделать из динамического сайта статический .
что то типа этого делают off line броузеры (но это не совсем то что меня устраивает, поэтому решил все сделать сам и вот я здесь .

подскажите как рекурсивно обойти все ссылки.
я никак не догоню про рекурсию.

Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 4
Всего: 49

ginnie
Дата 22.9.2009, 11:42 (ссылка) | (нет голосов) Загрузка .

Профиль
Группа: Участник
Сообщений: 554
Регистрация: 28.7.2006

Репутация: нет
Всего: нет

Перевод на статику мне нужен, чтобы придать вес моего сайта в глазах поисковых систем.
Понимаю, что многим такое решение покажется сомнительным, но все же. (к тому же от основного динамического варианта я не отказываюсь : — в нужный момент — раз и подключил)

поэтому off line броузер для такой задачи (напрямую) не подошел. (он меняет структуру сайта, страниц)
а мне нужна только генерация HTML без выкачки содержимого.
решил сам написать нечто вроде off line Броузера

ну и первым вопросом попал на рекурсивный обход ссылок.

burakov
Дата 22.9.2009, 12:01 (ссылка) | (нет голосов) Загрузка .

Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 4
Всего: 49

ginnie
Дата 22.9.2009, 12:08 (ссылка) | (нет голосов) Загрузка .

Профиль
Группа: Участник
Сообщений: 554
Регистрация: 28.7.2006

Репутация: нет
Всего: нет

и все таки рекурсивное получение ссылок понадобится мне для еще одной задачи — карта сайта (нужна для того же SEO).

у кого нить есть примерчик такого получения ссылок из сайта ?

burakov
Дата 22.9.2009, 12:40 (ссылка) | (нет голосов) Загрузка .

Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 4
Всего: 49

burakov, несколько удивляет попытки решать задачи через получение и обработку содержимого страниц. Такой подход актуален для чужих внешних сайтов. Для собственного сайта нужно использовать более эффективные методы! Я не могу представить, что Вы не знаете какие страницы есть на Вашем сайте! Он динамический, формируется, скорее всего, на основе БД. Вы серьезно считаете, что получение и парсинг html-страниц сайта эффективнее запросов в БД и формирования необходимых url?

P.S. Если очень хочется попробовать рекурсию, читайте Поиск по сайту — статичный контент (Perl)

Это сообщение отредактировал(а) ginnie — 22.9.2009, 12:50

ginnie
Дата 22.9.2009, 12:47 (ссылка) | (голосов:1) Загрузка .
Google
Дата 10.11.2020, 01:19 (ссылка)
Правила форума «Perl: CGI программирование»
  • В этом разделе обсуждаются вопросы относящиеся только к CGI программированию
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O’REILLY, The source for Perl
  • Справочное руководство «Установка perl-модулей», качать здесь
  • FAQ раздела лежит здесь!

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

Поиск по сайту — статичный контент (Perl)

Perl является интерпретируемым языком, созданным программистом Лари Уоллом (Larry Wall) для обработки больших текстов и файлов и расшифровывается, как Practical Extraction and Report Language (язык для практического извлечения данных и составления отчетов). С помощью Perl вы, например, можете создать скрипт, который открывает один или несколько файлов, обрабатывает информацию и записывает результаты.

С изобретением World Wide Web, Perl оказался прекрасным средством для взаимодействия с web-серверами через Common Gateway Interface (CGI) — общий интерфейс взаимодействия. Команды Perl могут легко получить данные из формы HTML или другого источника и что-нибудь с ними сделать.

Как Perl обрабатывает данные из форм

Perl достаточно гибок для обработки введенных данных. Например, если пользователь вводит информацию в регистрационную форму скрипт Perl может обработать ее многими способами, такими как:

  • добавить их в текстовый файл,
  • ввести их в базу данных,
  • вставить их в электронное письмо,
  • добавить их в существующую web-страницу,
  • создать новую web-страницу,
  • отобразить их в окне браузера.

Некоторые из этих примеров рассматриваются в нашем уроке.

Как генерируются web-страницы «на лету»

Больше всего впечатляет то, что Perl может быть использован для создания web-страниц «на лету» в ответ на запрос или действие пользователя. Новая страница может быть

  • благодарностью за заполнение формы
  • страницей подтверждения с возможностью редактирования
  • запросом дополнительных данных
  • результатом запроса к базе данных или запроса поиска

Эта возможность обеспечивает истинную интерактивность вашего узла. Такие скрипты позволят web-серверу автоматически реагировать на определенный набор запросов пользователя, предоставляя данные в требуемом пользователем виде.

В чем различие между программой и скриптом?

Перед началом работы с Perl необходимо понять разницу между программой и скриптом. Оба из них используют набор инструкций для выполнения определенного задания, но программа скомпилирована в эффективный двоичный формат, что позволяет ей быстро выполняться на определенной платформе, в то время как скрипт хранится в оригинальном текстовом формате.

За счет того, что скрипты значительно короче программ, они выполняются тоже достаточно быстро.

За счет того, что скрипт не надо компилировать перед запуском он становится замечательным средством для быстрого создания и внесения исправлений в разработку интерактивных частей узла.

Альтернативы Perl

Существует несколько альтернатив использованию Perl:

  • С, Visual Basic — более традиционные компьютерные языки для обработки вводимых данных. Должны компилироваться под определенную платформу.
  • ActiveX — включение программных компонент, выполняющихся в браузере.
  • JavaScript, VBScript — обеспечивают некоторую интерактивность HTML страниц, которую HTML обеспечить не может.
  • Cold Fusion — сторонняя программа для связи форм с базами данных.
  • PHP/FI — еще одна сторонняя программа для связи форм с базами данных.

Несмотря на это Perl на сегодняшний день является наиболее простым и быстрым и в тоже время очень мощным средством придания интерактивности вашему узлу.

Что вам требуется, чтобы запустить Perl

Для запуска Perl вашей системе понадобится несколько компонент:

  1. Скрипт, написанный вами или предложенный вам другим, сохраненный в текстовом файле.
  2. Perl интерпретатор. Любой Perl скрипт в первой строке содержит путь к этой программе.
  3. Web-страница с которой будет запускаться этот скрипт. Она может содержать форму или просто ссылку, если скрипт не требует входных данных.
  4. Web-сервер. Взаимодействие между web-страницей и скриптом производится сервером. Поэтому вы должны иметь доступ к web-серверу с возможностью записи и запуска на нем скриптов.

Где взять Perl

Существует много различных мест, где можно получить информацию о последних версиях Perl.

  • Общая информация о Perl — https://www.perl.com/perl/index.html
  • Perl для UNIX — https://www.perl.com/perl/info/software.html
  • Perl для Win32 — https://ntperl.hip.com

Этапы создания скрипта

После того, как вы установили на своем компьютере необходимое ПО, нужно совершить несколько шагов для запуска Perl на вашем узле:

  1. Создать форму для вызова скрипта.
  2. Создать сам скрипт.
  3. Отладить скрипт. Проверить отсутствие ошибок (если это возможно, лучше проверить все возможные пути выполнения программы).
  4. Поместить скрипт на сервер и не забыть дать ему права на выполнение.
  5. Связать скрипт с формой, вставив его имя в параметр action тэга form. Например:

Сохраните файл на диске.

Шаг 2 — Создание скрипта

Предложенный ниже скрипт берет введенные данные, сохраняет их в файле и показывает сообщение, содержащее ссылку на файл с сохраненным именем. Наберите в редакторе текст программы и сохраните в файле testform.pl в каталоге cgi-bin вашего web-сервера. Убедитесь, что первая строка программы содержит правильный путь к программе-интерпретатору (для определения местоположения программы на UNIX воспользуйтесь командой which perl, под Windows выполните поиск файла perl.exe). Убедитесь также, что путь к выходному файлу является корректным путем к области хранения документов web-сервера. В заключение исправьте URL на адрес вашего сервера.

Шаг 3 — Тестирование скрипта

Проверив скрипт визуально на наличие ошибок — отсутствие «;» в конце строк, наличие непарных скобок и кавычек и т.п., запустите скрипт для проверки прямо из командной строки, перейдя предварительно в каталог cgi-bin. Вот некоторые примеры того, как это делается:

Если в скрипте содержатся ошибки, то вы увидите сообщение типа

В этом случае проверьте текст около указанной строки. Помните, что причина ошибки может быть выше на несколько, иногда достаточно много строк. Исправленный скрипт сохраните, и тестируйте так до тех пор, пока он не выдаст корректных выходных данных:

Шаг 4 — Тестирование скрипта с формой

Если скрипт работает сам по себе, вы можете оттестировать его с формой:

  1. Убедитесь, что web-сервер запущен.
  2. Запустите ваш браузер.
  3. Наберите URL по которому находится ваша форма (обратите внимание, что строка должна начинаться с https://, а не с file://.
  4. Введите ваше имя в поле формы и нажмите кнопку «Зарегистрировать».
  5. Вы должны увидеть сообщение вроде этого:

Спасибо, что заполнили форму
Нажмите сюда, чтобы увидеть Ваш ввод.

Это и есть страница, сгенерированная скриптом «на лету». Если вы получили сообщение об ошибке сервера, проверьте правильность расположения скрипта и правильность значения параметра action в тэге form.

  1. Если вы видите правильно сгенерированную страницу, нажмите на ссылку. Вы должны будете увидеть новую страницу, созданную скриптом примерно в таком виде:

Если вы не видите этого, проверьте правильность пути в переменной $targetfile и правильность URL в предпоследней строке скрипта. В противном случае форма и скрипт правильно работают вместе. Вы успешно создали первое web-приложение.


Далее мы рассмотрим четыре части созданного нами скрипта более внимательно.

Обсуждение: Настройка скрипта

Как уже было сказано, первая часть скрипта содержит настройки, включающие в себя несколько элементов. Первая строка определяет путь к программе-интерпретатору:
#!/usr/local/bin/perl для UNIX
или
\Program Files\Perl5\perl.exe для Win32

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

Комментарии могут располагаться в любом месте программы и начинаются с символа #:
или

Также хорошей манерой является определение в начале скрипта всех констант и глобальных переменных. (Советую все пути прописывать в виде переменных, особенно если программа содержит более 50 строк, для удобства изменения местоположения файлов). Например:

Все обычные переменные в Perl начинаются с символа $. Существует много других видов переменных, таких как массивы и т.п.

Все строки программы кроме первой и комментариев должны заканчиваться на «;».

Обсуждение: Чтение данных из формы

Теперь необходимо «считать» введенные пользователем данные в переменные Perl. После того как пользователь нажмет кнопку Submit в форме браузер посылает серверу имя скрипта и данные, взятые из формы. Данные передаются скрипту на стандартный вход.

Предположим, что форма содержит следующие поля:

Имя поля в форме

Имя, определенное параметром name=»xxx» в тэге поля

Данные пользователя

user_name

Andy Novikov

Компания:

co_name

TeleSputnik

Телефон:

phone

(812) 123-45-67

В этом случае данные будут посланы скрипту в следующем формате:
user_name=Andy+Novikov&co_name=TeleSputnik&phone=(812)+123-45-67

Perl скрипт должен разобрать эту строку по частям и сохранить в переменных для дальнейшей обработки. Строки, производящие эти действия достаточно стандартны:

Эта строка читает данные со стандартного входа и помещает их в переменную $buffer. Длина строки передается скрипту через переменную окружения CONTENT_LENGTH.

Как только данные помещены в переменную $buffer вы можете разбить их на отдельные переменные с соответствующими им значениями:

Теперь мы получили массив @pairs со следующими строковыми переменными:
[1] user_name=Andy+Novikov
[2] co_name=TeleSputnik
[3] phone=(812)+123-45-67

Теперь нам необходимо разбить эти строки на пары параметр-значение:

Таким образом вы получаете массив переменных, индексом в котором является значение параметра name поля формы, а значением — данные, введенные в соответствующее поле.

Обсуждение: Что делать с данными?

Следующим шагом является обработка данных. Но как? Все зависит от того, что вы хотите сделать с данными. В нашем примере мы на основе полученных данных создаем новый HTML документ. Нише мы рассмотрим несколько простых примеров того, что можно сделать с полученными данными. Обратите внимание, что мы не предпринимаем попыток проверить правильность (validate) содержимого полей. Хотя в реальных скриптах это является желательным, а иногда и необходимым действием.

Обсуждение: Запись в файлы

Одно из действий, которое вы можете совершить над данными, это записать их в файл. Perl предоставляет набор функций для открытия, обработки и закрытия файлов. Таким образом вы можете создать новый HTML документ, добавить данные в уже существующий HTML документ или сохранить данные в текстовом файле для дальнейшей обработки.

Функция открытия файла выглядит следующим образом:

HANDLE является любым временным именем, который вы будете использовать как идентификатор файла при проведении операций. Как только файл открыт, вы можете писать в него, используя функцию print:

После завершения операций с файлом необходимо его закрыть:

После этого все записанные данные будут сохранены на диск.

Перед осуществлением запись в файл, вы должны убедиться, что web-сервер имеет доступ к директории, в которой находится файл и имеет права на запись в этот файл.

Обратите внимание: функция close должна располагаться как можно ближе к последней функции записи в файл. Это обусловлено тем, что web-сервер выполняется в многопользовательской среде, и скрипт может запускаться одновременно несколькими пользователями. При открытии файла на запись он (файл) блокируется и другие экземпляры скрипта не смогут его открыть, что вызовет задержку в выполнении запроса.

Пример: Создание новой HTML страницы

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

В связи с тем, что мы создаем web-страницу файл содержит тэги HTML вместе с обычным текстом. Помните, что \n просто вставляет перевод строки в текст для удобства последующего просмотра созданного файла.

Все входные данные из формы содержатся в переменных $input. При печати такие переменные должны выноситься за кавычки и отделяться запятыми.

Пример: Добавление в конец файла

Запись в существующий файл проста, когда вы хотите добавить новую информацию в конец файла. Например, для добавления данных о новом пользователе в созданный выше файл вам потребуется следующий скрипт:

Пример: Добавление в середину существующего файла

Более сложной задачей является вставка новых данных в середину файла. Обратите внимание, что в первом примере мы вставили в файл линию комментария, выглядящую следующим образом:

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

Пример: Отправка данных по e-mail

Иногда вам может потребоваться, чтобы данные введенные в форму были посланы по некоторому адресу электронной почты.

Для этого вам потребуется программа посылки почты с интерфейсом командной строки. Под UNIX это может быть sendmail или mail. В данном примере данные посылаются с помощью программы sendmail. Вместо записи в файл мы используем запись в специально открытый канал (pipe):

Обсуждение: Создание web-страниц «на лету»

Последней важной частью Perl скрипта является посылка результата обратно пользователю. Это достигается тем же print, но без идентификатора файла или канала. Все, что печатается на стандартный выход формирует текущий документ в окне браузера. Например:

Обратите внимание на первую строку. Эта строка содержит информацию о типе возвращаемых данных. Двойной перевод стоки при этом обязателен. Эта страница будет возвращена пользователю почти сразу после нажатия им кнопки Submit.

Учтите, что это всего лишь один из многих примеров того, какой может быть страница «на лету». В принципе вы можете формировать HTML документ любой формы и содержания.

Генерация контента сайта с использованием Template Toolkit.

ОПИСАНИЕ

Этот пособие представляет собой введние в Template Toolkit и показывает несколько типичных способов использования этой библиотеки для генерации контента сайта. Пособие описывает генерацию статических страниц с использованием утилит tpage и ttree и динамических страниц с использованием CGI скриптов и обработчиков Apache/mod_perl.

Знакомство, краткое описание и объяснение с использованием примеров различных возможностей Template Toolkit. Дополнительная информация приведена в pod-документации Template, Template::Manual и в подразделах, например


Документация также поставляется в HTML формате (или точнее, в форме HTML шаблонов). Смотрите каталог ‘docs’ пакета для получения дополнительной информации о построении HTML документации.

Если же вы читаете это руководство как часть HTML документации, значит вам не нужно беспокоится об этом. Вы можете присесть, расслабиться и наслаждаться чтением остальной части пособия.

ВВЕДЕНИЕ

Template Toolkit — это набор модулей Perl, который в совокупности реализуют систему по обработке шаблонов. В данном контексте шаблон — это текстовый документ, содержащий специальные разметочные теги, называемые ‘директивами’. Директива это инструкция процессору шаблонов выполнить некоторое действие и заменить директиву в документе на результат этого действия. Директивы используются для определения или вывода значения переменной, выполнения циклических операций с массивами (FOREACH), выполнения условных операций (IF/UNLESS/ELSE), включения и выполнения других шаблонов (INCLUDE) и т.д.

Во всем остальном, документ это обычный текстовый файл и может иметь любое содержимое (например HTML, XML, RTF, LaTeX, и т.п.). Директивы включаются в документ внутри специальных разметочных тегов. По умолчанию, в качестве таких тегов используются [% и %], но они могут быть заменены на другие через опции конфигурации модуля. Пример HTML документа с дополнительными директивами Template Toolkit.

Этот пример показывает как директива INCLUDE используется для загрузки, обработки и включения в текущий документ отдельных шаблонов ‘header’ и ‘footer’. Эти файлы могут выглядеть например так:

Также в примере показано использование директивы FOREACH для построения таблицы ссылок с помощью цикла по массиву ‘webpages’. Мы определяем внутри шаблона массив, содержащий несколько ссылок на хэши, состоящих из двух элементов ‘url’ и ‘title’. Директива FOREACH проходит по массиву, используя ‘link’ в качестве указателя на каждый элемент массива (ссылка на хэш). Затем директивы [% link.url %] и [% link.title %] получают соответсвующие значения хэша и вставляют их в документ.

В следующих разделах показаны другие способы определения данных, которые используются в шаблонах.

ГЕНЕРАЦИЯ СТАТИЧЕСКИХ СТРАНИЦ

Создав шаблон, мы теперь можем обработать его и получить некоторый вывод. Наиболее быстрый и простой способ для этого использование утилиты tpage. Она поставляется как часть библиотеки Template Toolkit и должна быть установлена в каталог с исполняемыми файлами perl.

Если вы сохранили свой шаблон как файл ‘mypage.html’, вам нужно выполнить команду:

Эта команда запустит обработку шаблона, а вывод будет отправлен на STDOUT (т.е. пролетит по вашему экрану). Вы может перенаправить вывод в файл, но будьте осторожны, не указывайте то же имя файла, что и имя шаблона, иначе вы перезапишите его. Вы можете использовать для шаблонов и обычных файлов различные расширения. Например, для шаблонов используйте расширение ‘.atml’ (видимо ‘Another Template Markup Language’?) и привычное ‘.html’ для выходных файлов (преполагается, что вы создаете HTML). Или, вы можете перенаправить вывод в другой каталог, например

Утилита tpage довольно проста и предназначена для того, чтобы дать возможность просто обработать шаблон без необходимости писать perl-код. Более гибкая утилита ttree описанна ниже, но сейчас нам достаточно вывода сгенерированного командой из примера выше (для краткости пустые строки удалены):

Шаблоны header и footer включены (предполагается, что вы их создали и они находятся в текущем каталоге) и данные о ссылках преобразованы в список в HTML-файле.

Утилита ttree, также поставляемая в составе библиотеки Template Toolkit, предоставляет более гибкий способ обработки шаблонов. При первом запуске утилиты, вам будет предложено создать конфигурационный файл, в большинстве случаев называемый ‘.ttreerc’ в вашем домашнем каталоге. Ответьте ‘y’, чтобы создать файл.

Документация по ttree описывает, как вы можете изменить расположение это файла, а также описывает синтаксис и назначение различных опций в этом файле. Конфигурационный файл, приведенный в качестве примера, содержит комментарии, которые также могут помочь.

Коротко говоря, конфигурационный файл описывает каталоги, в которых хранятся шаблоны (src), и куда будут сохраняться соответсвующие файлы (dest), и некоторые другие каталоги (lib), которые могут содержать файлы шаблонов, которые вы планируете включать с помощью директивы INCLUDE в ваши исходные шаблоны. Также в конфигурационном файле можно указать опции парсера (такие как ‘verbose’ и ‘recurse’) и при помощи регулярных выражений ограничить список файлов, которые необходимо обрабатывать парсером (ignore, accept) или указать файлы, которые вместо обработки нужно скопировать (copy).

Пример файла .ttreerc:

Можно создать много других конфигурационных файлов и сохранить их в каталоге, указанном в опции ‘cfg’, как показано выше. Затем вы можете указать команде ttree опцию ‘-f filename’, чтобы использовать файлы из этого каталога.

Когда вы запускаете скрипт, он сравнивает все файлы в каталоге ‘src’ (включая файлы в подкаталогах, если установлена опция ‘recurse’) с файлами в каталоге ‘dest’. Если выходного файла не существует или он имеет более раннее время модификации, чем соответсвующий исходный файл (шаблон), то исходный файл будет обработан парсером и вывод записан в выходной файл. Опция ‘-a’ вынуждает скрипт обработать все файлы вне зависимости от времени модификации.

Скрипт не обрабатывает файлы из каталога ‘lib’, но он включает каталог в переменную INCLUDE_PATH, передаваемую процессору шаблонов для того чтобы он мог определить местонахождение файлов, указываемых в директивах INCLUDE или PROCESS. Таким образом, каталог ‘lib’ — хорошее место для хранения элементов, используемых в шаблонах, таких как header, footer, и т.п., которые не являются документами в полном смысле этого слова.

Также в конфигурационном файле можно указать различные опции Template Toolkit. Для получения подробной информации обратитесь к документации ttree и краткой справке (‘ttree -h’). Например,

Опция ‘pre_process’ позволяет указать шаблон, который будет обработан перед каждым файлом. Неудивительно, что также есть опция ‘post_process’ для добавления шаблона, обрабатываемого после обработки файла. В приведенном выше фрагменте мы указываем, что шаблон ‘config’ будет использован в качестве префиксного шаблона. Мы можем создать этот файл в каталоге ‘lib’ и использовать его для определния некоторых общих переменных, включая определенные ранее ссылки на веб-страницы и которые мы можем захотеть использовать в других шаблонах. Также в этот файл мы можем включить голову и заголовок HTML-документа, или меню, которые затем будут включаться в начало любого шаблона, но пока мы будем использовать для этих целей отдельный файл ‘header’.

Подготовив шаблоны ‘header’ и ‘footer’ из приведенного ранее примера и поместив их в каталог ‘lib’, вы можете начинать создавать в вашем каталоге ‘src’ веб-страницы, подобные приведенной ниже, и обрабатывать их с помощью ttree.

Здесь мы показали, как использовать предопределенные переменные в качестве флагов для включения различных возможностей (например, ‘graphics’) и определять общие переменные, такие как адрес email, URLы домашней страницы, каталога с картинками и т.д. Такой подход позволяет определить эти перемнные один раз, и таким образом поддерживать их целостность на всех страницах и обеспечить возможность легко изменить их значения на новые.

После запуска ttree, вы должны увидеть схожий с приведенным ниже вывод (предполагается, что флаг verbose установлен).

‘+’ перед ‘newpage.html’ показывает что файл был обработан процессором, а вывод сохранен в каталоге назначения. Если вы снова запустите эту команду, вы увидите, что в этой строке вывода вместо ‘+’ будет выведен ‘-‘ и будет приведена причина по которой файл не был обработан процессором.

Процессор обнаружил страницу ‘newpage.html’ в каталоге назначения с датой модификации большей, чем у исходного файла, и не стал тратить время на его повторную обработку. Для того, чтобы принудительно обработать все исходные файлы, используйте опцию ‘-a’. Дополнительно вы можете один или более исходных файлов в качестве аргументов командной строки для утилиты ttree:

Полученный после обработки процессором файл будет выглядет следующим образом.

Вы можете добавить сколько угодно документов в каталог ‘src’ и ttree обработает их аналогично. Таким образом можно полностью построить статическое содержимое сайта с помощью одной команды. Дополнительная выгода заключается в том, что вы можете быть уверены в целостности ссылок, едином стиле шапки и всех прочих компонентов, реализованных через общие шаблоны и переменные.

ДИНАМИЧЕСКАЯ ГЕНЕРАЦИЯ СТРАНИЦ С ПОМОЩЬЮ CGI СКРИПТОВ

Модуль Template обеспечивает простой интерфейс к библиотеке Template Toolkit для использования в CGI-скриптах и обработчиках Apache/mod_perl. Просто включите в ваши скрипты модуль Template с помощью команды ‘use’, создайте экземпляр объекта с помощью метода new(), а затем вызывайте метод объекта process(), передавая в качестве параметра имя файла шаблона. Второй передаваемый параметр — ссылка на хэш с переменными, которые мы хотим сделать доступными в шаблоне:

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

Заметьте, что здесь мы определяем в опции PRE_PROCESS файл ‘config’. Это означает, что шаблоны, которые мы будем обрабатывать могут использовать те же глобальные переменные, которые мы определили раньше для использования в статических страницах. Нам не нужно повторно определять их в скрипте. Тем не менее, мы можем предоставить дополнительные данные и функциональность, специфичную для скрипта через хэш переменных, передаваемый методу process().

Элементы хэша могут содержать обычный текст или другие переменные, ссылки на массивы, другие хэши, функции или объекты. Template Toolkit автоматически применит нужную процедуру для доступа к данным различного типа, когда вы будете использовать переменные в шаблоне.

Приведем более детальный пример для дальнейшего рассмотрения. Среди различных переменных шаблона, определенных в ‘$vars’, мы создали ссылку на объект CGI и ссылку на функцию ‘get_user_projects’.

Ниже приведен пример шаблона, который мы можем использовать в скрипте.

Этот пример показывает как можно разделить perl-реализацию (код) и представление (HTML), что не только делает проще поддержку изоляции, но и позволяет многократно использовать существующие шаблонные элементы, такие как шапки, подвалы и т.п. Используя шаблоны для организации вывода CGI скриптов, вы можете обеспечить такую же целостность, какой мы добились при построении статических страниц с помощью ttree и других средств.

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

ДИНАМИЧЕСКАЯ ГЕНЕРАЦИЯ СТРАНИЦ ЧЕРЕЗ ОБРАБОТЧИК APACHE/MOD_PERL

ВНИМАНИЕ: Вы можете скачать из сети CPAN модуль Apache::Template, который обеспечивает простой и легкий в использовании интерфейс между Apache/mod_perl и Template Toolkit. В момент написания этого документа был доступен первый релиз (0.01), который предлагает только самые базовые возможности, но в нем реализована большая часть, если не все, что описано ниже. Следует избегать необходимости писать свой собственный обработчик. Тем не менее, во многих случаях, вам может понадобиться написать свой собственный обработчик под ваши собственные нужды, и этот раздел покажет вам с чего начинать.

Модуль Template можно использовать обычным способом из обработчика Apache/mod_perl. Ниже приведен типичный фрагмент файла конфигурации Apache httpd.conf:

Этот фрагмент определяет URL ‘/user/bin’, все запросы к которому будут передаваться методу handler() модуля MyOrg::Apache::User. Этот модуль может выглядеть приблизительно так:

Обработчик получает в качестве параметра запрос и использует его для определения значения ‘websrc_root’ из файла конфигурации. Это значение затем используется для определения INCLUDE_PATH при создании объекта Template. Далее из запроса получаем URI и создаем объект CGI. Оба объекта определяются как переменные шаблона.

Само имя шаблона извлекается из PATH_INFO запроса. В нашем примере, оно будет частью URL, идущего после ‘/user/bin’, то есть для ‘/user/bin/edit’, шаблоном будет файл ‘edit’, расположенный в «$websrc/src/user» Далее выводим заголовки и обрабатываем шаблон. Весь вывод отправляется напрямую в метод print() объекта запроса Apache.

ИСПОЛЬЗОВАНИЕ МОДУЛЕЙ-РАСШИРЕНИЙ (ПЛАГИНОВ)

Как мы уже показали, при создании динамического контента с помощью CGI скриптов или обработчиков Apache/mod_perl можно связывать данные и функции из Perl с переменными шаблона. Template Toolkit также предоставляет интерфейс для создания модулей расширений (плагинов), который позволяет вам определить эти дополнительные данные и/или функциональность в отдельном модуле и затем загрузить его и использовать по назначению с помощью директивы USE.

Основное преимущество такого подхода заключается в том, что вы можете использовать такое расширение в любых шаблонах, даже в тех, которые используются при построении статического контента с помощью tpage или ttree. Вам не нужно специально писать обертку на Perl только для того, чтобы загрузить модуль и сделать его доступным через хэш переменных шаблона.

Давайте продемонстрируем этот принцип на примере плагина DBI, написанного Симоном Мэттьюсом (Simon Matthews ). Вы можете создать этот шаблон в вашем каталоге ‘src’, обработать его при помощи ttree и посмотреть результат. Разумеется, этот пример зависит от наличия подходящей базы данных SQL, но вы можете адаптировать его под ваши возможности, либо просто рассматривать как пример возможностей Template Toolkit.

Плагин — это обычный Perl модуль, расположенный в определенном месте и согласующийся с известными стандартами таким образом, чтобы Template Toolkit смог найти его и автоматически загрузить. Вы можете создать свой собственный плагин с помощью наследования модуля Template::Plugin.

Ниже приведен пример, который определяет некоторые данные (‘foo’ и ‘people’) и также метод объекта (‘bar’). За неимением лучшего мы назовем плагин ‘FooBar’ и создадим его в пакете ‘MyOrg::Template::Plugin::FooBar’. Мы добавили ‘MyOrg’ к обычному имени пакета ‘Template::Plugin::*’, чтобы избежать конфликта имен с существующими плагинами.

Заготовку модуля можно сделать с помощью Perl утилиты h2xs:

Эта команда создаст структуру каталогов, отражающую имя пакета с набором файлов, составляющих ваш новый модуль. Вы можете отредактировать FooBar.pm, чтобы он выглядел примерно так:

Как принято в Perl, конструктор плагина new() получает имя класса в качестве первого параметра. Следующий параметр — ссылка на экземпляр объекта Template::Context. Сейчас вам не нужно беспокоится об этом объекте. Это основной объект парсера Template Toolkit. Он предоставляет доступ к функциональности процессора и некоторым плагинам может понадобится взаимодествовать с ним. Нам это пока не нужно, но мы тем не менее сохраним эту ссылку в переменной объекта ‘_CONTEXT’. Начальное подчеркивание — это соглашение об именах переменных, которое указывает что эта переменная приватная и Template Toolkit не будет пытаться получить доступ к этой переменной. Другие определяемые переменные ‘foo’ и ‘people’ — это обычные данные, которые будут доступны из шаблонов, использующих этот плагин. Следом за ссылкой на объект Template::Context идут дополнительные параметры, которые указываются с директивой USE, такие как источник данных, ‘dbi:mSQL:mydbname’, который мы использовали в предыдущем примере с плагином DBI.

Если для создания заготовки модуля вы использовали h2xs, то у вас уже есть файл Makefile.PL и вы можете выполнить знакомую процедуру по сборке и установке модуля. Не забудьте добавить тесты в test.pl!

Если вы не стали или не смогли установить плагин в обычное место для хранения модулей Perl (например, если у вас недостаточно привилегий), вы можете установить переменную окружения PERL5LIB, чтобы указать другое место, где установлен модуль. Если вы используете ttree, вместо этого вы можете добавить следующую строку в ваш конфигурационный файл. Это будет равносильно добавлению ‘/path/to/modules’ в массив @INC.

Еще одна дополнительная строка должна быть добавлена, чтобы указать парсеру новое имя пакетов, которое мы создали для наших плагинов:

Если вы пишите скрипт, использующий модуль Template напрямую, эта переменная может быть передана как параметр конфигурации при создании объекта.

Теперь мы можем создать шаблон, использующий этот плагин:

Члены ‘foo’, ‘bar’ и ‘people’ из плагина FooBar автоматически преобразуются в соответствующие переменные или вызовы методов лежащего в основе объекта.

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

Мастер Йода рекомендует:  Создание выпадающего меню с помощью MySQL, PHP и JavaScript
Добавить комментарий