DataparkSearch Engine 4.53: Справочное руководство
Пред. | Глава 8. Поиск документов | След.

# 8.3. Как создавать шаблоны результатов поиска

Пользователи DataparkSearch имеют возможность настраивать вывод результатов поиска (вывод `search.cgi` ). Эта настройка находится в файле `search.htm`, располагаемым в поддиректории `/etc/` относительно корневой директории установки DataparkSearch.

Файл шаблона это обычный HTML файл, разделённый на секции.

> Замечание: Каждая строка шаблона не должна превышать 1024 байт.

Каждая секци начинается с разделителя <!--sectionname--> и заканчивается разделителем <!--/sectionname-->, оба разделителя должны находится на отдельной строке, в её начале.

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

Формат переменных шаблона следующий:

    $(x) - значение
    $&(x) - значение с HTML-кодировкой недопустимых символов и выделением слов из запроса.
    $*(x) - значение с HTML-кодировкой недопустимых символов.
    $%(x) - значение с URL-кодированием запрещенных символов.
    $^(x) - значение с выделением слов из поискового запроса.
    $(x:128) - значение усекается до 128 байт, если оно длиннее.
    $(x:UTF-8) - значение записывается в кодировке UTF-8. Можно указывать любую поддерживаемую кодировку.
    $(x:128:right) - значение усекается слева до 128 байт, если оно длиннее.

## 8.3.1. Секции шаблона

Определены следующие секции шаблонов: TOP>, BOTTOM>, RESTOP>, RES>, CLONE>, RESBOT>, navleft, navleft_nop>, navbar0>, navright, navright_nop>, navbar1>, notfound>, noquery>, error>, variables>.

### 8.3.1.1. Секция TOP

Эта секция всегда вставляется первой на каждой странице ответов. Вы должны начинать эту секцию с <HTML><HEAD> и т.д. Также это подходящее место для размещения формы поиска. В этой секции вы можете использовать некоторые метасимволы (переменные шаблона):

    $(self)     - аргумент атрибута ACTION тэга FORM
    $(q)        - запрос на поиск
    $(cat)      - текущее значение категории
    $(tag)      - текущее значение тэга
    $(rN)       - случайное число (здесь N - число)

Если вы хотите разместить на ваших страницах некоторые банеры случайным образом, используйте `$(rN)`. Вы также должны поместить строчку типа `RN xxxx` в секции 'variables' (см. Разд. 8.3.2>), что даст вам для $(rN) значение из диапазона 0..xxxx. Вы можете использовать столько случайных переменных, сколько вам нужно.

Например: `$(r0), $(r1), $(r45)` и т.д.

Простая секция top может быть примерно такой:

    <!--top-->
    <HTML>
    <HEAD>
     <TITLE>Search query: $(q)</TITLE>
    </HEAD>
    <BODY>

    <FORM METHOD=GET ACTION="$(self)">
     <INPUT TYPE="hidden" NAME="ul" VALUE="">
     <INPUT TYPE="hidden" NAME="ps" VALUE="20">
     Search for: <INPUT TYPE="text" NAME="q" SIZE=30
     VALUE="$&(q)">
     <INPUT TYPE="submit" VALUE="Search!"><BR>
    </FORM>
    <!--/top-->

Существует несколько переменных, указываемых в форме для установки различных параметров поиска. См. также Разд. 8.1.2>.

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

    <SELECT NAME="lang">
    <OPTION VALUE="en" SELECTED="$(lang)">English
    .....
    </SELECT>

`ul` задаёт фильтр по URL. Позволяет вам ограничить поиск одним сайтом или какой-то его части, и т.д. Например, вы можете добавить следующий код в вашу форму

    Search through:
    <SELECT NAME="ul">
    <OPTION VALUE=""            SELECTED="$(ul)">Entire site
    <OPTION VALUE="/manual/"    SELECTED="$(ul)">Manual
    <OPTION VALUE="/products/"  SELECTED="$(ul)">Products
    <OPTION VALUE="/support/"   SELECTED="$(ul)">Support
    </SELECT>

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

Выражение `SELECTED="$(ul)"` в примере выше (и во всехпримерах ниже) позволяет сохранять выбранным значение той или иной опции поиска на следующих страницах результатов. Если поисковый фронтэнд находит такое выражение, он выводит строку `SELECTED` только для того варианта `OPTION`, значение которого равно значению соответсвующей переменной.

`pn` равно ps*np. Эта переменная не используется DataparkSearch, но может быть полезна, например, в директиве <!INCLUDE CONTENT="..."> если вы хотите включить результаты поиска другой поисковой системы.

В этом примере формы помогается выбрать различные ограничения по времени.

    <!-- 'search with time limits' options -->
    <TR><TD>
    <TABLE CELLPADDING=2 CELLSPACING=0 BORDER=0>
    <CAPTION>
    Limit results to pages published within
    a specified period of time.<BR>
    <FONT SIZE=-1><I>(Please select only one option)
    </I></FONT>
    </CAPTION>
    <TR>
    <TD VALIGN=center><INPUT TYPE=radio NAME="dt"
    VALUE="back" CHECKED></TD>
    <TD><SELECT NAME="dp">
    <OPTION VALUE="0" SELECTED="$(dp)">anytime
    <OPTION VALUE="10M" SELECTED="$(dp)">in the last ten minutes
    <OPTION VALUE="1h" SELECTED="$(dp)">in the last hour
    <OPTION VALUE="7d" SELECTED="$(dp)">in the last week
    <OPTION VALUE="14d" SELECTED="$(dp)">in the last 2 weeks
    <OPTION VALUE="1m" SELECTED="$(dp)">in the last month
    <OPTION VALUE="3m" SELECTED="$(dp)">in the last 3 months
    <OPTION VALUE="6m" SELECTED="$(dp)">in the last 6 months
    <OPTION VALUE="1y" SELECTED="$(dp)">in the last year
    <OPTION VALUE="2y" SELECTED="$(dp)">in the last 2 years
    </SELECT>
    </TD>
    </TR>
    <TR>
    <TD VALIGN=center><INPUT type=radio NAME="dt" VALUE="er">
    </TD>
    <TD><SELECT NAME="dx">
    <OPTION VALUE="1" SELECTED="$(dx)">After
    <OPTION VALUE="-1" SELECTED="$(dx)">Before
    </SELECT>

или так

    <SELECT NAME="dm">
    <OPTION VALUE="0" SELECTED="$(dm)">January
    <OPTION VALUE="1" SELECTED="$(dm)">February
    <OPTION VALUE="2" SELECTED="$(dm)">March
    <OPTION VALUE="3" SELECTED="$(dm)">April
    <OPTION VALUE="4" SELECTED="$(dm)">May
    <OPTION VALUE="5" SELECTED="$(dm)">June
    <OPTION VALUE="6" SELECTED="$(dm)">July
    <OPTION VALUE="7" SELECTED="$(dm)">August
    <OPTION VALUE="8" SELECTED="$(dm)">September
    <OPTION VALUE="9" SELECTED="$(dm)">October
    <OPTION VALUE="10" SELECTED="$(dm)">November
    <OPTION VALUE="11" SELECTED="$(dm)">December
    </SELECT>
    <INPUT TYPE=text NAME="dd" VALUE="$(dd)" SIZE=2 maxlength=2>
    ,
    <SELECT NAME="dy" >
    <OPTION VALUE="1990" SELECTED="$(dy)">1990
    <OPTION VALUE="1991" SELECTED="$(dy)">1991
    <OPTION VALUE="1992" SELECTED="$(dy)">1992
    <OPTION VALUE="1993" SELECTED="$(dy)">1993
    <OPTION VALUE="1994" SELECTED="$(dy)">1994
    <OPTION VALUE="1995" SELECTED="$(dy)">1995
    <OPTION VALUE="1996" SELECTED="$(dy)">1996
    <OPTION VALUE="1997" SELECTED="$(dy)">1997
    <OPTION VALUE="1998" SELECTED="$(dy)">1998
    <OPTION VALUE="1999" SELECTED="$(dy)">1999
    <OPTION VALUE="2000" SELECTED="$(dy)">2000
    <OPTION VALUE="2001" SELECTED="$(dy)">2001
    </SELECT>
    </TD>
    </TR>
    </TR>
    <TD VALIGN=center><INPUT TYPE=radio NAME="dt" VALUE="range">
    </TD>
    <TD>
    Between
    <INPUT TYPE=text NAME="db" VALUE="$(db)" SIZE=11 MAXLENGTH=11>
    and
    <INPUT TYPE=text NAME="de" VALUE="$(de)" SIZE=11 MAXLENGTH=11>
    </TD>
    </TR>
    </TABLE>
    </TD></TR>
    <!-- end of stl options -->

### 8.3.1.2. Секция BOTTOM

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

Ниже дан пример секции `bottom`:

    <!--bottom-->
    <P>
    <HR>
    <DIV ALIGN=right>
    <A HREF="http://www.maxime.net.ru/">
    <IMG SRC="dpsearch.gif" BORDER=0
    ALT="[Powered by DataparkSearch search engine software]">
    </A>
    </BODY>
    </HTML>
    <!--/bottom-->

### 8.3.1.3. Секция RESTOP

Эта секция вставляется непосредственно перед результатами поиска. Служит местом указания общих параметров результата поиска. Вы можете использовать для этого слудующие метасимволы (переменные):

- `$(first)` - номер первого документа, отображаемого на этой странице

- `$(last)` - номер последнего документа, отображаемого на этой странице

- `$(total)` - общее число документов найденых документов

- `$(grand_total)` - общее число документов найденых документов до группировки по сайтам

- `$(WE)` - результат поиска со всей статистикой по каждой словоформе поискового запроса

- `$(W)` - результат поиска со статистикой по словам запроса, указывается двумя числами, разделёнными знаком '/'. Первое число указывает число найденых вхождений слова из запроса, второе - число всех найденых словоформ этого слова. Например, `test: 25/73` обозначает, что слово "test" найдено 25 раз, а число всех его словоформ ("test", "tests", "testing", и т.д..) - 73.

- `$(WS)` - результат поиска в короткой форме с отображением числа всех словоформ каждого слова запроса.

- `$(SearchTime)` - время выполения поискового запроса.

- `$(ndocs)` - число документов в базе. Внимание: для больших баз данных это потребует больших ресурсов.

Ниже дан пример секции `restop`:

    <!--restop-->
    <TABLE BORDER=0 WIDTH=100%>
    <TR>
    <TD>Search<BR>results:</TD>
    <TD><small>$(WE)</small></TD>
    <TD><small>$(W)</small></TD>
    </TR>
    </TABLE>
    <HR>
    <CENTER>
    Displaying documents $(first)-$(last) of total <B>$(total)</B> found.
    </CENTER>
    <!--/restop-->

### 8.3.1.4. Секция RES

Эта секция используется для вывода разнообразной информации о каждом найденном документе. Могут использоваться слудующие метасимволы (переменные):

- $(URL) URL документа

- $(Title) Заголовок документа

- $(Score) Рейтинг документа (как он вычислен DataparkSearch

- $(Body) Текст документа, первые несколько строк, или цитаты из документа по словам запроса, если используется stored, чтобы дать представление о содержимом документа.

- $(Content-Type) Content-type документа (например, text/html)

- $(Last-Modified) Дата последней модификации документа

- $(Content-Length) Размер документа в байтах

- $(FancySize) Размер документа в байтах, килобайтах или мегабайтах, что больше подходит

- $(Order) Общий номер документа (в порядке показа результатов поиска), т.е. от 1 до $(total).

- $(Pos) Новер документа на странице (в порядке показа результатов поиска), т.е. от 1 до $(ps).

- $(meta.description) Описание документа (из тэга META DESCRIPTION)

- $(meta.keywords) Ключевые слова документа (из тэга META KEYWORDS)

- $(DY) Категория документа с путём, т.е. `/home/computers/software/www/`

- $(CL) Лист клонов (см. подробности в Разд. 8.3.1.5>)

- $(BrowserCharset) Кодировка, используемая для вывода результатов поиска

- $(PerSite) При использовании группировки по сайту, число суммарное число документов с сайта найденного документа. Иначе, значение равно 0.

> Замечание: Возможно указывать максимальное сичло символов, возвращаемых любой из описаных выше переменной. Например, `$(URL)` может возвращать длинный URL, который может разрушать табличный вывод результатов. Для указания максимального числа выводимых символов в отображаемом URL, используйте `$(URL:xx)`, где `xx` - максимальное число символов: `$(URL:40)` вернёт URL, и если он окажется длиннее 40 символов, только превые 40 символов будут показаны на странице результатов поиска: `http://very.long.url/path/veery/long/...`

Ниже пример секции `res`:

    <!--res-->
    <DL><DT>
    <b>$(Order).</b><a href="$(URL)" TARGET="_blank">
    <b>$(Title)</b></a> [<b>$(Score)</b>]<DD>
    $(Body)...<BR>
    <b>URL: </b>
    <A HREF="$(URL)" TARGET="_blank">$(URL)</A>($(Content-Type))<BR>
    $(Last-Modified), $(Content-Length) bytes<BR>
    <b>Description: </b>$(meta.description)<br>
    <b>Keywords: </b>$(meta.keywords)<br>
    </DL>
    <UL>
    $(CL)
    </UL>
    <!--/res-->

### 8.3.1.5. Секция CLONE

Содержимое этой секции включается в результат поиска вместо метасимвола $(CL) для каждого найденного клона документа. Служит для указания всех URL с одним и тем же содержимым (как зеркала и т.п.). Вы можете использовать те же мета символы, что и в секции `res`.

Ниже пример секции `clone`.

    <!--clone-->
    <li><A HREF="$(DU)" TARGET="_blank">$(DU)</A> ($(DC)) $(DM)
    <!--/clone-->

### 8.3.1.6. Секция RESBOT

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

Вот пример секции `resbot`:

    <!--resbot-->
    <HR>
    <CENTER>
    Result pages: $(NL)$(NB)$(NR)
    </CENTER>
    <!--/resbot-->

Навигация - сложная штука, создаваемая из следующих секций шаблона: navleft, navleft_nop>, navbar0>, navright, navright_nop>, navbar1>.

### 8.3.1.7. Секция navleft, navleft_nop

Используются для образования ссылки на предыдущую страницу. Если предыдущая страница существует, исаользуется <!--navleft-->, если нет (на первой странице) - используется <!--navleft_nop-->.

    <!--navleft-->
    <TD><A HREF="$(NH)"><IMG...></A><BR>
    <A HREF="$(NH)">Prev</A></TD>
    <!--/navleft-->

    <!--navleft_nop-->
    <TD><IMG...><BR>
    <FONT COLOR=gray>Prev</FONT></TD>
    <!--/navleft_nop-->

### 8.3.1.8. Секция navbar0

Используется для печати текущей страницы в списе страниц.

    <!--navbar0-->
    <TD><IMG...><BR>$(NP)</TD>
    <!--navbar0-->

### 8.3.1.9. Секции navright, navright_nop section

Эти секции используются для печати ссылки на следующую страницу. Если следующая страница существует, используется секция <!--navright-->, на последней странице используется <!--navright_nop-->.

    <!--navright-->
    <TD>
    <A HREF="$(NH)"><IMG...></A>
    <BR>
    <A HREF="$(NH)">Next</A></TD>
    <!--/navright-->

    <!--navright_nop-->
    <TD>
    <IMG...>
    <BR>
    <FONT COLOR=gray>Next</FONT></TD>
    <!--/navright_nop-->

### 8.3.1.10. Секция navbar1

Используется для печати ссылок на другие страницы списка страниц результата поиска.

    <!--navbar1-->
    <TD>
    <A HREF="$(HR)">
    <IMG...></A><BR>
    <A HREF="$(NH)">$(NP)</A>
    </TD>
    <!--/navbar1-->

### 8.3.1.11. Секция notfound

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

Ниже пример секции `notfound`:

    <!--notfound-->
    <CENTER>
    Sorry, but search hasn't returned results.<P>
    <I>Try to compose less restrictive search query or check spelling.</I>
    </CENTER>
    <HR>
    <!--/notfound-->

### 8.3.1.12. Секция noquery

Эта секция выводится если пользователь выдал пустой запрос на поиск.. Ниже приводится пример этой секции:

    <!--noquery-->
    <CENTER>
    You haven't typed any word(s) to search for.
    </CENTER>
    <HR>
    <!--/noquery-->

### 8.3.1.13. Секция error

Эта секция выводится только при обнаружении ошибок во время поиска. Например, если не запущен SQL сервер и т.п. Вы можете использовать следующий метасимвол (переменную): `$(E)` - текст сообщения об ошибке.

Пример секции `error`:

    <!--error-->
    <CENTER>
    <FONT COLOR="#FF0000">An error occured!</FONT>
    <P>
    <B>$(E)</B>
    </CENTER>
    <!--/error-->

## 8.3.2. Секция Variables

В специальной секции `variables` вы можеде задать значения некоторых переменных и параметров поиска.

Секция `variables` обычно выглядит примерно так:

    <!--variables
    DBAddr		  mysql://foo:bar@localhost/search/?dbmode=single
    VarDir            /usr/local/dpsearch/var/
    LocalCharset	  iso-8859-1
    BrowserCharset    iso-8859-1
    TrackQuery	  no
    Cache		  no
    DetectClones	  yes
    HlBeg		  <font color="blue"><b><i>
    HlEnd		  </i></b>
    R1		  100
    R2		  256
    Synonym		  synonym/english.syn
    ResultContentType text/xml
    Locale            ru_Ru.KOI8-R
    -->

> Замечание: Так же как и в `indexer.conf`, имя хоста в DBAddr имеет значение только для поддерживаемых баз данных и не играет никакой роли при использовании ODBC баз данных. В случае ODBC, используйте имя базы в DBAddr для указания ODBC DSN.

Команда VarDir задаёт альтернвтивный путь рабочей директории при использовании способа хранения cache. По умолчанию используется поддиректория `/var` относительно корневой директории установки DataparkSearch.

Команда LocalCharset указывает кодировку локальной базы данных. Должна совпадать с кодировкой, заданной этой же командой в `indexer.conf`.

Команда BrowserCharset указывает, какая кодировка используется для вывода результатов поиска. Она может отличаться от значения, указанного в LocalCharset. Значения всех метасимволов (переменных) при выводе будут перекодированы в эту кодировку, однако сам шаблон не перекодируется, он уже должен быть в этой кодировке.

Используйте "Cache yes/no" для включения/выключения кэширования результатов поиска.

Используйте "DetectClones yes/no" для включения/выключения определения клонов.

Используйте "GroupBySite yes/no" для включения/выключения группировки результатов по url.site_id.

> Замечание: Если используется `searchd`, вы должны указывать GroupBySite в вашем файле `searchd.conf`, или передавать его как CGI параметр.

> Если используется способ хранения cache, необходимо также создать лимит по сайту (см. Разд. 5.2.8>).

> Используйте команду PagesInGroup для указания числа дополнительных результатов с одного сайта при группировке результатов а-ля Google.

> Вы можете использовать команду MaxSiteLevel для задания максимального уровня доменного имени, используемого для расчёта site_id. Значение по умолчанию: 2. Одно исключение: трёх и менее буквенные домены второго уровня считаются доменами первого уровня. Например: domain.ext - уровень 2, www.domain.ext - уровень 3, domain.com.ext - уровень 2. Отрицательное значение для MaxSiteLevel означает группировку на уровне поддиректорий, т.е. при уровне -1 www.site.ru/dir1/ и www.site.ru/dir2/ группируются как разные сайты.

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

Команда Alias в `search.htm` похожа на одноимённую команду в `indexer.conf`, но имеет действие на отображение результатов поиска, а не при индексировании. См. детали в Разд. 3.7>.

Команды R1 и R2 задают диапазон значений для переменных шаблона $(R1) и $(R2).

Команда Synonym используется для загрузки указанного списка синонимов. Имя файла синонимов может быть и абсолютным и относительно поддиректории `/etc` коренвой директории установки DataparkSearch.

Команда DateFormat служит для изменения формата вывода даты последней модификации файла. При задании своего формата, используйте метапеременные функции `strftime`.

> Замечание: Если используется `searchd`, вы можете указывать DateFormat в вашем файле `searchd.conf` (отличие состоит в необходимости заключать строку фомата в кавычки `"`), или передавать как CGI параметр.

Команда "Log2stderr yes/no" предписывает выводить все сообщения об ошибках на `stderr`.

Команда ResultsLimit может быть использована для ограничения максимального числа выводимых результатов поиска. При использовании searchd, эта команда может быть указана в файле конфигурации `searchd.conf`.

Команда ResultContentType используется для указания заголовка Content-Type страницы с результатами. Значение по умолчанию: `text/html`.

Команда Locale используется для указания заголовка для задания LC_ALL локали при выдаче результатов поиска. Значение по умолчанию: `не определено` (используется установленное ранее значение).

При помощи команды MakePrefixes yes вы можете автоматически расширять поисковый запрос префиксами слов запроса. В частности, это можно использовать при организации подсказок при поиске. (См. также Разд. 3.10.60>)

## 8.3.3. Включения в шаблонах

Вы можете использовать <!INCLUDE Content="http://hostname/path"> дял включения внешних URLs в страницу результатов поиска.

ВНИМАНИЕ: Вы можете использовать <!INCLUDE> ТОЛЬКО в следующих секциях шаблона:

<!--top-->
<!--bottom-->
<!--restop-->
<!--resbot-->
<!--notfound-->
<!--error-->

Это пример использования включения:

    <!--top-->
    ....
    <!INCLUDE CONTENT="http://hostname/banner?query=$&(q)">
    ...
    <!--/top-->

## 8.3.4. Условные операторы в шаблонах

DataparkSearch поддерживет в шаблонах условные операторы: <!IF, <!ELSE, <!ENDIF, <!ELIF, <!ELSEIF, <!SET, <!COPY, <!IFLIKE, <!IFREGEX, <!ELIKE, <!EREGEX, <!ELSELIKE, <!ELSEREGEX.

    <!IF   NAME="Content-Type" Content="application/pdf">
    <img src="pdf.png">
    <!ELIF NAME="Content-Type" Content="text/plain">
    <img src="text.png">
    <!ENDIF>

Возможно использовать вложенные конструкции условных операторов. Это обеспечивает большую гибкость при написании шаблонов результатов поиска. Смотрите примеры использования в файле `etc/search.htm-dist`.

## 8.3.5. О безопасности

ВНИМАНИЕ: Так как файл шаблона содержит такую информацию как пароль, во избежание утечки этого пароля, рекомендуется проверить права доступа к нему, чтобы обеспечить право чтения только для программы поиска.

Пред. | Начало | След.
Модуль `mod_dpsearch` для Apache httpd | Уровень выше | Дизайн search.html