Николай Ланец
30 июня 2013 г., 16:32

Наборы параметров

Вообще раньше только пару раз использовал Наборы параметров. А зря… Их силу оценил только сегодня, когда полез переносить очередной старый сайт на Рево. Как раз недавно писал про обновление сайта. Так вот, там я писал, что так как сайт старый, то просто в базе копировал содержимое отдельных таблиц, и последним пунктом выполнял обновление (читай установку новых/голых) пакетов. Так вот, я там не написал с какой проблемкой столкнулся при таком переносе. И проблема не в самом способе переноса, а в ошибочном подходе к переопределению параметров сторонних элементов.
Простой пример: прописываем вызов сниппета [[Wayfinder?startId=`0`]], но чтобы не переопределять каждый раз все эти innerClass, rowTpl и прочее, просто идем в редактирование сниппета Wayfinder и в удобном редакторе правим нужные нам Параметры по умолчанию. ?
И все. Переопределили все нужные нам параметры, и теперь везде можно тыкать [[Wayfinder]], и не прописывать каждый раз одни и те же параметры. Удобно? А то!
А теперь представьте, что по какой-то причине сниппет Wayfinder (не важно по какой). Само собой удалились и все Параметры по умолчанию, в том числе и те, которые переопределели вы. А там и шаблон был указан с интуитивным названием RowTpl12321SDF, и несколько excludeDocs (2,3,4,5,7,12-34,56-77) и т.д. И как, теперь все это опять где-то искать, переопределять и т.п.?
Вот это как раз и есть проблема, с которой я столкнулся. Конечно всего пара параметров было переопределено, но все равно пришлось их поискать. Проблема просто еще не только в том, что надо найти эти параметры, проблема в том, что они в общей куче со всеми Параметрами по умолчанию, и поиск нужного параметра, который переопределенный, а не с исходным значением, может превратиться в поиск иголки в стоге сена.
Но как оказалось, есть вполне деликатное решение данной проблемы. И это — Наборы параметров. В чем их суть? Создается набор параметров, связывается с объектами MODX, и можно создавать свои параметры, или (и это главное), переопределять имеющиеся параметры связанных объектов.
Опять пример. В свой шаблон мы воткнули сниппет [[!Login]]. Смотрим результат. ?
Хотим изменить шаблон формы. Само собой нам надо изменить параметр loginTpl. Но для этого мы не будем ни редактировать этот параметр по умолчанию, не передавать его в вызов сниппета. Вместо этого мы создадим свой Набор параметров. Назовем его Site, дабы не профилировать его с ходу. ?
?
?
Теперь этот Набор нужно привязать к сниппету Login. Вообще связывать можно с чанками, сниппетами, плагинами и TV, при чем не с одним элементом. Потому и говорю, что не обязательно с ходу профилировать набор. ?
?
?
?
Все, связали со сниппетом Login. А теперь внимание! Кликаем Login, и что там видим? ?
А там мы сразу видим все Параметры по умолчанию сниппета Login. И здесь же можем изменить нужные нам параметры. К примеру я изменю loginTpl. ?
Но самое приятное не то, что мы здесь же можем параметры править. Самое приятное вот что: 1) Мы не только этот параметр видим в списке всех параметров. ?
Главное — мы видим измененный параметр в отдельности, если кликнем на сам Набор параметров. ?
2) Изменив параметр сниппета Login, мы не изменили параметр в самом сниппете. Там он остался прежним. ?
А вот это уже действительно удобно. Теперь остается только в элемент передать ссылку на Набор, и все. [[!Login@Site]] Смотрим результат (только не забывайте, что WebLoginSideBar — это мой пользовательский чанк-шаблон для Login, потому кто захочет поэкспериментировать, просто написать имя этого чанка недостаточно): ?
А теперь в этот же набор можно добавить и другие объекты, к примеру сниппет Wayfinder. И не только переопределим его параметры, но и свой новый добавим. ?
И все измененные параметры мы видим в одном месте. ?
При этом мы сами решаем, когда использовать эти параметры, а когда нет (то есть передавать параметр @Site объекту или нет).
В общем кому как, но на мой взгляд все это очень удобно. Хотя видимо не очень популярно, так как не смотря на то, что уже версия Revolution 2.2.5, не то, чтобы ошибки какие-то, элементарные недоработки есть. К примеру, тупо нет возможности удалить какой-либо параметр, даже свой, пользовательский. В контекстном меню пункт Редактировать есть, а Удалить — нет. ?
Но это не большая проблема. Сейчас мне это не мешает, а потом наверняка доработают.
UPD: А вот с синтаксисом есть особенности. Название Набора параметров не должно следовать за вопросительным знаком. Так же нельзя указать сразу два набора параметров. Так что, если хотите вызвать с набором параметров, и еще и на лету переопределить какие-то параметры, то пишем так: [[!Wayfinder@Site?&limit=`2`&rowClass=`row`(и так далее)]]
UPD 2:Еще одна приятность: возможность восстановить изначальное значение по умолчанию, при этом это действие будет локально только для связанных с этим Набором объектов, а не затронет всю систему в целом. Вот у меня два Набора, связанных со сниппетом Wayfinder. Каждый набор использует для себя дефолтовые параметры из Wayfinder. В каждом наборе свои переопределения параметров. Но если в каком-то наборе я восстанавливаю дефолтовое значение, это восстановление касается только этого набора. ?
Правда на практике это действие через контекстное меню опять-таки не доработано, то есть не выполняет на сервер запрос с целью выяснения дефолтового значения, и приходится значение восстанавливать самому вручную, но в обозримом будущем наверняка это доработают, или если спрос будет, то сделаю заплатку.
Добрый вечер, Николай! Пробую создать наборы параметров из панели — вроде, все нормально. Создал 2 набора(top-menu, mail-us), добавил параметры.Но когда пробую вызвать из smarty набор кодом $modx->getObject('modPropertySet','mail-us')->getProperties()); или $modx->getObject('modPropertySet','top-menu')->getProperties()); выдает всегда набор для top-menu. Удаляю top-menu, mail-us возвращается нормально. Стоит снова создать top-menu, как любой вызов возвращает именно его. Пробовал привязывать их к компонентам и без этого — результат один. Тот же результат, если указываю несуществующее имя.
Не подскажешь, в чем ошибка? Спасибо. Александр
$modx->getObject('modPropertySet','top-menu')
Это буквально «получить объект modPropertySet с primary key 'top-menu'». Но для modPropertySet ключ не имя, а id, то есть число. То, как ты его вызываешь, получается неверный PK, конвертируемый xPDO в int (в данном случае вообще никак), и получается, что он получает первый попавшийся объект. В данном случае надо так:
$modx->getObject('modPropertySet',array('name'=>'mail-us'))->getProperties());
Но это так, просто к слову. Но вызов сниппетов с наборами параметров таким образом не очень юзабильней. Правильней так:
{snippet name="snippet@mail-us"}
Но на всякий случай старайся избегать дефисов в названиях. Это очень скользкая дорожка.
Понял, спасибо. Как я понял, вызов сниппета а не кода напрямую не утяжеляет код, и я могу писать на нем часть функционала? Просто я хотел сделать этот функционал на процессорах.
У меня там такой код: {$menuParams=$modx->getObject('modPropertySet','top-menu')->getProperties()} … {processor action=«getmenu» ns=«site» params=$menuParams assign=result} {assign var=items value=$result.object} {include file=«top-menu/outer.tpl»}
Ну тогда в общих чертах все ОК (что-то я как-то проморгал передачу параметров в Smarty-плагин процессора). Но в любом случае, в комменте выше я написал в чем проблема вызова объекта параметров.
Я все понял. Просто в документации сразу не разберешься, да и с английским не очень дружен... Спасибо огромное за помощь.
Как я понял, вызов сниппета а не кода напрямую не утяжеляет код
Утяжеляет, тем более если через MODX-теги делается. Но даже если не через MODX-теги, все равно это лишний вызов объекта сниппета. Процессоры быстрее.
Кастати, по поводу передачи параметров… Возникла у меня идея сделать плагин, ну, чтобы можно было делать что-то типа {processor action=«getmenu» ns=«site» params={params name='top-menu'} assign=result} ну, чтобы сразу из наборов дергать параметры. Но, насколько я понял, smarty-планигы возвращают только строку? И json-encode тоже отдает не в том виде, что надо. Можно ли сделать что-то вроде этого? И стоит ли овчинка выделки?
ну, чтобы сразу из наборов дергать параметры. Но, насколько я понял, smarty-планигы возвращают только строку?
Нет, неправильно понял. Наоборот, процессоры очень даже возвращают массивы. А если очень надо, то можно и объекты возвращать. Это сниппеты строки только возвращают. Про это я писал здесь: community.modx-cms.ru/blog/tips_and_tricks/9966.html
Возникла у меня идея сделать плагин, ну, чтобы можно было делать что-то типа
А зачем? В сниппеты параметры передаются в имени. В плагинах параметры можно назначить по дефолту в методе initialize через $this->setDefaultProperties(). Не думаю, что имеет смысл утяжелять все это дело.
Нет, неправильно понял. Наоборот, процессоры очень даже возвращают массивы. А если очень надо, то можно и объекты возвращать. Это сниппеты строки только возвращают.
Нет, я не про процессоры, с ними все понятно, я про конструкции типа {processor ... и т.п. А без сниппетов я совсем хочу по максимуму обходиться.
Но я тоже уже подумал, что заполнить массив по месту как-то попроще будет, чем вызывать набор параметров. Да и свой модуль написать можно, где все это собрать в одну кучу. Подумаю еще.
Просто хочется иметь нечто вроде наборов, чтобы все в одном месте лежало, а при необходимости нужное по имени вытаскивать.
Просто хочется иметь нечто вроде наборов, чтобы все в одном месте лежало, а при необходимости нужное по имени вытаскивать.
Все равно на все случаи жизни наборами не запасешься. И есть барьер, когда куча наборов не помогают, а мешают, так как многое взаимосвязано, и правишь одно, а в другом месте боком выходит. Напиши себе несколько базовых процессоров и их развивай. А лучше сразу сборку себе движка сделай и все.
Да, я тоже к этому склоняюсь. Спасибо.
Нет, я не про процессоры, с ними все понятно, я про конструкции типа {processor… и т.п.
И все-таки, не могу понять, где у тебя возвращается только строка? Можешь более развернутый пример дать? Я что-то вообще не улавливаю где там такие ограничения.
Я про функцию расширения smarty, вроде твоих smarty_plugins/*.php Я попробовал написать smarty_plugins/function.params.php:
?php function smarty_function_getprops($params, & $smarty) { if (!isset($params['name']) OR !$name = $params['name']) { return; } if(!empty($params['assign'])){ $assign = (string)$params['assign']; } $output=$smarty->modx->getObject('modPropertySet',array('name'=>$name))->getProperties(); return !empty($assign) ? $smarty->assign($assign, $output) : $output; }
Как я понял, эти функции только строку возвращают
Кстати, а если в функцию расширения function.processor.php добавить еще один параметр, например, props, который будет подставлять в вызов процессора набор параметров, взятый из MODX? по той же схеме, как делает ns?
Ну, например,
{processor name="some_processor" ns="namespace" props="some_props_name"}
Как я понял, эти функции только строку возвращают
Нет, ты не правильно понял. Ты имей ввиду, что даже если ты в шаблоне написал {$var}, тебе не $var сразу возвращается, а $_smarty_tpl->getVariable('var')->value. То есть все прогоняется через Smarty-объект в любом случае. А результат подобных функций может быть абсолютно любым, даже объектом. {processor} же возвращает результат-массив. Посмотри что там в функции прописано.
Кстати, а если в функцию расширения function.processor.php добавить еще один параметр, например, props, который будет подставлять в вызов процессора набор параметров, взятый из MODX? по той же схеме, как делает ns?
Идея по-моему довольно здравая. Допиши эту функцию и оформи топик, погоняем, и может действительно и включим в пакет. Только имей ввиду, что нормальная практика перечислять сразу несколько наборов, к примеру {snippet name=«snippet@propertySet1@propertySet2@propertySet3»}
непойму почему, настроил так ? вставил в главный шаблон {snippet name=«Wayfinder@TopMenu»}
но на главной нечего не выводит. на странице категории выводит дочерние категории, если их нет то нечего. если убрать templates=2 то выводит товары текущей категории не пойму как связно меню с текущей страницей. До этого кстати создавал меню с похожими настройками, оно нормально отображается. Правда вставлял я его в шаблон category.tpl
А этот набор параметров со сниппетом связали?
?
Судя по всему вы этого не сделали, параметры не учитываются и WF тупо пытается получить дочерние документы.
если бы параметры не учитывались то он бы не выводил в моем шаблоне, всмысле эти параметры то учитываются ?
ну и на всякий случай ?
вроде как надо ну и как я писал если убрать templates=2 то выводит товары текущей категории
У вас по-моему написано не startId, а startid (то есть с маленькой i). Довольно распространенная ошибка. Тоже может быть дело в ней, из-за чего так же будут выводиться только дочерние документы. И пока уберите из параметров свои шаблоны, чтобы быть уверенными, что в шаблонах тоже нет косяка.
вы правы, дело в регистре, спасибо
Хорошая статья, но картинки не грузятся. Не могли бы восстановить изображения?
Восстановил. Спасибо за багрепорт!
Вам спасибо за отличные статьи!

Добавить комментарий