Сразу замечу, что я здесь опущу мелкие детали, что бы не потерять "стратегичекую" мысль))). Лишь бы уловить саму логику. Пишу больше для себя, ибо трудно в голове держать все связи. Но думаю, будет интересно и тем, кто хочет всегда все знать глубоко.
Здесь я уж касался темы TV(Template Variable). Со временем стал все сильнее меня мучить вопрос: как это все функционирует "изнутри". И вот пока выдалось более-менее свободное время, решил поразбираться. Вообще "погружение" в исходники MODX весьма увлекательное и полезное занятие. Поскольку документации даже на английском весьма мало.
Ну надо уяснить что в самом TV - ничего сложного, создается элементарно. Самое интересное в написании своих типов ввода и вывода. Типы ввода - для backend(контекст менеджера). Типы
вывода - для отображения на странице(web context) с помощью тэга [[*имя_TV]]
.
Все что мы видим в менеджере - это виджеты. Т.е. JS код. Реализованный на ExtJS(фреймворк ява-скрипта). И механизмы общения с сервером стандартные:
{"success":true,"total":"2","results":[{"name":"URL","value":"url"},{"name":"Vologda-2","value":"Vologda-2"}]}Это годится для получения списков типов ввода и вывода. И не подходит для отрисовки свойств типов TV в менеджерe
$scriptProperties=Array ( [action] => element/tv/renders/getProperties [context] => mgr [tv] => 9 [type] => image )
$tv=Array ( [id] => 9 [source] => 1 [property_preprocess] => [type] => image [name] => test_botton [caption] => [description] => [editor_type] => 0 [category] => 12 [locked] => [elements] => [rank] => 0 [display] => image [default_text] => [properties] => Array ( ) [input_properties] => Array ( [allowBlank] => true [maxLength] => [minLength] => ) [output_properties] => Array ( [alttext] => [hspace] => [vspace] => [borsize] => [align] => none [name] => [class] => as_b [id] => 455667 [style] => color: red; [attributes] => v="6" ) [static] => [static_file] => [content] => )
В родной документации обработчики входных типов(на стороне сервера) называются контроллерами.
Наиболее просто добавить свой контроллер - это поместить его в каталог "..../core/model/modx/processors/element/tv/renders/mgr/input/". И он сразу появится в списке входных типов при создании TV. Вопрос: почему в каталоге процессоров?
Ответ: потому что виджет списка входных типов использует стандартный коннектор, который подключает стандартные процессоры:
Вот например для отрисовки TV в менеджере:
Виджеты TV можно найти в каталоге "..../manager/assets/modext/widgets".
Обработчик на сервере(PHP - файл) на самом деле является процессором (class modTvRendersGetPropertiesProcessor extends modProcessor
).
Так вот этот процессор делает следующее:
$this->templatesPaths=Array ( [0] => .........../manager/templates/default/ )
$renderDirectories=Array ( [0] => ......../core/model/modx/processors/element/tv/renders/mgr/inputproperties/ [1] => ......../core/components/gallery/elements/tv/inputoptions/ [2] => ......../core/components/ourtvs/tv/inputoptions/ )
Вот так..... И эта куча кода только для того, чтобы найти и пропарсить шаблон. И вернуть его обратно в виджет. А виджет отобразит его уже в менеджере. Не покидает ощущение, что можно сделать проще. Ну да ладно. Со стороны всегда виднее))).
Ну тут все аналогично.
$renderDirectories=Array ( [0] => ......../core/model/modx/processors/element/tv/renders/mgr/input/ [1] => ......../core/components/gallery/elements/tv/input/ [2] => ......../core/components/ourtvs/tv/input/ )
Таким образом, процессор возвращает:
{"success":true,"total":"25","results":[{"name":"URL","value":"url"},{"name":"Vologda-2","value":"Vologda-2"},{"name":"galleryalbumlist"....
ВЫХОДНЫХ
типов TVА вот тут не все аналогично.
$renderDirectories=Array ( [0] => .............../core/model/modx/processors/element/tv/renders/web/output/ [1] => .............../core/components/gallery/elements/tv/output/ [2] => .............../core/components/ourtvs/tv/output/ )
Таким образом, процессор возвращает:
{"success":true,"total":"25","results":[{"name":"URL","value":"url"},{"name":"Vologda-2","value":"Vologda-2"},{"name":"galleryalbumlist"....
$renderDirectories=Array ( [0] => ......../core/model/modx/processors/element/tv/renders/mgr/properties/ [1] => ......../core/components/gallery/elements/tv/properties/ [2] => ......../core/components/ourtvs/tv/properties/
Здесь как ни странно все без процессоров. По крайней мере на уровне интерфейса. TV стразу встраиваются в страницу на сервере.
$this->action='resource/update' $this->namespace='core'
$paths=Array ( [0] => ...../manager/controllers/default/ [1] => ...../manager/controllers/ )
очень важная вещь!!!
определяются пути где ищутся котроллеры. $subdir='input'
$pluginResult=Array ( [0] => /home/aset/data/www/cppv.fvds.ru/mdx/core/components/gallery/elements/tv/input/ [1] => /home/aset/data/www/cppv.fvds.ru/mdx/core/components/ourtvs/tv/input/ )
Да. Все очень сурово... Это сколько нужно времени и мозгов...Хотя в официальной документации и рекомендуют использовать пространство имен(NS), вместо "плагинов путей", но тут видно, что при формировании массива путей контроллеров для TV(input-render), про NS явно забыли. По крайней мере в моей версии(2.3).
Вызываются сразу 2 процессора:
element/propertyset/updatefromelement
'. - тут сохраняются наборы параметров(propertyset). Нам пока это не интересно.element/tv/update
'. Вот тут похоже сохраняется сам TV со всеми свойствами(параметрами).
$inputProperties=Array ( )
$outputProperties=Array ( [alttext] => Рисунок [hspace] => 10 [vspace] => 11 [borsize] => 12 [align] => middle [name] => pic [class] => as_b [id] => 455667 [style] => color: red; [attributes] => v="6" )
<field key="input_properties" dbtype="text" phptype="array" null="true"/>
$this->getProperties()=Array ( [action] => element/tv/update [templates] => {} [resource_groups] => {} [sources] => [{"context_key":"web","source":"1","name":"Filesystem","menu":null}] [propdata] => [] [id] => 9 [props] => [name] => test_botton [caption] => [description] => [static_file] => [category] => 12 [rank] => 0 [locked] => 0 [clearCache] => 1 [static] => 0 [source] => 1 [propertyset] => По умолчанию [property_preprocess] => 0 [type] => image [els] => [default_text] => [display] => image [prop_alttext] => Рисунок [prop_hspace] => 10 [prop_vspace] => 11 [prop_borsize] => 12 [prop_align] => middle [prop_name] => pic [prop_class] => as_b [prop_id] => 455667 [prop_style] => color: red; [prop_attributes] => v="6" [ext-comp-1062] => 20 [ext-comp-1079] => 20 )
В отличие от всех предыдущих случаев, здесь инициатором служит не виджет(через коннектор), а парсер MODX. Например, для отображения TV типа img запускается скрипт по пути:
'core/model/modx/processors/element/tv/renders/web/output/image.class.php'Там описан класс - потомок modTemplateVarOutputRender(потомок - modTemplateVarRender).
Array ( [alttext] => Кому на руси жить хорошо. фото Медведев Д. [hspace] => 10 [vspace] => 11 [borsize] => 12 [align] => middle [name] => pic [class] => as_b [id] => 455667 [style] => color: red; [attributes] => v="6" )т.е. и есть свойства вывода. Кто-то уже заботливо считал json из базы и преобразовал в массив(ассоциативный).
Вот теперь многое прояснилось. Причем не только в TV. Но и в логике всей системы. Обработка входных и выходных параметров для TV сделана очень хорошо. На мой взгляд. Жаль что в "modTemplateVarResource" поле "value" имеет phptype="string". Если б было "array" было бы легче с "комплексными" TV(когда TV имеет много полей). Хотя может это мало кому требуется. В принципе и так хорошо. Пол года назад, прочитав все это, я б наверное в душе обложил матюгами разработчиков))). Но теперь понимаю что это очень круто. Не перестает поражать продуманность и гибкость. Т.е. одно и то же, можно сделать несколькими путями. Например, можно воспользоваться стандартными каталогами для контроллеров TV. А можно определить свои. Причем опять же двумя методами. Через пространство имен, и через плагин. Ладно, это все хорошо. Теперь попробую уже на другом уровне познания создать TV со своими типами ввода, вывода и отображением в WWW так как умные люди это делают .
Комментарии 0