eXist-DB сопоставление URL для динамической страницы - PullRequest
0 голосов
/ 24 октября 2018

У меня есть несколько динамических страниц в моем приложении eXist-db, которые до этого момента тестировались через жестко закодированные вводы.Теперь я нахожусь в точке, где мне нужно рисковать в домене, с которым мне менее всего удобно: сопоставление / перезапись URL-адресов в eXist-db.

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

www.foo.com/doc/MS609-0020

Где / doc / говорит, что вы просматриваете документы, а MS609-0020 - это фактически имя документа (которое отражает файл XML, то есть MS609-0020.xml).

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

/db/apps/deheresi/document.html

. Этот document.html содержит шаблоны, которым требуется имя документа MS609-0020.xml из запроса, чтобы знать, чтопроцесс.Я назвал эту глобально доступную переменную $currentdoc.Используя эту переменную, различные шаблоны получают данные, необходимые для сборки document.html.

. Затем HTML-код отправляется в браузер по адресу www.foo.com/doc/MS609-0020

Если имя документа не найдено,пользователь направлен на «страницу документа не найдена».

Как вы видите, мое объяснение является основным - оно отражает тот факт, что у меня все еще есть тренировочные колеса с eXist и XQuery.

Я прочитал главы в книге eXist Зигеля / Реттера, но то, как перераспределение выполняется в модулях и передается с требуемым parameters ..., не сводится воедино для меня, независимо от того, сколько я с этим справлюсь.

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

Заранее большое спасибо.

NB: Я должен добавить, что это будет публичносайт без разрешений для просмотра документов.

Примечание 2: я получу награду за этот вопрос, как только получу право.

Ниже, схема из книги Зигеля / Реттера.

Diagram from Siegel/Retter

1 Ответ

0 голосов
/ 27 октября 2018

В этом ответе, который охватывает только базовую перезапись URL-адреса, предполагается, что приложение eXist построено с использованием так называемой «базовой» архитектуры приложения eXist:

  • Приложение, которое мы назовем«my-app» хранится в /db/apps/my-app.
  • Не было внесено никаких изменений в файлы конфигурации Jetty в EXIST_HOME/tools/jetty/etc, файл конфигурации сервлета XQuery в EXIST_HOME/webapp/WEB-INF/web.xml или базовую конфигурацию для eXist.Перезапись URL-адреса на webapp/WEB-INF/controller-config.xml.
  • Это означает, что к приложению можно получить доступ на http://localhost:8080/exist/apps/my-app.(Если цель состоит в том, чтобы обслуживать это приложение через URL-адрес, такой как http://my-server/, и направить его в eXist на http://localhost:8080/exist/apps/my-app, это лучше всего обрабатывать обратным прокси-сервером, который выходит за рамки «базовой» архитектуры приложения eXist.)
  • Мы будем обрабатывать перезапись URL-адреса с помощью средства перезаписи URL-адреса eXist, т. Е. Записывать файл controller.xql, а не через RESTXQ.

С этими допущениями мы можем создавать полностью настраиваемые URL-адреса, что позволяет нам брать URL-адреса, такие как:

  • http://localhost:8080/exist/apps/my-app/doc.xq?filename=my-document.xml

исделать этот же ресурс доступным через:

  • http://localhost:8080/exist/apps/my-app/doc/my-document

Для этого нам нужно создать новый основной модуль XQuery с именем controller.xql (он должен бытьэто называется именно так, и мы назовем его «контроллером» приложения в корневой коллекции вашего приложения: /db/apps/my-app/controller.xql.Это специальный модуль, который eXist ищет первым, когда приходит запрос на путь в адресном пространстве /apps (например, http://localhost:8080/exist/apps/...).Хотя обычно приложение имеет только один контроллер, eXist поддерживает несколько контроллеров;eXist ищет в целевой коллекции, а затем вверх по дереву коллекции, от самой глубокой ветви до корневой /db/apps коллекции.

Цель контроллера - получить информацию о запросе - запрошенный путь и другую информациюо контексте приложения - и возвращает специальный вид директивы, которая сообщает eXist, как направить запрос.Ключевая информация о запросе предоставляется вашему запросу в виде серии внешних переменных (переменных, которые вам не нужно определять, которые eXist устанавливает для вас и на которые вы можете ссылаться), включая, что наиболее важно, $exist:path - часть URL запроса, которая идет после пути к коллекции, содержащей контроллер.Таким образом, в приведенном выше URL-адресе $exist:path будет равно /doc/my-document.

Теперь давайте создадим директиву, которая берет этот путь и направляет этот запрос (сформулированный с использованием параметра filename к фактической конечной точке:

xquery version "3.1";

declare variable $exist:path external;
declare variable $exist:resource external;
declare variable $exist:controller external;
declare variable $exist:prefix external;
declare variable $exist:root external;

if (starts-with($exist:path, "/doc/")) then
    <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
        <forward url="{$exist:controller}/doc.xq">
            <add-parameter name="filename" value="{$exist:resource}.xml"/>
        </forward>
    </dispatch>

else
    <ignore xmlns="http://exist.sourceforge.net/NS/exist"/>

В первом блоке кода (пролог) этот контроллер явно объявляет переменные, которые eXist предоставляет контроллеру. В основной части запроса условное выражение обрабатывает два случая:

  1. Если запрошенный путь начинается с /doc/, то мы хотим, чтобы запрос обрабатывался doc.xq - модулем XQuery в нашем приложении по адресу /db/apps/my-app/doc.xq. Вместо того, чтобы вводить этот полный путь,мы можем заменить /db/apps/my-app на $exist:controller - это путь базы данных к коллекции, в которой находится активный контроллер. Мы также знаем, что doc.xq требует параметр filename, поэтому мы явно создаем его из $exist:resourceпеременная, которая всегда предоставляет нам часть запрошенного URL-адреса после последней косой черты - например, my-document в нашем примере URL-адреса выше.После запроса, на который контроллер перенаправляет запрос (например, doc.xq), он думает, что получил запрос напрямую, и он может получить доступ к параметрам запроса через функцию request:get-parameter().Например, doc.xq может просто содержать:

    xquery version "3.1";
    
    let $doc := request:get-parameter("filename", ())
    return
        <p>Who's looking for {$filename}?</p>
    

    И запрос на приведенный выше URL вернет <p>Who's looking for my-document.xml?</p>.

  2. Для любых других запросов мыпропустит их без выполнения переадресации или других действий с URL-адресом.

Если вы используете шаблонизатор HTML в eXist, вы, скорее всего, будете пересылать запросы в шаблон (document.html) вместозапрос (doc.xq).В этом случае директива становится немного сложнее немного :

    <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
        <forward url="{$exist:controller}/document.html"/>
        <view>
            <forward url="{$exist:controller}/modules/view.xql">
                <add-parameter name="filename" value="{$exist:resource}.xml"/>
            </forward>
        </view>
    </dispatch>

Здесь мы пересылаем запрос на document.html, но затем результат передается через модуль обработки шаблонов eXist, который обычно хранится в файле modules/view.xql вашего приложения.(Обратите внимание, что директива <add-parameter> переместилась во 2-ю директиву <forward>.)

Другие внешние переменные (а именно, $exist:root и $exist:prefix) и другие виды директив (а именно, <redirect> и другие подэлементы) описаны на странице документации eXist по перезаписи URL, http://exist -db.org / Существовать / приложения / doc / urlrewrite .Хотя страница в настоящее время предупреждает, что она устарела, я думаю, что это все еще хороший ресурс.

Сила средства перезаписи URL в eXist заключается в том, что вы можете использовать полную выразительность XQuery для определения того, как ваше приложение направляет и получает URL-адреса.Слабость в том, что контроллер может стать длинной цепочкой условных выражений, которые трудно поддерживать;просто постарайтесь сделать логику контроллера максимально простой.Изучение внешних переменных также может занять некоторое время;Я бы предложил широко использовать ведение журнала (с помощью функций util:log или console:log для вывода значений внешних переменных и другой информации о запросе, доступных через request:get-url() и другие функции request:get-*) дляПосмотрите, что происходит с каждым запросом, пока не получите его руку.Также может оказаться полезным изучить файлы контроллера в других приложениях, исходный код которых доступен, и задать дополнительные вопросы здесь!

...