Алгоритм разбора URL-ов для CMS, у которой не бывает дублей
На самом деле, мне неизвестно ни одной популярной CMS с вменяемым механизмом устранения этой проблемы. Обычно все сводится к танцам с бубном вокруг .htaccess и robots.txt.
Однако, выход (для самописов) есть. Все, что изложено далее - вовсе не теоретические абстрактные измышления. Механизм успешно работает, в том числе и на этом самом сайте.
Итак, что мы с будем делать? Приходящий get-запрос, перед отправкой на обработку, фильтруем на предмет выполнения жёстких правил.
Принцип построения правил чем-то сходен с правилами nginx. Вначале проверяется точное совпадение url (с отброшенными параметрами) до первого совпадения. Если нет, то затем - регулярные выражения для url без параметров (до первого совпадения).
Внутри каждого правила присутствует список разрешенных параметров для текущего url, а также указание, какой шаблон отвечает за обработку страницы.
Я реализовал этот механизм с помощью шаблонизатора Template-Toolkit. Примерный кусочек конфигурации выглядит так, сначала управляющий шаблон:
Таким образом, мы гарантированно избегаем вызова непредусмотренных страниц и реакции на урлы с "левыми" параметрами. По этой причине, на данном блоге нет и не может быть неожиданных для автора дублей.
Однако, выход (для самописов) есть. Все, что изложено далее - вовсе не теоретические абстрактные измышления. Механизм успешно работает, в том числе и на этом самом сайте.
Итак, что мы с будем делать? Приходящий get-запрос, перед отправкой на обработку, фильтруем на предмет выполнения жёстких правил.
Принцип построения правил чем-то сходен с правилами nginx. Вначале проверяется точное совпадение url (с отброшенными параметрами) до первого совпадения. Если нет, то затем - регулярные выражения для url без параметров (до первого совпадения).
Внутри каждого правила присутствует список разрешенных параметров для текущего url, а также указание, какой шаблон отвечает за обработку страницы.
Я реализовал этот механизм с помощью шаблонизатора Template-Toolkit. Примерный кусочек конфигурации выглядит так, сначала управляющий шаблон:
[% engine.config.uri_parser.uri = engine.config.request.uri() %]
[% MACRO macro_check_params_and_run BLOCK %]
[%-
engine.config.uri_parser.error.param = allow_params.test(engine.params.keys);
IF (engine.config.uri_parser.error.param.size);
engine.http_status = default_bad_status || 404;
RETURN;
END;
PROCESS $engine.template;
RETURN;
-%]
[% END #MACRO %]
[% IF method=='get' %]
[% PROCESS config.get.tpl %]
[% RETURN %]
[% END #IF method=='get' %]
[% IF method=='post' %]
[% PROCESS config.post.tpl %]
[% RETURN %]
[% END #IF method=='post' %]Выжимка из обработчика метода GET: [% default_bad_status = 404 %]
[% allow_params = [MAGIC_PARAMETER] %]
[% SWITCH engine.config.uri_parser.uri %]
[% CASE '/' %]
[%
allow_params = [MAGIC_PARAMETER, 'url', 'err', 'alias'];
engine.config.uri_parser.label = 'default';
engine.template = 'index.tpl';
macro_check_params_and_run;
%]
[% END #SWITCH %]
[% IF (matches = engine.config.uri_parser.uri.match('^\/ajax\/added\/([1-9]\d*)\/)) %]
[%
engine.config.uri_parser.label = 'ajax_added';
engine.template = 'ajax/added.tpl';
engine.config.uri_parser.var.pagenum = matches.0;
macro_check_params_and_run;
%]
[% END %]
[% engine.http_status = 404 %]
[% RETURN %]Ну и дальше управление передается либо найденному шаблону, отвечающему за прорисовку страницы (напр. index.tpl), либо возврат в движок с кодом 404. Таким образом, мы гарантированно избегаем вызова непредусмотренных страниц и реакции на урлы с "левыми" параметрами. По этой причине, на данном блоге нет и не может быть неожиданных для автора дублей.
