# FLUIdS
Профильные файлы

- Структура профильного файла
- Директивы конфигурационного файла
- Формы вывода значений переменных
- Параметрические переменные
- Переменные профильных файлов (для всех видов профильных файлов)
- Переменные профильных файлов (для представления бланка запроса)
- Переменные профильных файлов (для представления результатов поиска)
- Иконки
- Операторы
- Тестовые профильные файлы
- Стандартное представление бланка запроса
- Стандартное представление результатов поиска
- Примеры использования профильных файлов

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

| Структура профильного файла |

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

- Последовательность символов вида $NAME (т.е. знак доллара с последующим известным системе именем NAME) будет заменена в нем на другую, отвечающую этому имени и зависящую от текущего состояния системы. Такую последовательность символов в дальнейшем будем называть переменной профильного файла с именем NAME, а ее замену - значением этой переменной. Если после знака доллара стоит неизвестное системе имя, то замены не происходит.
- В нем действует правило экранирования, которое осуществляется с помощью символа "обратный слэш".
- Его размер ограничен 4095 байтами. Даже если физический размер профильного файла на диске превышает эту величину, то все равно, из него будет считано только первые четыре килобайта текста.

Кроме обычных переменных (которые задаются знаком доллара и соответствующим именем) в профильных файлах возможны еше параметрические переменные, значение которых зависит от некоторого параметра, указываемого в фигурных скобках после имени переменной: $name{parameter}, и операторы. Имена обычных переменных задаются в верхнем регистре букв, тогда как параметрических - в нижнем. Это сделано для более четкого разделения этих двух видов переменных.

| Директивы конфигурационного файла |

Сгенерированная CGI модулем страница результатов поиска (здесь мы выпустим из рассмотрения ее заголовок с логотипом FLUIdS и бланк запроса, выдаваемый в конце) может быть схематически представлена следующим образом:

код HTML, начинающий список результатов
код HTML, с данными о найденной ссылке #1
`* * *`
код HTML, с данными о найденной ссылке #n
код HTML, завершающий список результатов

Стартовый код HTML может содержать информацию о пользовательском запросе, времени поиска и т.д. Завершающий - ссылки на другие страницы результатов (если они есть). Данные о каждой найденной ссылке выдаются единообразно, и они ни в коем образом не интерферируют с информацией, отображаемой в стартовом и завершающем коде HTML. Поэтому в FLUIdS для представления результатов поиска используются два вида профильных файлов с различными наборами переменных: один для начала и завершения списка результатов, другой - непосредственно для вывода данных о каждой найденной ссылке:

стартовый профильный файл
профильный файл результата поиска для ссылки #1
`* * *`
профильный файл результата поиска для ссылки #n
завершающий профильный файл

где стартовый и завершающий профильные файлы имеют один набор переменных, а профильный файл результата - другой.

Таким образом, для отображения результатов поиска применяются три профильных файла (стартовый / результативный / завершающий) с двумя различными наборами переменных. Соответственно, в конфигурационном файле CGI модуля предусмотрено три различных директивы, задаваемых в разделе [templates], которые и определяют три вышеозначенных профильных файла:

- BeginResulFile
- MatchResultFile
- EndResultFile

где в имени директивы слово Begin означает стартовый профильный файл, Match - результативный, а End - завершающий. Пример написания директив:

    [templates]
    BeginResultFile = begin.tpl
    MatchResultFile = match.tpl
    EndResultFile = end.tpl

Чтобы задать имя профильного файла для представления бланка запроса, необходимо воспользоваться директивой QueryFormFile, прописываемой в этом же конфигурационном разделе:

    [templates]
    QueryFormFile = form.tpl

Для профильного файла бланка запроса определен свой набор переменных.

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

FormHeaderFile и FormFooterFile
  профильные файлы, включаемые в текст сгенерированной CGI модулем страницы с бланком запроса (FormHeaderFile - перед бланком запроса, а FormFooterFile - после оного).

SearchHeaderFile и SearchFooterFile
  профильные файлы, включаемые в текст сгенерированной CGI модулем страницы с результатами поиска (SearchHeaderFile - перед списком результатов поиска, а SearchFooterFile - после него).

TopContentFile и BottomContentFile
  профильные файлы, включаемые в текст сгенерированных CGI модулем страничек (TopContentFile - сразу после тега
  , а BottomContentFile - непосредственно перед тегом
  ). Они совершенно одинаковы для страниц с бланком запроса и с результатами поиска.

  Замечания:
  - Для того, чтобы пользоваться профильными файлами, необходимо в достаточной степени знать HTML - язык гипертекста, а также ознакомиться с аргументами вызова CGI модуля.
  - В конфигурационном разделе [templates] определена еще одна директива - icon, описание которой приводится ниже.

| Формы вывода значений переменных |

При выводе значений той или иной переменной профильного файла требуется некоторая аккуратность, поскольку вывод осуществляется в гипертекстовой среде, для которой часть символов является управляющими. Поэтому вывод возможен как с заменой управляющих символов (на их символические эквиваленты), так и без оного. Помимо этого, существуют атрибуты некоторых тегов, которые требуют для своих значений применения специализированного механизма экранирования, когда символ текста заменяется на `%` с последующим указанием его шестнадцатиричного номера (как, например, для HREF тегов A, IMG, MAP и т.д.) Все это многообразие и обуславливает множественность форм вывода значений переменных профильных файлов:

Условное название формы вывода | Описание
html | вывод осуществляется в формате HTML, т.е. значением переменной является кусок гипертекста.
text | вывод производится в текстовом виде, для которого характерна замена управляющих символов гипертекста `<`, `>`, `&` и `"` на `&lt;`, `&gt;`, `&amp;` и `&#34;` соответственно. Переменные этой формы можно использовать в качестве значений для атрибутов ALT тега IMG, VALUE тега INPUT и т.д.
escaped | вывод осуществляется в виде, пригодном для организации ссылок (т.е. здесь применяется вышеупомянутый механизм экранирования).
asis | переменная выдается безо всяких изменений. Такая форма, например, применяется для вывода интернетовского адреса найденной ссылки, так как считается, что в индексном файле (откуда и извлекается этот адрес) хранятся готовые к выводу адреса документов.

  Необходимо отметить, что для форм вывода html, text и escaped дополнительно осуществляется перекодировка русских букв.

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

| Параметрические переменные |

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

  `$name{parameter:modificator}`

Здесь:

- name - имя параметрической переменной;
- parameter - ее параметр;
- modificator - модификатор для параметра. Его можно было бы назвать вторым параметром, если бы не тот факт, что он может отсутствовать в записи переменной.

Для каждой параметрической переменной заданы свои параметры и модификаторы.

Во всех видах профильных файлов, т.е. используемых как для представления результатов поиска, так и для представления бланка запроса, определяются две параметрические переменные с именами env, color и sflag. Кроме того, в профильных файлах представления результатов поиска задается переменная ending, а в профильном файле бланка запроса - переменные checked и selected.

- Переменная $env{name}
  В качестве значения этой переменной профильного файла используется значение переменной окружения текущего процесса с именем name.

  Так, например, согласно спецификации CGI, Web сервер устанавливает для исполняемых модулей несколько переменных окружения, в числе которых есть переменная окружения с именем SCRIPT_NAME. Ее значение - расположение вызываемого CGI модуля относительно файловой системы сервера; т.е. запросив у Web сервера страницу с URL http://www.server.ru/search/fluids.cgi получим значение для $env{SCRIPT_NAME} как /search/fluids.cgi. Значит, данную переменную можно использовать при формировании HTML формы запроса:

    `<form method="get" action="$env{SCRIPT_NAME}">`

  Для переменной $env определяется только один модификатор с именем escaped. При использовании этого модификатора значение $env выводится в виде, годном для формирования ссылок (т.е. все специальные символы в нем - пробел, знак вопроса, амперсанд и т.д. - заменяются их escape-эквивалентами).

  Строго говоря, в выше приведенном примере должен был фигурировать модификатор escaped: $env{SCRIPT_NAME:escaped}, так как в относительном имени CGI модуля могут присутствовать специальные символы.

- Переменная $color{name}
  Этой переменной отвечает значение цвета, которое можно установить в конфигурационном файле CGI модуля в разделе colors. Здесь name - имя как раз той директивы конфигурационного файла, которая и ответственна за назначение этого цвета. Например: $color{IndexListHeader}.

  Если переменная используется без модификатора ее параметра, то выдается значение цвета в шестнадцатиричном виде (без предварительного `#`, для неопределенного цвета выводится `-1`).

  Для переменной $color определены следующие модификаторы:

  start
    для определенных цветов выдается тег <font color=...>, если же цвет неопределен, то ничего не выводится.

  end
    для определенных цветов выдается завершающий тег </font>, если же цвет неопределен, то ничего не выводится. Например, конструкции

    `$color{UserQuery:start}query$color{UserQuery:end}`

    в гипертекстовой среде отвечает просто слово `query`, усли цвет UserQuery не задан, или же подцвеченное слово, если этот цвет определен.

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

    `<font $color{Keyword:color} size="+1">`

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

    `<table $color{QueryFormBackground:bgcolor}>`

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

- Переменная $sflag{flag-name}
  Эта переменная используется в профильном файле бланка запроса для передачи значения флага поиска с именем flag-name в CGI модуль. Сейчас такой флаг только один - "Учитывать регистр букв", и его имя - CaseDepend. Пример использования переменной:

  `<input type="hidden" name="fl" value="$sflag{CaseDepend}">`

- Переменная $ending{word-type:number}
  Эта переменная нужна тогда, когда необходимо правильно просклонять слова, употребляемые совместно с числами, например: "НайденО 25 документОВ". Значением переменной $ending являются окончания этих слов, зависящие от соответствующего числа. В приведенном примере это "o" для слова "найден", и "ов" для слова "документ". Слово, для которого требуется определить окончание, задается через целочисленный параметр word-type. На данный момент он может принимать 3 значения: 0 - для слова "найден", 1 - для "документ", и 2 - для "байт". Модификатор number задает то самое число, которому и должно отвечать окончание слова. Это может быть просто число или же имя целочисленного параметра (вместе с знаком '$'), например:

  `Найден$ending{0:$FOUND_COUNT} $FOUND_COUNT документ$ending{1:$FOUND_COUNT}`

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

- Переменные $checked{parameter:value} и $selected{parameter:value}
  Эти параметрические переменные имеют одинаковый формат записи и практически одинаковый смысл - их значением являются слова checked (для переменной $checked) и selected (для $selected) - в том случае, когда условия поиска соответствуют указанной паре параметр/модификатор, либо же пустая строка - в противном случае. Так, например, если максимально допустимое число найденных ссылок на страницу установлено в 20, то значением переменной $checked{psize:20} будет слово checked, a $checked{psize:30} - пустая строка. Эти переменные удобно применять в тегах INPUT и OPTION.
  Для переменных $checked и $selected определены следующие параметры и модификаторы:

  Параметр | Модификаторы | Комметарий
  model | srt std dtl | выбрана ли компактная, стандартная или детализированная модель представления результатов поиска
  psize | число | равно ли текущее число ссылок на одну страницу результатов указанному числу
  index | id индекса | выбран ли индекс с данным id
  area | none content filename title keyword | какая выбрана область поиска в гипертекстовых документах
  sflag | CaseDepend | установлен ли флаг "Учитывать регистр букв"

| Переменные профильных файлов для всех видов профильных файлов |

Для каждого профильного файла определены следующие переменные:

  Имя переменной | Значение переменной | Форма вывода
  QUERY | пользовательский запрос (инициализирующий поле ввода) | text
  ESCAPED_QUERY | пользовательский запрос, выдаваемый в виде, пригодном для организации ссылок (вряд ли понадобится, но мало ли...) | escaped
  PAGE_SIZE | максимальное число ссылок на каждую страницу результатов (может принимать пять значений: 10, 20, 30, 40 и 50) | asis
  MODEL_TYPE | текущая модель представления результатов поиска (может принимать три значения: srt, std или dtl) | asis
  MODEL_NUMBER | текущая модель представления результатов поиска (может принимать три значения: 0, 1 или 2). В отличии от $MODEL_TYPE может применяться в операторах $if. | asis
  QUERY_TYPE | тип запроса (может принимать два значения: ef и if) | asis
  CHARSET | текущая кодировка | asis
  CONF_FILE | текущее имя используемого конфигурационного файла | escaped
  SELF_REF | адрес CGI модуля (в файловой системе WWW сервера) вместе с некоторыми параметрами, значения которых отличаются от принятых по умолчанию. В значении этой переменной профильного файла гарантированно присутствует символ '?', разделяющий имя CGI модуля от параметров (даже если таковые отсутствуют). Хотя эта переменная может быть записана через другие переменные, ее значение не эквивалентно приводимой ниже записи. | asis
  WHAT_ACTION | текущее действие, т.е. показ страницы с бланком запроса или же с результатами поиска (соответствующие значения параметра - frm и sch) | asis
  USED_INDEXES | список используемых индексов в виде ind=id1&ind=id2&...ind=idN, т.е. пригодном для организации ссылок | asis
  SEARCH_FLAGS | список установленных флагов в виде fl=flag1&fl=flag2&...fl=flagN, т.е. пригодном для организации ссылок | asis
  AREA | область применимости запроса | asis
  MSIE4 | равно 1, если используется браузер MSIE 4.0 (или старших версий), в противном случае - 0 | asis
  env{...} | значение соответствующей переменной окружения (см. раздел, посвященный параметрическим переменным) | text или escaped
  color{...} | значение соответствующего цвета (см. раздел, посвященный параметрическим переменным) | asis или html
  sflag{...} | имя флага поиска | asis

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

| Переменные профильного файла бланка запроса |

В профильном файле бланка запроса можно использовать следующие дополнительные переменные:

  Имя переменной | Значение переменной | Форма вывода
  FORM_HEADER | заголовок бланка запроса | html
  MODEL_SELECTION | панель выбора для модели представления результатов поиска | html
  PSIZE_SELECTION | панель выбора для максимального числа ссылок на каждую страницу результатов | html
  AREA_SELECTION | варианты выбора для области применимости запроса | html
  INDEX_LIST | список доступных индексов (в зависимости от типа запроса) | html
  QUERY_HELP | содержание файла QueryHelpFile | html
  checked{...} | означает слово checked, если условия поиска соответствуют указанному параметру | html
  selected{...} | означает слово selected, если условия поиска соответствуют указанному параметру | html

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

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

- Стартовый и завершающий профильные файлы

  Имя переменной | Значение переменной | Форма вывода
  QUERY_FORM | бланк запроса | html
  RESULT_PAGE_HEADER | заглавие страницы результатов | html
  QUERY_STRING | пользовательский запрос с предшествующим заголовком | html
  EXECUTED_QUERY | исполняемый запрос (пользовательский запрос в том виде, в каком его восприняла система) | html
  EXECUTED_QUERY_STRING | исполняемый запрос с предшествующим заголовком | html
  SEARCH_TIME | время поиска в секундах или миллисекундах (это время, затраченное системой на обслуживание запроса) | text
  SEARCH_TIME_STRING | время поиска с предшествующим заголовком | html
  FOUND_COUNT | общее число найденных ссылок | text
  FOUND_COUNT_STRING | общее число найденных ссылок с предшесвующим заголовком | html
  CURRENT_RESULT_PAGE | номер текущей страницы результатов | text
  START_RESULT_NUMBER | последовательный номер ссылки, отображаемой первой на текущей странице результатов | text
  END_RESULT_NUMBER | последовательный номер ссылки, отображаемой последней на текущей странице результатов | text
  PROBLEM_WORDS | список слов, вызвавших затруднения у компилятора запросов, выдаваемых вместе с причинами затруднений ("слишком короткое слово" и пр.) | html
  OTHER_RESULT_PAGES | список гипертекстовых ссылок на другие страницы результатов, если они есть | html
  TOTAL_RESULT_PAGES | общее число страниц результатов | asis
  NEXT_LIST_NUMBER | номер страницы, которая является первой в списке следующего (после текущего) набора страниц результатов. Если таковой нет, то значением этой переменной является 0. Эта переменная (наряду с PREV_LIST_NUMBER) необходима при создании набора ссылок на другие страницы результатов (т.е. для самостоятельной реализации $OTHER_RESULT_PAGES) (см. параметр компиляции MAX_PAGES_PER_BLOCK). | asis
  PREV_LIST_NUMBER | номер страницы, которая является последней в списке предыдущего (по отношению к текущему) набора страниц результатов. Если таковой нет, то значением этой переменной является 0. | asis
  NEXT_RESULT_PAGE | номер следующей (по отношению к текущей) страницы результатов. Если таковой нет, то значением этой переменной является 0. | asis
  PREV_RESULT_PAGE | номер предыдущей (по отношению к текущей) страницы результатов. Если таковой нет, то значением этой переменной является 0. | asis
  ending{...} | окончание слова | text
  page | номер страницы результатов в текущем наборе этих страниц (используется внутри оператора $foreach) | asis

- Результативный профильный файл

  Имя переменной | Значение переменной | Форма вывода
  NUMBER | последовательный номер найденной ссылки в списке результатов | text
  URL | адрес, ассоциированный с найденной ссылкой | asis
  URL_TEXT | адрес, ассоциированный с найденной ссылкой, выдаваемый в текстовом виде | text
  TITLE | заглавие документа, если найденная ссылка представляет собой гипертекстовый файл, в противном случае - ее URL | text
  SHORT_EXTRACT | краткая выдержка из начала документа (не более 80 символов), если найденная ссылка представляет собой текстовый или гипертекстовый файл | text
  EXTRACT | выдержка из начала документа (не более MAX_CONTENT_LENGTH символов), если найденная ссылка представляет собой текстовый или гипертекстовый файл | text
  SIZE | размер найденного документа в байтах | text
  SIZEK | размер найденного документа в килобайтах | text
  LAST_MODIFIED | дата внесения последних изменений в найденный документ в длинном формате | text
  SHORT_LAST_MODIFIED | дата внесения последних изменений в найденный документ в коротком формате | text
  RANK | соответствие найденного документа запросу, выраженное числом в диапазоне от 1 до 0 | text
  SCORE | соответствие найденного документа запросу, выраженное в процентах (с долями процента и без самого знака процента) | text
  SCORE_PROCENT | соответствие найденного документа запросу, выраженное в процентах (без долей процента и без самого знака процента) | text
  INDEX_FACE | отвечает значению face того индекса, которому принадлежит найденная ссылка | asis
  ICON | иконка, ассоциированная с найденной ссылкой (выдается в виде `<img src="icon-url" border=0>`) | html
  ending{...} | окончание слова | text

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

| Иконки |

В отличии от стандартного представления результатов поиска, принятого в FLUIdS по умолчанию, в результативном профильном файле для каждой найденной ссылки можно использовать отвечающую этой ссылке иконку через переменную ICON. Адреса иконок и правила их соответствия найденным ссылкам задаются в конфигурационном файле CGI модуля, в разделе [templates], директивами icon.

Общий формат директивы icon выглядит так:

  `icon = URL "альтернативный текст" pattern1 pattern2 ...`

Здесь URL - интернетовский адрес используемой иконки, альтернативный текст - текст, который будет виден вместо иконки пользователям текстовых браузеров, а pattern1, pattern2 и т.д. - шаблоны, которые будут сравниваться с адресом, ассоциированным с найденной ссылкой (т.е. с URL документа). (Сравнение происходит в режиме, независящем от регистра букв.) Например:

    [templates]
    icon = /icons/dir.gif  "[dir]"  */ */index.html */index.htm

В этом примере для найденной ссылки с адресом /docs/images/index.htm переменная ICON примет следующее значение:

`<img src="/icons/dir.gif" alt="[dir]" border=0>`

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

    [templates]
    icon = /icons/dir.gif     "[dir]"  */ */index.html */index.htm
    icon = /icons/text.gif    "[txt]"  *.txt
    icon = /icons/default.gif "[   ]"  *

Обычно вместе с WWW сервером поставляется некоторый набор иконок, который используется в работе этого сервера. Эти иконки можно использовать и для представления результатов поиска системы FLUIdS. Вот примерное описание для иконок, поставляемых вместе с Web сервером Russian Apache:

    [templates]
    icon = /icons/world2.gif       "[   ]"  *.wrl *.wrl.gz *.vrml *.vrm *.iv
    icon = /icons/a.gif            "     "  *.rtf *.ai
    icon = /icons/alert.black.gif  "[ ->]"  */readme */header
    icon = /icons/binhex.gif       "[   ]"  *.hqx
    icon = /icons/bomb.gif         "[cor]"  *.core
    icon = /icons/c.gif            "[src]"  *.c *.h *.cpp *.cc *.hh
    icon = /icons/compressed.gif   "[arc]"  *.zip *.tgz *.gz *.z *.arj *.ha *.rar *.lzh
    icon = /icons/dvi.gif          "[   ]"  *.dvi
    icon = /icons/folder.gif       "[dir]"  */ */index.{s}htm{l}
    icon = /icons/f.gif            "[src]"  *.for *.f
    icon = /icons/image2.gif       "[img]"  *.gif *.jpg *.bmp *.jpeg
    icon = /icons/index.gif        "[ind]"  *.flu */.glimpse{^/}
    icon = /icons/layout.gif       "[   ]"  *.{s}htm{l} *.pdf *.doc
    icon = /icons/movie.gif        "[   ]"  *.mov *.avi *.mpg *.mpeg
    icon = /icons/p.gif            "[src]"  *.pl *.py
    icon = /icons/patch.gif        "[   ]"  *.diff
    icon = /icons/ps.gif           "[ ps]"  *.ps *.eps
    icon = /icons/script.gif       "[   ]"  *.asp *.sh *.csh *.ksh *.shar *.tcl
    icon = /icons/sound2.gif       "[snd]"  *.wav *.snd *.mid
    icon = /icons/tar.gif          "[arc]"  *.tar
    icon = /icons/tex.gif          "[   ]"  *.tex
    icon = /icons/text.gif         "[txt]"  *.txt
    icon = /icons/uuencoded.gif    "[   ]"  *.uu
    icon = /icons/binary.gif       "     "  *.bin *.exe *.com /cgi-bin/*
    icon = /icons/unknown.gif      "[   ]"  *

Обратите внимание, что определение для иконки /icons/folder.gif стоит раньше, чем для /icons/layout.gif. В противном случае срабатывало бы только определение для /icons/layout.gif. (То же самое касается определений для иконок /icons/world2.gif и /icons/compressed.gif.)

Все же, не стоит описывать такое большое количество иконок. Достаточно ограничиться четырьмя-пятью иконками.

| Операторы |

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

- комментарий;
- условный оператор;
- орератор цикла.

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

Комментарий
  Комментарий записывается как параметрическая переменная профильного файла без имени: ${ ... }. Все, что находится внутри фигурных скобок, является комментарием и в текст сгенерированных CGI модулем страничек не попадает. Внутри фигурных скобок действует правило экранирования, так что, если есть необходимость поместить в комментарий символ '}', его надо заэкранировать, в противном случае он будет считаться концом комментария.

Условный оператор
  Общий вид условного оператора:

        $if{ условие }
        ...
        $elif{ еще_условие }
        ...
        $else
        ...
        $endif

  При этом операторов $elif может быть сколько угодно, а также он и оператор $else могут отсутствовать в записи, т.е. они не являются необходимыми. Условие, которое помещается внутри фигурных скобок операторов $if и $elif должно быть одинарным (т.е. простое сравнение без булевых операций OR, AND и NOT) вида

    `число операция_сравнения число`

  Здесь число - это либо запись неотрицательного целого числа в десятиричной системе счисления, либо указание (вместе со знаком '$') имени целочисленной переменной, определенной в текущем профильном файле (символьное сравнение строк не предусмотрено). Операция_сравнения - это могут быть символы '=', '<', '<=', '!=', '>=', '>' для операций "равно", "меньше", "меньше или равно", "не равно" и т.д. Например:

    `$if{ $FOUND_COUNT = 0 } Найдено 0 документов $endif`

  В этом примере, если число найденных ссылок - 0, то будет выдано соответствующее сообщение.

  Условные операторы могут быть вложенными:

        $if{ ... }
        ...
          $if{ ... }
            ...
          $endif
        ...
        $endif

  но максимальный уровень вложения не должен превышать 15.

Оператор цикла
  Этот оператор имеет следующую форму записи:

    `$foreach{page} ... $endfor`

  Здесь page - фиксированное имя особой целочисленной переменной, использовать которую можно только внутри тела цикла. При этом переменная пробегает значения от $PREV_LIST_NUMBER+1 до $NEXT_LIST_NUMBER-1, т.е. номера всех тех страниц результатов, на которые образуются ссылки в переменной $OTHER_RESULT_PAGES. Оператор $foreach не может быть вложенным.

| Тестовые профильные файлы |

В директории ./examples/templats/ можно найти три профильных файла (с именами ex-start.htm, ex-match.htm и ex-form.htm), специально приготовленных с целью показать, какие значения принимают те или иные переменные. Для реальной демонстрации расположите эти три файла в одной директории с CGI модулем (предполагается, что его работа уже налажена) и пропишите в конфигурационном файле следующие строчки:

    [templates]
    icons = /icons/unknown.gif "." *
    BeginResultFile = ex-start.htm
    MatchResultFile = ex-match.htm
    #QueryFormFile = ex-form.htm

  Обратите внимание, что последняя строчка закомментирована!

После чего обратитесь из браузера к CGI модулю поисковой системы. В бланке запроса в поле ввода набирите какой-нибудь разумный запрос (скажем, "a*"). Тогда стартовый профильный файл должен дать примерно такой результат:

Ниже приводится текст профильного файла (ex-start.htm), который и привел к этому результату:

      <table border cellspacing=1>
      <tr align="left" valign="top"><td><b>\$RESULT_PAGE_HEADER</b></td><td>$RESULT_PAGE_HEADER</td></tr>
      <tr align="left" valign="top"><td><b>\$QUERY</b></td><td>$QUERY</td></tr>
      <tr align="left" valign="top"><td><b>\$QUERY_STRING</b></td><td>$QUERY_STRING</td></tr>
      <tr align="left" valign="top"><td><b>\$ESCAPED_QUERY</b></td><td>$ESCAPED_QUERY</td></tr>
      <tr align="left" valign="top"><td><b>\$EXECUTED_QUERY</b></td><td>$EXECUTED_QUERY</td></tr>
      <tr align="left" valign="top"><td><b>\$EXECUTED_QUERY_STRING</b></td><td>$EXECUTED_QUERY_STRING</td></tr>
      <tr align="left" valign="top"><td><b>\$SEARCH_TIME</b></td><td>$SEARCH_TIME</td></tr>
      <tr align="left" valign="top"><td><b>\$SEARCH_TIME_STRING</b></td><td>$SEARCH_TIME_STRING</td></tr>
      <tr align="left" valign="top"><td><b>\$FOUND_COUNT</b></td><td>$FOUND_COUNT</td></tr>
      <tr align="left" valign="top"><td><b>\$FOUND_COUNT_STRING</b></td><td>$FOUND_COUNT_STRING</td></tr>
      <tr align="left" valign="top"><td><b>\$START_RESULT_NUMBER</b></td><td>$START_RESULT_NUMBER</td></tr>
      <tr align="left" valign="top"><td><b>\$END_RESULT_NUMBER</b></td><td>$END_RESULT_NUMBER</td></tr>
      <tr align="left" valign="top"><td><b>\$PROBLEM_WORDS</b></td><td>$PROBLEM_WORDS</td></tr>
      <tr align="left" valign="top"><td><b>\$OTHER_RESULT_PAGES</b></td><td>$OTHER_RESULT_PAGES</td></tr>
      <tr align="left" valign="top"><td><b>\$TOTAL_RESULT_PAGES</b></td><td>$TOTAL_RESULT_PAGES</td></tr>
      <tr align="left" valign="top"><td><b>\$PREV_RESULT_PAGE</b></td><td>$PREV_RESULT_PAGE</td></tr>
      <tr align="left" valign="top"><td><b>\$CURRENT_RESULT_PAGE</b></td><td>$CURRENT_RESULT_PAGE</td></tr>
      <tr align="left" valign="top"><td><b>\$NEXT_RESULT_PAGE</b></td><td>$NEXT_RESULT_PAGE</td></tr>
      <tr align="left" valign="top"><td><b>\$PREV_LIST_NUMBER</b></td><td>$PREV_LIST_NUMBER</td></tr>
      <tr align="left" valign="top"><td><b>\$NEXT_LIST_NUMBER</b></td><td>$NEXT_LIST_NUMBER</td></tr>
      <tr align="left" valign="top"><td><b>\$SELF_REF</b></td><td>$SELF_REF</td></tr>
      <tr align="left" valign="top"><td><b>\$WHAT_ACTION</b></td><td>$WHAT_ACTION</td></tr>
      <tr align="left" valign="top"><td><b>\$CHARSET</b></td><td>$CHARSET</td></tr>
      <tr align="left" valign="top"><td><b>\$USED_INDEXES</b></td><td>$USED_INDEXES</td></tr>
      <tr align="left" valign="top"><td><b>\$SEARCH_FLAGS</b></td><td>$SEARCH_FLAGS</td></tr>
      <tr align="left" valign="top"><td><b>\$MODEL_TYPE</b></td><td>$MODEL_TYPE</td></tr>
      <tr align="left" valign="top"><td><b>\$MODEL_NUMBER</b></td><td>$MODEL_NUMBER</td></tr>
      <tr align="left" valign="top"><td><b>\$QUERY_TYPE</b></td><td>$QUERY_TYPE</td></tr>
      <tr align="left" valign="top"><td><b>\$CONF_FILE</b></td><td>$CONF_FILE</td></tr>
      <tr align="left" valign="top"><td><b>\$PAGE_SIZE</b></td><td>$PAGE_SIZE</td></tr>
      <tr align="left" valign="top"><td><b>\$AREA</b></td><td>$AREA</td></tr>
      <tr align="left" valign="top"><td><b>\$MSIE4</b></td><td>$MSIE4</td></tr>
      <tr align="left" valign="top"><td><b>\$page</b></td><td>$page</td></tr>
      <tr align="left" valign="top"><td><b>документ\$ending{1:\$FOUND_COUNT}</b></td><td>документ$ending{1:$FOUND_COUNT}</td></tr>
      </table>
      <p>

Второй профильный файл (ex-match.htm) предназначен для вывода информации о каждой найденной ссылке:

Здесь демонстрируются значения всевозможных переменных результативного профильного файла для найденной ссылки с порядковым номером 133. Вот текст этого профильного файла:

      <table width="100%"><tr><td width="5%"><hr noshade size=3></td><td align="center"><b>
      $NUMBER
      </b></td><td width="100%"><hr noshade size=3></td></tr></table>

      <table border cellspacing=1>
      <tr align="left" valign="top"><td><b>\$NUMBER</b></td><td>$NUMBER</td></tr>
      <tr align="left" valign="top"><td><b>\$URL</b></td><td>$URL</td></tr>
      <tr align="left" valign="top"><td><b>\$URL_TEXT</b></td><td>$URL_TEXT</td></tr>
      <tr align="left" valign="top"><td><b>\$TITLE</b></td><td>$TITLE</td></tr>
      <tr align="left" valign="top"><td><b>\$SHORT_EXTRACT</b></td><td>$SHORT_EXTRACT</td></tr>
      <tr align="left" valign="top"><td><b>\$EXTRACT</b></td><td>$EXTRACT</td></tr>
      <tr align="left" valign="top"><td><b>\$SIZE</b></td><td>$SIZE</td></tr>
      <tr align="left" valign="top"><td><b>\$SIZEK</b></td><td>$SIZEK</td></tr>
      <tr align="left" valign="top"><td><b>\$LAST_MODIFIED</b></td><td>$LAST_MODIFIED</td></tr>
      <tr align="left" valign="top"><td><b>\$SHORT_LAST_MODIFIED</b></td><td>$SHORT_LAST_MODIFIED</td></tr>
      <tr align="left" valign="top"><td><b>\$RANK</b></td><td>$RANK</td></tr>
      <tr align="left" valign="top"><td><b>\$SCORE</b></td><td>$SCORE</td></tr>
      <tr align="left" valign="top"><td><b>\$SCORE_PROCENT</b></td><td>$SCORE_PROCENT</td></tr>
      <tr align="left" valign="top"><td><b>\$ICON</b></td><td>$ICON</td></tr>
      </table>
      <p>

Теперь раскомментируйте строчку с определением QueryFormFile (если ее предварительно не закомментировать, то Вы не сможете ввести запрос к поисковой системе FLUIdS, и, соответственно, увидеть результаты поиска), а в браузере нажмите на кнопку "Reload". Тогда бланк запроса должен выглядеть примерно так (ясно, что в реальности не следует создавать подобные бланки запроса):

Ниже приводится текст профильного файла ex-form.htm:

      <table border cellspacing=1>
      <tr align="left" valign="top"><td><b>\$FORM_HEADER</b></td><td>$FORM_HEADER</td></tr>
      <tr align="left" valign="top"><td><b>\$QUERY</b></td><td>$QUERY</td></tr>
      <tr align="left" valign="top"><td><b>\$ESCAPED_QUERY</b></td><td>$ESCAPED_QUERY</td></tr>
      <tr align="left" valign="top"><td><b>\$MODEL_SELECTION</b></td><td>$MODEL_SELECTION</td></tr>
      <tr align="left" valign="top"><td><b>\$PSIZE_SELECTION</b></td><td>$PSIZE_SELECTION</td></tr>
      <tr align="left" valign="top"><td><b>\$AREA_SELECTION</b></td><td>$AREA_SELECTION</td></tr>
      <tr align="left" valign="top"><td><b>\$INDEX_LIST</b></td><td>$INDEX_LIST</td></tr>
      <tr align="left" valign="top"><td><b>\$QUERY_HELP</b></td><td>$QUERY_HELP</td></tr>
      <tr align="left" valign="top"><td><b>\$SELF_REF</b></td><td>$SELF_REF</td></tr>
      <tr align="left" valign="top"><td><b>\$WHAT_ACTION</b></td><td>$WHAT_ACTION</td></tr>
      <tr align="left" valign="top"><td><b>\$MODEL_TYPE</b></td><td>$MODEL_TYPE</td></tr>
      <tr align="left" valign="top"><td><b>\$MODEL_NUMBER</b></td><td>$MODEL_NUMBER</td></tr>
      <tr align="left" valign="top"><td><b>\$QUERY_TYPE</b></td><td>$QUERY_TYPE</td></tr>
      <tr align="left" valign="top"><td><b>\$CONF_FILE</b></td><td>$CONF_FILE</td></tr>
      <tr align="left" valign="top"><td><b>\$PAGE_SIZE</b></td><td>$PAGE_SIZE</td></tr>
      <tr align="left" valign="top"><td><b>\$CHARSET</b></td><td>$CHARSET</td></tr>
      <tr align="left" valign="top"><td><b>\$USED_INDEXES</b></td><td>$USED_INDEXES</td></tr>
      <tr align="left" valign="top"><td><b>\$SEARCH_FLAGS</b></td><td>$SEARCH_FLAGS</td></tr>
      <tr align="left" valign="top"><td><b>\$AREA</b></td><td>$AREA</td></tr>
      <tr align="left" valign="top"><td><b>\$MSIE4</b></td><td>$MSIE4</td></tr>
      <tr align="left" valign="top"><td><b>\$sflag{CaseDepend}</b></td><td>$sflag{CaseDepend}</td></tr>
      <tr align="left" valign="top"><td><b>\$env{SCRIPT_NAME}</b></td><td>$env{SCRIPT_NAME}</td></tr>
      <tr align="left" valign="top"><td><b>\$color{QueryFormHeader}</b></td><td>$color{QueryFormHeader}</td></tr>
      <tr align="left" valign="top"><td><b>\$selected{psize:20}</b></td><td>$selected{psize:20}</td></tr>
      </table>
      <p>

| Стандартное представление бланка запроса |

Стандартно выводимый бланк запроса может быть записан через переменные профильного файла QueryFormFile (хотя, в действительности, стандартный бланк запроса, генерируемый CGI модулем, может отличаться от приводимой ниже записи):

      $FORM_HEADER
      <form method="get" action="$env{SCRIPT_NAME:escaped}">
      <center>
      <table border=1 $color{QueryFormBackground:bgcolor} width="99%"><tr><td>
      <table width="100%" border=0>
      <td align="center">
      Ваш запрос:&nbsp;&nbsp;<input type="text" name="q" maxlength="255" size="32" value="$QUERY"><br>
      <input type="submit" value="Искать"> <input type="reset" value="Очистить бланк"><br>
      <input type="checkbox" name="fl" value="cd" $checked{sflag:CaseDepend}> Учитывать регистр букв
      </td>
      <td>Результатов на страницу:&nbsp;$PSIZE_SELECTION<br>
      Представить результат в&nbsp;$MODEL_SELECTION<br>
      Область поиска&nbsp;$AREA_SELECTION
      </td></tr>
      <tr align="left" valign="top"><td colspan="2">
      $INDEX_LIST
      </td></tr>
      </table>
      </td></tr></table>
      </center>
      <input type="hidden" name="w" value="sch">
      <input type="hidden" name="cfg" value="$CONF_FILE">
      <input type="hidden" name="cs" value="$CHARSET">
      <input type="hidden" name="qt" value="$QUERY_TYPE">
      </form>
      $QUERY_HELP

Кроме этого, значения некоторых переменных, выводимых в форме html, могут быть выражены через другие переменные и записаны в явном виде:

FORM_HEADER

      <h2 align="center"><b>$color{QueryFormHeader:start}Бланк запроса$color{QueryFormHeader:end}</b><br>
      <hr noshade width="50%" size=3></h2><p>

PSIZE_SELECTION

      <select name="page">
      <option value="10" $selected{psize:10}>10</option>
      <option value="20" $selected{psize:20}>20</option>
      <option value="30" $selected{psize:30}>30</option>
      <option value="40" $selected{psize:40}>40</option>
      <option value="50" $selected{psize:50}>50</option>
      </select>

MODEL_SELECTION

      <select name="trs">
      <option value="srt" $selected{model:short}>краткой форме</option>
      <option value="std" $selected{model:standard}>стандартной форме</option>
      <option value="dtl" $selected{model:detailed}>детальной форме</option>
      </select>

AREA_SELECTION

      <select name="ar">
      <option value="-" $selected{ar:none}>искать везде</option>
      <option value="c" $selected{ar:text}>текст документов</option>
      <option value="t" $selected{ar:title}>заглавие документов</option>
      <option value="ct" $selected{ar:text}>текст и заглавие</option>
      <option value="n" $selected{ar:filename}>имена файлов</option>
      </select>

| Стандартное представление результатов поиска |

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

- Стартовый файл

      $RESULT_PAGE_HEADER
      $QUERY_STRING
      $EXECUTED_QUERY_STRING
      $SEARCH_TIME_STRING
      $PROBLEM_WORDS
      $FOUND_COUNT_STRING
      <dl>

- Завершающий файл

      </dl>
      $OTHER_RESULT_PAGES
      <hr><p>
      $QUERY_FORM

- Результативный файл

      $if{ $MODEL_NUMBER == 0 }
      <dt>$NUMBER. <a href="$URL"><b>$TITLE</b></a> [$SIZE байт$ending{2:$SIZE}]</dt>
      $elif{ $MODEL_NUMBER == 1 }
      <dt>$NUMBER. <a href="$URL"><b>$TITLE</b></a></dt>
      <dd>$SHORT_EXTRACT</dd>
      <dd><b><i>Ранг:</b></i> $RANK</dd>
      <dd><b><i>Размер:</b></i> $SIZE байт$ending{2:$SIZE}</dd>
      <dd><b><i>Адрес:</b></i> $URL_TEXT</dd>
      $else
      <dt>$NUMBER. <a href="$URL"><b>$TITLE</b></a></dt>
      <dd>$EXTRACT</dd>
      <dd><b><i>Ранг:</b></i> $RANK</dd>
      <dd><b><i>Размер:</b></i> $SIZE байт$ending{2:$SIZE}</dd>
      <dd><b><i>Дата последней модификации:</b></i> $LAST_MODIFIED</dd>
      <dd><b><i>Адрес:</b></i> $URL_TEXT</dd>
      $endif
      <p>

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

FOUND_COUNT_STRING

      <p>
      <h3 align="left"><b>Найден$ending{0:$FOUND_COUNT} $FOUND_COUNT документ$ending{1:$FOUND_COUNT}</b></h3>

RESULT_PAGE_HEADER

      <h2 align="center"><b>$color{SearchResultsHeader:start}Результаты поиска$color{SearchResultsHeader:end}</b><br>
      <hr noshade width="50%" size=3></h2><p>

EXECUTED_QUERY_STRING

      <dl>
      <dt><b>Исполняемый запрос</b></dt>
      <dd>$EXECUTED_QUERY</dd>
      </dl>
      <p>

SEARCH_TIME_STRING

      Время поиска: $SEARCH_TIME

SELF_REF

      $env{SCRIPT_NAME:escaped}?cfg=$CONFIG&cs=$CHARSET&$USED_INDEXES&SEARCH_FLAGS&ar=$AREA&page=$PAGE_SIZE&trs=$MODEL_TYPE&qt=$QUERY_TYPE

OTHER_RESULT_PAGES

      $if{ $TOTAL_RESULT_PAGES > 1 }
        <p><h3 align="center"><hr noshade width="50%"><b>$color{OtherPagesHeader:start}Другие страницы результатов$color{OtherPagesHeader:end}</b></h3><p>
        <center><b><tt>
        $if{ $PREV_LIST_NUMBER != 0 }
          <a href="$SELF_REF&w=sch&q=$ESCAPED_QUERY&start=$PREV_LIST_NUMBER">Пред.</a>
        $endif
        $foreach{page}
          $if{ $page == $CURRENT_RESULT_PAGE }
            $page
          $else
            <a href="$SELF_REF&w=sch&q=$ESCAPED_QUERY&start=$page">$page</a>
          $endif
        $endfor
        $if{ $NEXT_LIST_NUMBER != 0 }
          <a href="$SELF_REF&w=sch&q=$ESCAPED_QUERY&start=$NEXT_LIST_NUMBER">След.</a>
        $endif
        </tt></b>
        </center><p>
      $endif

| Примеры использования профильных файлов |

В директории examples/templats можно обнаружить три специально подготовленных примера написания профильных файлов, условно названных стилями:

- в поддиректории 1 - свободный стиль #1 (подразумевается, что возможны стили #2, #3 и т.д.);
- в поддиректории aport - стиль, эмулирующий поисковую систему Апорт!;
- в поддиректории sledopyt - стиль, эмулирующий поисковую систему Следопыт.

Для того, чтобы заставить работать FLUIdS с этими стилями, необходимо:

- разместить целиком поддиректории 1, aport и sledopyt в директории CGI модуля:

      host# ls -l
      drwxr-xr-x  2 web      web       512  2 апр 18:48 1
      drwxr-xr-x  2 web      web       512  2 апр 18:48 aport
      -rw-r--r--  1 web      web       883  2 апр 19:47 fluids.cfg
      -rw-r--r--  1 web      web      7879 11 ноя 16:51 fluids.jpg
      -rw-r--r--  1 web      web       168 11 ноя 16:51 footer.htm
      -rwxr-xr-x  1 web      web     98304  2 апр 19:41 fluids.cgi
      -rw-r--r--  1 web      web  12642021  5 апр 02:15 index.flu
      -rw-r--r--  1 web      web      1995  3 мар 18:59 qhelp.htm
      drwxr-xr-x  2 web      web       512  2 апр 18:48 sledopyt

- оформить надлежащим образом конфигурационные файлы CGI модуля в каждой из поддиректорий 1, aport и sledopyt (т.е. прописать используемые индексы в файлах 1/1.cfg, aport/aport.cfg и sledopyt/sledopyt.cfg и, возможно, создать свой раздел replace)

  Заметьте, что в них все прописываемые имена файлов (индексных, профильных и т.д.) исчисляются от директории, в которой находится именно CGI модуль, а не от директории конфигурационного файла!

- обратиться к CGI модулю с соответствующим параметром cfg:
  - http://www.domain.ru/search/fluids.cgi&cfg=1/1 для свободного стиля #1;
  - http://www.domain.ru/search/fluids.cgi&cfg=aport/aport для стиля поисковой системы Апорт!;
  - http://www.domain.ru/search/fluids.cgi&cfg=sledopyt/sledopyt для стиля поисковой системы Следопыт.

  Имя пользовательского конфигурационного файла в HTTP запросе пишется без расширения .cfg.

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

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

Обратите внимание, что в этих примерах CGI модуль располагается не в директории /cgi-bin/, а в некоторой директории /search/ Web сервера. Это сделано потому, что на некоторых платформах некоторые серверы (например, Apache под OS/2) не дают возможности извлекать статические документы (в том числе и картинки) из под директории /cgi-bin/. При такой попытке в лог-файле могут появиться следующие строчки:

         httpd.exe: [Fri Dec 31 23:47:13 1999] [error] (2)Invalid executable file
         format: exec of D:/WWW/SEARCH/SLEDOPYT/BG.JPG failed

         httpd.exe: [Fri Dec 31 23:47:14 1999] [error] [client 127.0.0.1]
         Premature end of script headers: d:/www/search/sledopyt/bg.jpg

На предыдущую страницу | valera@sbnet.ru