# Как создавать шаблоны результатов поиска
DataparkSearch - Полнофункциональная поисковая машина для Интернета и Интранета с открытым исходным кодом. Распространяется по лицензии GNU.
Keywords: shareware, freeware, интернет, unix, поисковик, поисковая машина, поиск, поиск информации, интранет, open source, opensource, search, searching, software, udmsearch, engine, indexing, system, web, ftp, http, cgi, php, SQL, MySQL, database, php3, FreeBSD, Linux, Unix, DataparkSearch, MacOS X, Mac OS X, Windows, 2000, NT, 95, 98, GNU, GPL, url, grabbing

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