Widget

97 views
Skip to first unread message

Андрей Баранов

unread,
Jul 18, 2011, 10:31:36 AM7/18/11
to ru-zend-...@googlegroups.com
Интересно знать кто как реализовывает "идею виджетов" в Zend MVC.
Под виджетами я понимаю повторяемые "блоки"/контроллеры на разных генерируемых HTML страницах, и даже в пределах одной страницы, к примеру: форма авторизации, голосования, рекламный блок, и т.д и т.п., В моем понимании меню (главное, неглавное, повторяемые элементы навигации) тоже виджеты. В joomla виджеты называются модулями, в bitrixе - компоненты (точнее там все компаненты - но это не суть)

Я решил пойти таким путем: 
По сути своя реализация плагина ActionStack.
в routeStartup стек виджетов наполняется из, допустим, файла конфигурации, или БД.

"Основной контроллер", обрабатывающий запрос, может дополнять, удалять, модифицировать этот стек

в postDispatch, в своем собственном цикле диспетчеризации, отличном от диспетчеризации FrontControllera, "исполняются контроллеры", помещая результат работы в определенную метку заполнения. Причем никакие плагины, помимо Pre- и Post-Dispatch самого контроллера, не задействованы.
-----------------
Сейчас столкнулся с тем, что мне не помешал бы функционал "Виджет в виджете" и "виджет в основном контроллере", точнее уже вроде придумал как красиво это реализовать в рамках моей логики :)

--------------------
Интересно кто что думает об этом. Если удалось вменяемо и сжато объяснить... :) 
Может мысли подскажите, ссылками поделитесь, хотя возможно я это уже и читал....
Или кратко расскажите как Вы реализовывали/ваете подобное, саму суть чтоб понять идею

Денис Кириченко

unread,
Jul 18, 2011, 10:48:35 AM7/18/11
to ru-zend-...@googlegroups.com
Есть своя реализация MVC.
Что бы было нягляднее, см. диаграмму в аттаче.
Код тоже в аттаче..
собственно, все что тебе нужно это - Ik_Cms_Block_Abstract
Этот класс полностью выполняет все те функции, что ты описал.
+ У нас есть в MongoDB коллекция так называемых Inode, что по сути есть единицей контента. которые могут быть связаны между собой, а так же иметь внутри неограниченное количество модулей и данных для них.
Будут вопросы - задавай.


18 июля 2011 г. 17:31 пользователь Андрей Баранов <andre...@gmail.com> написал:



--
С уважением, Денис Кириченко.
Ik_Cms.png
Ik.zip

Olekhy Khutoretsky

unread,
Jul 18, 2011, 11:49:02 AM7/18/11
to ru-zend-...@googlegroups.com
A почему не устраивают View Helpers
или я вообще не в тему?
wkr
--
OK



2011/7/18 Денис Кириченко <zedro...@gmail.com>

Андрей Баранов

unread,
Jul 18, 2011, 11:51:45 AM7/18/11
to ru-zend-...@googlegroups.com
Такого ответа неожидал, большое спасибо :)
Прям готовое решение моей задачи, хотя и требует кое какого рефакторинга моей архитектуры, и можно внедрять предложенную логику Ik_Cms_Block_Abstract
Мое решение конечно в задумке было проще (но ток в задумке), зато тут более функциональное и логичное :)
Единственное я склоняюсь не объявлять новый класс блока (Ik_Cms_Block_Abstract), а унаследовать от Zend_Controller_Action (что в принципе у меня и сделано, поэтому рефакторинг незначительный). Надо подробней рассмотреть этот вопрос, может гдето ошибаюсь :) Может и никчему, у меня просто эти виджеты сейчас обрабатывает Zend_Controller_Dispatcher_Standard...

ЗЫ а какие права на использование кода/идеи? :)

Olekhy Khutoretsky

unread,
Jul 18, 2011, 11:55:01 AM7/18/11
to ru-zend-...@googlegroups.com
Вот что то помоему интересное

http://www.doctrine-project.org/docs/orm/2.0/en/cookbook/strategy-cookbook-introduction.html?highlight=strategy

--
OK



2011/7/18 Olekhy Khutoretsky <ole...@googlemail.com>

Денис Кириченко

unread,
Jul 18, 2011, 2:44:02 PM7/18/11
to ru-zend-...@googlegroups.com
Если не сильно вникать в код, а подходить как к абстрактной задаче, то тут идеи вот в чем:
- блоки - это и есть контроллеры, только у них по умолчанию действие не "index", а "view" или же "render" (просто "render" больше за отрисовку по смыслу отвечает.)
- блоки могут быть в композите с самими собой, проще говоря, быть вложенными, а так же каждый элемент композита должен "видеть" и иметь доступ ко всем элементам композита (см. функцию getBlock() (BLOCKs COMPOSITE))
- отображение всех "детских" блоков производиться исключительно через плэйсхолдеры этого блока (см. в коде PLACEHOLDER). Так же нужно понимать, что есть плейсхолдеры Глобальные! и есть локальные конкретного блока.
- у на блоки можно повесить плагины. смысл 1 в 1 с хелперами экшн-контролов.. вот только в моей реализации есть поддержка так называемых "дружеских" классов, то что есть в таких языках прогр. типа C++ и др. что позволяет "дружескому" классу, т.е. плагинам вызывать приватные функции блока, а так же обращаться к их приватным переменным.
- собственно в ключе CMS очень тут важен аспект информационного элемента (узла). назвал я его "Inode" (information node). Это храниться в какой то БД и полностью описывает страницу, вложенные элементы и их связи.
- а так же должен упомянуть про вспомогательные классы зендовского MVC, такие как: Ik_Cms_Controller_Plugin_BlockLayout (отвечает за подключение внешнего (родительского) блока) и Ik_Cms_Controller_Router_Route_Inode (отвечает за ЧПУ ссылки для навигации по нодам (страницам)).

Ну и еще приведу пример Inode из MongoDB:

array (
  'children' =>
  array (
    0 => new MongoId("4d415e1d8f2a2dd008030000"),
    1 => new MongoId("4d41607b8f2a2d8408040000"),
    2 => new MongoId("4d18ad6d8f2a2d8c03000000"),
    3 => new MongoId("4d4161158f2a2dd008080000"),
    4 => new MongoId("4d4163058f2a2d84080b0000"),
    5 => new MongoId("4d4163fe8f2a2d84080d0000"),
    6 => new MongoId("4d4164078f2a2d880e0b0000"),
  ),
  'createdAt' => new MongoDate(1291481447, 0),
  'createdBy' => 'denis',
  'mods' =>
  array (
    'block' =>
    array (
      'options' =>
      array (
        'params' =>
        array (
          'noRender' => true,
        ),
        'parentBlock' =>
        array (
          'type' => 'page',
          'options' =>
          array (
            'blocks' =>
            array (
              0 =>
              array (
                'type' => 'inodePartnerList',
                'placeholder' => 'left-panel',
              ),
              1 =>
              array (
                'type' => 'inodeClientList',
                'placeholder' => 'left-panel',
              ),
              2 =>
              array (
                'type' => 'inodeNewsList',
                'options' =>
                array (
                  'template' => 'default1',
                ),
                'placeholder' => 'header',
                'priority' => 1,
              ),
              3 =>
              array (
                'type' => 'paysystemList',
                'placeholder' => 'header',
                'priority' => 2,
              ),
              4 =>
              array (
                'type' => 'static',
                'placeholder' => 'header',
                'options' =>
                array (
                  'template' => 'intro',
                ),
                'priority' => 3,
              ),
            ),
          ),
        ),
        'plugins' =>
        array (
          1 =>
          array (
            'plugin' => 'inodePage',
          ),
        ),
        'template' => 'default',
      ),
    ),
    'page' =>
    array (
      'title' =>
      array (
        0 =>
        array (
          'l' => 'ru',
          'v' => 'Заглавная',
        ),
      ),
      'status' => 2,
      'author' => 'Denis Kirichenko',
      'desc' =>
      array (
        0 =>
        array (
          'l' => 'ru',
          'v' => 'Заглавная страница сайта',
        ),
      ),
      'tags' =>
      array (
        0 =>
        array (
          'l' => 'ru',
          'v' => 'Заглавная главная',
        ),
      ),
    ),
    'menuItem' =>
    array (
      'type' => 'self',
    ),
  ),
  'type' => 'page',
)

array (
  'ancestors' =>
  array (
    0 => new MongoId("4d18ad6d8f2a2d8c03000000"),
    1 => new MongoId("4cfa7167e56645b80a000000"),
  ),
  'createdAt' => new MongoDate(1304517631, 0),
  'createdBy' => 'denis',
  'mods' =>
  array (
    'page' =>
    array (
      'author' => 'Denis Kirichenko',
      'path' => 'news/1',
      'status' => 2,
      'title' =>
      array (
        0 =>
        array (
          'l' => 'ru',
          'v' => 'Новость 1',
        ),
      ),
    ),
    'news' =>
    array (
      'title' =>
      array (
        'l' => 'ru',
        'v' => 'Интернет провайдер "Домашняя сеть" принимает теперь платежи через Interkassa',
      ),
      'desc' =>
      array (
        'l' => 'ru',
        'v' => 'Мы построили и продолжаем современную опто-волоконную сеть связи, и с ее помощью внедряем новейшие технологи Интернет. Каждый жилой дом',
      ),
      'body' =>
      array (
        'l' => 'ru',
        'v' => 'Мы построили и продолжаем современную опто-волоконную сеть связи, и с ее помощью внедряем новейшие технологи Интернет. Каждый жилой дом asddfgdsfgds sadsafsdf sdf sdfsdfsdf',
      ),
    ),
  ),
  'type' => 'news',
)

Код, как ты уже понял не подпадает под какие то права :)) ибо я не жадный :))

18 июля 2011 г. 18:51 пользователь Андрей Баранов <andre...@gmail.com> написал:
Reply all
Reply to author
Forward
0 new messages