Разделы

Фильтрация каталога для юзера с помощью Ditto - Request

Здравствуйте.
Возникла такая идея — сделать с помощью Ditto -> request фильтрацию по каталогу (со стороны пользователя), используя html-форму(checkbox или multiple select) где использовать тэги, как параметры для фильтрации.
Напомню, что расширение Request позволяет ditto принимать и обрабатывать параметры, пришедшие методом GET.
Таким образом в ditto-параметр &tags можно поместить значения какого-либо TV и сделать фильтр соответствующих документов, отправляя данные с html-формы методом get.

Проблема в том, что html форма, которую придётся использовать для формирования GET запроса, передаёт параметры поочереди, так, что ditto обрабатывает только самую поледнюю переменную.

index.php?id=1&ditto_tags=param1&ditto_tags=param2&ditto_tags=param3


А request понимает, только когда тэги разделены запятой

index.php?id=1&ditto_tags=param1,param2,param3


Какие могут быть способы решения проблемы?
(Может с помощью javascript «научить» html-форму передавать параметры через запятую, или изменить сам request, чтобы понимал поочерёдные параметры?)

Может быть, подобный фильтр реализуем как-то подругому?

Спасибо большое за внимание к проблеме!

РЕШЕНИЕ:

Создан сниппет [[GetStringMod]], который преобразует полученный методом GET значения параметров, в вид, приемлемый для ditto, т.е. поочередно, через запятые;
В моем примере три параметра формы priority, place, style (принимают значения из input selelct'а).


$Priority = isset($_GET["priority"]) ? $_GET["priority"] : false;
$Place = isset($_GET["place"]) ? $_GET["place"] : false;
$Style = isset($_GET["style"]) ? $_GET["style"] : false;

if ($Priority=="priority") $Priority="";
if ($Place=="place") $Place="";
else $Place=','.$Place;
if ($Style=="style")$Style="";
else $Style=','.$Style;

echo $Priority.$Place.$Style;


Таким образом GET запрос например
index.php?tags=priority1&tags=style1&tags=place1
преобразуется в priority1,style1,place1

Далее он(сниппет) помещен в вызов ditto

[!Ditto? &startID=`id` &tpl=`list-output` &display=`all` &tagDelimiter=`,` &tags=`[!GetStringMod!]` &tagData=`priority,style,place` &tagMode=`onlyTags`  &sortBy=`createdon` &sortDir=`ASC` &extenders=`request`!]


И дитто выбирает значения подкаталога только по пришедшим, с помощью расширения request, тэгам (параметр &tags)
Всё, надеюсь это кому-нибудь пригодится :)

Комментарии (21)

RSS свернуть / развернуть
0
Почему бы не использовать сниппет до вызова дитто, который бы обрабатывал и преобразовывал строку запроса?

или так:


[!Ditto? &sometag=`[[Snippet]]`!]

*Кажется так модикс отработает вложенный вызов.
avatar

pitbull

  • 19 августа 2009, 20:36
0
Но в таком случае корректировать приходящий GET запрос нужно внутри кода самого сниппета, а не в запросе.
Хотя, если честно, то я немного не понял, Вашего решения.
avatar

JustViktor

  • 19 августа 2009, 20:51
0
Если сниппет вызвать до ditto,

[!SnippetCall!]
[!Ditto!]

можно просто разобрать запрос и присвоить переменной c именем параметра Ditto нужное значение, например
<?php
$parents=1;
?>

И Дитто ее с удовольствием подхватит. Ну если не заменить ее значение в самом вызове дитто в виде:
[!Ditto? &parents=`2`!]


Ну а пример с вложенным вызовом, он более наглядный что ли.
avatar

pitbull

  • 19 августа 2009, 23:18
0
Понятно, но я всё же надеюсь, что найдутся и другие решения.
Просмотрел дополнение tvexplorer, он вроде очень гибкий, но пока находится в бета версии.
Ктстати, в передаче &ditto_filter=pole,criteria,match (если пользоваться встроеным фильтром ditto) такая же проблема. Автоматически запрос через html-форму не сгенирировать.
avatar

JustViktor

  • 20 августа 2009, 00:10
0
Чем это решение не решение?
avatar

pitbull

  • 20 августа 2009, 05:33
0
Просто, если следовать такому способу, то лучше уже перехватить пришедший GET запрос в файле request.extender.inc.php
На строке 56 начинается преобразование, сейчас думаю, как лучше всего заместить.
Но появилась другая проблема. $_REQUEST приходит в виде
Array ( [id] => 6 [ditto_tags] => param3 [QE_linksShown] => 1 [SN1a44e02f18d0a] => f1f8923beac5e5d7bb16349d217c90c33 [__utma] => 10015269.1256337980858517400.1246546026.1250718271.1250750525.95 [__utmz] => 10015269.1247416797.47.2.utmcsr=goodsite.ru|utmccn=(referral)|utmcmd=referral|utmcct=/away.php [SN4a436f5689b0f] => 2b9780c39b4b021efbd6e1b7f82bf0d2 [__utmb] => 10015269.1.10.1220750525 [__utmc] => 10014269 ) 

Здесь только одна переменная ([ditto_tags] => param3 ), что означает, что это не дитто не принимает разделённые параметры, а это GET передаёт только последний из одинаковых. Верно?
avatar

JustViktor

  • 20 августа 2009, 10:55
0
Ну вообще-то логично, что при одинаковом названии переменной значение используется только последнее. :-)

Честно говоря с GET вообще мало разбирался на предмет всяких ухищрений, но возможно он как и POST умеет делать массив, если использовать квадратные скобки?

index.php?id=1&ditto_tags[]=param1&ditto_tags[]=param2&ditto_tags[]=param3


А на массив уже применить implode соответственно.
avatar

Carw

  • 20 августа 2009, 14:04
0
Нет, GET не передаёт массив в нужном виде.
Но я пробывал и с POST и вот что вышло.
В переменную $_REQUEST (файл request.extender.inc.php ) приходит массив в нормальном виде
Array ( [id] => 6 [ditto_tags] => Array ( [0] => one [1] => two [2] => three )...
но далее обработка запроса уже не подходит для такого массива. Это как раз строка 56 (request.extender.inc.php) и ditto возвращает «No documents found».
avatar

JustViktor

  • 20 августа 2009, 15:03
+1
А что насчет связи @eval прямо в вызове? ;-)

&filter=`myTv,@EVAL return $_POST['MyParam'];,1`
avatar

Carw

  • 20 августа 2009, 16:45
0
Вообще я вижу только два эфективных решения.
1. Переделать request.extender.inc.php так, чтоб он смог нормально обработать POST массив из html формы (как?).
2. С помощью способа, предложенного Temus (jquery.form.js) преобразовывать параметры перед отправкой html формы.
(я остановился на втором варианте, т.к. по задаче можно использовать javascript, но если по уму, то лучше (а главное универсальнее) конечно проработать первый.)
Кстати, подобной «многопараметровой» формой можно было бы сделать афтоконфигуратор сниппетов для MODX.
Например была бы колонка параметров (допустим для того же ditto), а по нажатию одного из них, раскрывается форма ввода возможные значений (checkbox, multiple select, select, input). И опубликовать бы такой конфигуратор на modx-cms.ru :-)
В revolution, вроде уже организована подобная штука.
avatar

JustViktor

  • 20 августа 2009, 17:41
0
Да, в Revo вообще супер сделано — там просто перетаскивается сниппет на поле редактирования и появляется форма с параметрами. Гениальная штука :-)

Кстати, подобной «многопараметровой» формой можно было бы сделать афтоконфигуратор сниппетов для MODX.
Например была бы колонка параметров (допустим для того же ditto), а по нажатию одного из них, раскрывается форма ввода возможные значений (checkbox, multiple select, select, input). И опубликовать бы такой конфигуратор на modx-cms.ru :-)


В очередной раз убеждаюсь, что одни и те же мысли приходят в разные головы. Я давно думаю над этой штукой, но пока не придумал как лучше всего ее организовать (чтобы и удобно и безопасно и просто для создания к разным сниппетам). Если есть на эту тему хорошие мысли, то буду рад узнать :-)
avatar

Carw

  • 20 августа 2009, 18:00
0
Через яваскрипт наверное можно сделать так:

<script type="text/javascript" src="jquery-1.3.2.min.js" ></script>
<script type="text/javascript" src="jquery.form.js" ></script>
<script type="text/javascript">
$(function(){
  $('#myForm').submit(function() {
    location.href=this.action+'?ditto_tags='+$('[name=ditto_tags]').fieldValue();
    return false;
  });
});
</script>

Можно кстати и аяксом отправлять. jquery.form.js — это jQuery Form Plugin
avatar

Temus

  • 19 августа 2009, 23:01
0
JS в данном контексте не стоит использовать.

Все-таки некоторые люди используют noscript к примеру.

Да и по логике разбирать значения и следить за их валидностью должна серверная часть.
avatar

pitbull

  • 19 августа 2009, 23:19
0
Вот нашел еще способ www.mredkj.com/tutorials/tutorial004.html, только не могу совместить обработку значений в массив и отправку формы. В javascript не силён…
avatar

JustViktor

  • 20 августа 2009, 11:11
+1
Там не очень универсально — только select обрабатывется. А fieldValue() выведет через запятую значения любых нужных полей формы. Ну и вообще jquery облегчает жизнь :)

В примере отправлять можно так:
Вместо txtSelectedValuesObj.value = selectedArray; поставить
location.href=document.myform.action+'?ditto_tags='+selectedArray;
и name='myform' у формы
avatar

Temus

  • 20 августа 2009, 13:03
+1
Надеюсь не буду выглядеть как КО

Но тем не менее в своё время мне очень понравились два материала… они как раз по вашей теме:
Use AJAX with modxAPI
Tagged blogging with Ditto

Думаю можно оформить эти статьи в виде топиков на более близком нам языке… если смогу завтра постараюсь перевести…
avatar

bullder

  • 20 августа 2009, 00:08
0
Однозначно полезно :-)
avatar

Carw

  • 20 августа 2009, 14:04
0
И все-таки был использован вариант, который предложил pitbull.

Создан сниппет [[GetStringMod]], который преобразует полученный методом GET значения параметров, в вид, приемлемый для ditto, т.е. поочередно, через запятые;
В моем примере три параметра формы priority, place, style (принимают значения из input selelct'а).


$Priority = isset($_GET["priority"]) ? $_GET["priority"] : false;
$Place = isset($_GET["place"]) ? $_GET["place"] : false;
$Style = isset($_GET["style"]) ? $_GET["style"] : false;

if ($Priority=="priority") $Priority="";
if ($Place=="place") $Place="";
else $Place=','.$Place;
if ($Style=="style")$Style="";
else $Style=','.$Style;

echo $Priority.$Place.$Style;


Таким образом запрос например
index.php?tags=priority1&tags=style1&tags=place1
преобразуется в priority1,style1,place1

Далее он(сниппет) помещен в вызов ditto

[!Ditto? &startID=`id` &tpl=`list-output` &display=`all` &tagDelimiter=`,` &tags=`[!GetStringMod!]` &tagData=`priority,style,place` &tagMode=`onlyTags`  &sortBy=`createdon` &sortDir=`ASC` &extenders=`request`!]

И дитто выбирает значения подкаталога только пришедшим, с помощью расширения request, тэгам (параметр &tags)
Всё, надеюсь это кому-нибудь пригодится :)
avatar

JustViktor

  • 14 сентября 2009, 02:06
0
Здравствуйте!
А вот подскажите, как сделать пагинацию в выведенных результатах — чего-то у меня не идет… каменный цветок.
avatar

tmih

  • 27 января 2012, 21:15
0
Сделать вызов дитто кешируемым, а сам ресурс — некешируемым.
avatar

w3d

  • 29 января 2012, 16:31
0
Спасибо, но уже пробовал — не помогло совсем, к сожалению
&tags=`[!GetStringMod!]` — у меня работает только кэшируемый &tags=`[[GetStringMod]]`, если ставлю
На &paginate=`1` &summarize=`2` — вообще не реагирует — вернее обрезает и выдает как указано 2 новости, а вместо пагинации ничего не пишет — отображается надпись СТРАНИЦЫ — и все — совсем плохо. Вызод ДИТТО делаю некэшируемый на некэшиируемой странице — тогла фильтраци работает на УРА, вызод
[!Ditto? &tagDelimiter=`,` &tags=`[[GetStringMod]]… !]
Спасибо за ответ!
avatar

tmih

  • 29 января 2012, 22:50

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.