"Супер-хуки" в шаблонах - вставка кода в любое место

Для начала хочу напомнить тем, кто забыл (и поставить в известность тех, кто не знал), что так уж исторически сложилось, что плагин aceAdminPanel – это не просто инструмент администратора сайта, но еще и некая надстройка над самим движком, которая добавляет движку какие-то фичи, которых, на мой взгляд, ему, порой, не хватает.

Вот и сейчас я хочу рассказать о новой классной фиче, которая, на мой взгляд, может оказать такое же революционное влияние на развитие движка (уж простите за нескромность), которое на него оказала реализация идеи плагинов с автонаследованием.

Если кратко, то суть такая: в шаблонах можно задавать практически произвольные точки (назовем их HTML-хуки или DOM-хуки) с помощью CSS-селекторов а-ля jQuery для вставки своего кода.

А теперь подробнее.

До сих пор было всего две возможности из плагина как-то изменять шаблон: либо делегированием, либо с помощью хуков.

Делегирование хорошо тем, что позволяет полностью видоизменять любой шаблон. Но огромный недостаток в том, что только один плагин может делегировать конкретный шаблон. И в этом нередко кроются корни несовместимости плагинов.

Хуки в шаблонах — это реально прорыв. Один хук может неоднократно использоваться разными плагинами. Но и тут есть один серьезный недостаток — хуки стоят в заранее заданных местах. И разработчики, вынуждены бегать вокруг них, как бычки на короткой привязи, что, разумеется, никак не способствует гибкости в плане адаптации шаблонов под свои нужды.

Я довольно долго вынашивал идею гибкой модификации шаблонов на этапе компиляции. И вот, наконец, смог ее реализовать.

Итак, HTML-хук — супер-хук в шаблонах.

Чтоб не размазывать манную кашу по белому листу, я сразу приведу пример. HTML-хуки задаются в файле конфигурации скина /templates/skin/<имя_скина>/settings/config/config.php таким вот образом:
$config['view']['hooks'] = array(
// ex. 1
    array(
        'template' => 'header_top.tpl',
        'selector' => '#nav-main li:nth-child(2)',  // равнозначно 'selector' => '#nav-main li:eq(1)',
        'action' => 'after',
        'content' => Plugin::GetTemplatePath('aceblogextender') . 'hook.header_top.li.tpl',
    ),
// ex. 2
    array(
        'template' => '/ActionTopic/add.tpl',
        'selector' => 'select#blog_id:parent',
        'action' => 'replace',
        'content' => Plugin::GetTemplatePath('aceblogextender') . 'hook.select_blog.tpl',
    ),
);

Тем, кто более-менее знаком с jQuery, наверное, можно ничего не объяснять – по-моему, и так все ясно с первого взгляда. Но для тех, кто с первого взгляда не понял, дам небольшие пояснения.

Пример 1

При компиляции шаблона header_top.tpl, в нем будут искаться элементы #nav-main li:nth-child(2) и после них будет вставлен контент, который находится в шаблоне 'hook.header_top.li.tpl' плагина 'aceblogextender'.
Т.е., если в исходном шаблоне был такой код:
<ul id="nav-main">
  <li>Item A</li>
  <li>Item B</li>
</ul>
<ul id="nav-main">
  <li>Item A</li>
  <li>Item B</li>
  <li>Эта строка была вставлена</li>
</ul>


Пример 2

В шаблоне, полный путь к которому который заканчивается строкой /ActionTopic/add.tpl, будет найден родитель элемента select#blog_id и заменен кодом из заданного файла.

Ну, и т.д. Причем, заметьте, такое описание можно сделать для каждого скина. По-моему, гибче уже некуда.

И в заключение сразу дам ответы на ожидаемые вопросы:

1. Насколько полно поддерживается синтаксис CSS-селекторов?
Почти полностью. Не поддерживается пока синтаксис типа 'E * F', не все еще псевдоклассы реализованы, и сами псевдоклассы могут пока применяться лишь к последнему элементу цепочки

2. Какие значения могут быть заданы в параметре action?
after — добавление контента после каждого элемента набора
before — добавление контента перед каждым элементом набора
append — добавление контента внутрь (в конец) каждого элемента набора
prepend — добавление контента внутрь (в начало) каждого элемента набора
replace — замена каждого элемента набора
html — замена HTML-контента каждого элемента набора
text — замена текстового контента каждого элемента набора

3. А можно ли в вставляемом контенте использовать команды/переменные/директивы Smarty?
Да, никаких ограничений нет. Если до вставки контента в шаблоне определена, например, переменная $oTopic, то вы можете ее использовать в вставляемом контенте.

4. Насколько использование этих хуков замедляют время отдачи сайтом контента?
Ни насколько! Хуки отрабатываются только во время компиляции соответствующего шаблона. Если шаблон скомпилирован, и исходные файлы шаблона не меняются, то Smarty не проверяет наличие хуков и не выполняет никаких лишних операций.

Жду реакции разработчиков — очень интересно услышать ваши мнения по поводу этой штуки

60 комментариев

avatar
Очень здоровская и полезная штука, действительно сталкивался с такой ситуаций и приходилось выводить темлейт по соседнему хуку, дальше самым настоящим костыльным способом перемещать его с помощью jquery. Будь такая возможность все вышло бы красиво и лаконично. Одназначно за то что бы было нативно в livestreet'е, т.к админка будет не у всех, а делать проверки на наличие админки от костыльности не избавляет.

И абсолютно согласен что это прорыв, не привычно, все таки новое решение, но действительно нужное для разработчиков. Добавит килотонны гибкости в работу с шаблонами :)
avatar
приходилось выводить темлейт по соседнему хуку, дальше самым настоящим костыльным способом перемещать его с помощью jquery
Занимался тем же самым, пока не достало и решил перенести это на сторону сервера
avatar
Автору респект за реализацию. С точки зрения реализации — качественный продукт.
Но за весь дальнейший свой текст извиняюсь сразу, так как возможно для кого-то он покажется оскорбительным, ибо буду критиковать Livestreet…
Почему вообще требуются подобные хаки, чтобы хоть как-то вклиниться в логику? Зачем вообще было так сильно логику вшивать в шаблоны со всеми его IF-ами, ELSE-ми, include-ами и т.п. Это просто ппц.
Мне вот в MODX никогда в голову не приходило, что могут понадобиться такие хаки.
В MODX есть сущности:
— Сниппет — Блок PHP-кода
— Чанк — Блок HTML-кода
Если мне в шаблоне где-то надо вставить просто сторонний HTML-блок, я в шаблоне воткну [[$chunk]]. Если мне надо вставить логику, то я вставлю сниппет [[Snippet]], и отделю логику от шаблонизации, так как в сниппете будет чистый PHP, но если мне понадобится вывод оформить в HTML-шаблон, я внутри сниппета получу чанк и наполню его данными.
При этом сниппеты можно вкладывать в чанки и другие сниппеты, а чанки в другие чанки и сниппеты. Это как раз типа ваших хуков, но не надо и прописывать в нескольких местах. А то у вас потом получается, что за каждой строчкой в шаблоне приходится думать «а не вставить ли тут на всякий случай еще один хук, а то вдруг какому-нибудь разработчику здесь надо будет выполнить свой хук?».
Да и где управление очередностью вызовов хуков? Какой плагин вперед инициализировался, того и тапки? А что, если в одном шаблоне надо, чтобы сначала вызвался хук первого плагина, а потом второго, а в другом случае наоборот?
Это первый момент, локальный.
Второй момент, глобальный: кеширование. Вот у вас все выполняется в момент компиляции шаблона, то есть тупо шаблон конечный набивает (данный вопрос конкретно к автору, но коммент не персональный, а общественный, так как конкретно к автору никаких претензий). А если надо управлять кешированием? В MODX я просто ставлю восклицательный знак, что говорит о том, что элемент не кешируется, и каждый раз по новой выполняется, даже если весь документ закеширован. То есть ставлю [[!snippet]] и все.
Третий момент. Эти оба примера — локальные действия внутри конкретной точки шаблона. А если нужно выполнить какое-то действие глобально над всем документом, или до определения документа (чтобы можно было осуществить подмену, или в момент генерации документа, или после его генерации и т.д.)?
В MODX нативно зарезервировано 168 системных событий (плюс сколько угодно можно своих зарезервировать), на каждое из которых можно навесить свой плагин и определить последовательность вывода наряду с другими плагинами. При этом не надо на все случаи жизни инициализировать весь плагин со всеми его конфигами, классами и т.п. В нужный момент инициализируется и выполнится только та часть плагина, которая нужна.
В итоге получается полная управляемость всем проектом.
В общем, чем больше я узнаю Livestreet, тем больше убеждаюсь, что интеграция с MODX — ему очень даже нужна, так как он получает много того, чего там скорее всего вообще никогда не появится в силу особенностей движка.
И поверьте мне, что я знаю о чем говорю, так как знаю Livestreet уже очень неплохо, но все равно большинство проблем, с которыми сталкиваюсь, с легкостью решаю именно с помощью MODX-а.
avatar
Я не использовал modx и не знаю его логику. Хотелось бы уточнить. Разрабатывая плагин на livestreet мы за пользователя вещаем какие то действия по хуку(сейчас речь только о шаблонах). Т.е пользователю даже палец о палец ударить не приходится. Некоторые разработчики при отсутствии хуков просят его добавить руками в шаблонах.

Как я понимаю modx позволяет вставлять эти самые «хуки» руками через админку.

Если так то это не панацея.
avatar
Уточняю. Есть разные вариант:
1. Это вставить свой чанк, сниппет или другой MODX-объект в шаблон, и он будет выполнен MODX-парсером конкретно в этом месте. Это локальный метод, и если это действие выполняется на стороннем шаблоне, то да, с ками согласен — не кашерно это.
2. Но есть более глобальный способ — то есть выполнение своего плагина по системному событию. То есть даже если взять пример из сабжа, то в MODX мне со своим плагином не пришлось бы ждать вызова хука из шаблона (тем более что шаблон мог бы быть замененным или измененным, и этого хука там вообще могло уже не быть прописано, а значит и хук не будет вызван). Я бы создал свой сторонний плагин, и навесил бы его на событие OnWebPagePrerender.
В момент парсинга страницы MODX-парсером, он вызвал бы по этому событию мой плагин, а я бы в плагине смог бы получить весь скомпелированный контент страницы $modx->resource->_output, и выполнить с ним все нужные мне манипуляции, в том числе обработку отдельных HTML-элементов.
Там же я мог бы прописать кеширование через $modx->cacheManager->set()/get(), и снизить нагрузку, если надо. То есть я бы выполнил все нужные мне манипуляции со всем контентом текущей страницы, и не вклинивался бы в логику конкретно индивидуального сайта. При этом гарантированно работало бы независимо от того, если какой-то нужный плагин, или нет, так как это все нативный функционал.
avatar
Я бы создал свой сторонний плагин, и навесил бы его на событие OnWebPagePrerender.
В момент парсинга страницы MODX-парсером, он вызвал бы по этому событию мой плагин, а я бы в плагине смог бы получить весь скомпелированный контент страницы $modx->resource->_output, и выполнить с ним все нужные мне манипуляции, в том числе обработку отдельных HTML-элементов.
И чем же это концептуально отличается от вышепредставленного варианта? Только тем, что это в модксе, а это в лайвстрите?
avatar
Как минимум тем, что это нативно работает, а не
Одназначно за то что бы было нативно в livestreet'е, т.к админка будет не у всех, а делать проверки на наличие админки от костыльности не избавляет.
.
Плюс к этому, в плагин передается не только контент (как в данном решении), но и другие важные данные, которые могут понадобиться плагину.
Есть еще куча плюсов, которые сейчас мне бессмысленно объяснять, так как у вас сейчас позиция, которая мешает вашему восприятию полезной информации.
avatar
Как минимум тем, что это нативно работает
Было время, когда в MODX вообще ничего нативного не было. Потому что это был не самостоятельный движок, а модуль к другой CMS :)

В ранних версиях и в ЛС тоже много чего не было, даже плагинов. И, для справки, когда технология автонаследования, которая сейчас активно в сторонних плагинах юзается, была впервые реализована именно в админке, как расширение родного функционала движка. Сейчас это нативная фича ЛС.

Плюс к этому, в плагин передается не только контент (как в данном решении), но и другие важные данные, которые могут понадобиться плагину
А кто Вам сказал, что передается контент? Передается шаблон Smarty, и Вы можете использовать все переменные, которые загружены в Smarty, весь синтаксис шаблона, включая те же инклюды и проч.
avatar
Ты тоже извини, но уже начинает поднадоедать ежедневное вещание(в тч и регулярные топики) за modx на сайте лайвстрит и на хабре. Точнее даже не они сами (интеграции, плагины это всегда круто, выложи в каталог, я уверяю — все только поддержат, в том числе и я), но зачем постоянно и везде вещать в ключе, какой лайвстрит убогий, а какой модкс молодец? Дикое желание переубедить народ? Желание быть признанным? Забавно прийти в клуб любителей джаза и начать убеждать всех, что рок то круче, чего вы этот сраный джаз слушаете.

beauty_free все правильно заметил насчет ручной настройки. Ничто не мешает также все вставить хуками (вообще не потребуется вмешательства пользователя), или на крайняк в tpl что то поправить(или просто новый хук добавить). В чем различие со вставкой чанков и сниппетов? В том, что это в интерфейсе, а tpl по фтп? Все?
Лайвстрит же идет в сторону более законченного коробочного продукта. Я не представляю как можно, например, покупателей плагинов просить «а вот тут вот в шаблончике вставьте сниппет/чанк новый инклуд/хук». Им это не нужно — изучать умные слова сниппет и чанк и как чего куда вставлять, без разницы — в интерфейсе или по ФТП. Им нужно плагин поставить и чтобы в идеале сразу все заработало. Да и слово хук многие признают ругательным.

В общем, чем больше я узнаю Livestreet, тем больше убеждаюсь, что интеграция с MODX — ему очень даже нужна
Она очень нужна в каталоге в виде модуля, а не в комментариях/топиках/холиварах с поучительным тоном.
Все мое личное мнение, конечно же. Nothing personal.
avatar
beauty_free все правильно заметил насчет ручной настройки.
Читайте коммент выше. пункт 2. Там написано, что можно не только руками делать.

Лайвстрит же идет в сторону более законченного коробочного продукта. Я не представляю как можно, например, покупателей плагинов просить «а вот тут вот в шаблончике вставьте сниппет/чанк новый инклуд/хук».
Если вам лень читать надоевшие топики и вникать, вы хоть видео посмотрите здесь: livestreet.ru/blog/13035.html
Там весь Livestreet со всеми плюшками, в том числе и для MODX ставится в пару кликов, и не требует вообще ни одной настройки от пользователя, разве что для главной страницы MODX указать из списка другой шаблон. Это я вам скажу, куда более гораздо ближе к коробочности, чем что-либо, так как при установке в пакете можно обратиться к API MODX и проверить наличие всего, что только можно, и изменить/создать/удалить/настроить все что хочешь. Так что те, кто ставят мой модуль, вообще ничего лишнего не делают, но получают сразу полностью интегрированный продукт.

Она очень нужна в каталоге в виде модуля, а не в комментариях/топиках/холиварах с поучительным тоном.
Я уже модуль залил на livestreetcms.com, просто еще проходит модерацию, хотя очень сомневаюсь, что пройдет.
А на счет холиваров и надоевших топиков: много делается, потому и много пишется. И мне нужен фидбек, и я его получаю. А холивары — извините. Вы предпочли бы, чтобы все восхваляли «О какой Livestreet классный и законченный! Его не надо больше развивать, не вздумайте! Он уже просто суперсовершенный и все остальное — от лукавого!»? А как же развитие? Я не думаю, что я предлагаю что-то не конструктивное. А извините, развиваться Livestreet-у еще есть куда. Обратите внимание на разницу жалоб тех, кто только жалуется, и тех, кто решает возникающие сложности и говорит, как надо, чтобы было лучше. Я не новичок, который для себя вчера открыл тайны HTML, и знаю что говорю. Это еще не холивары. Холивары начались бы тогда, когда я стал бы выражать все свое мнение по поводу того, что livestreet.ru и livestreetcms.com — это два разных движка и две разные базы данных, что мне пришлось там сегодня повторно регистрироваться, и что там нет ни моего имени, ни моей фотографии, ни моей кармы, ничего вообще! Вот это повод для холиваров, вот это эмоции и мое личное отношение.
А то что я пишу — это сухое программирование.
avatar
Прочитав все это я окончательно понял что ModX нифига не удобнее и не проще в плане расширения. Вы говорите
Так что те, кто ставят мой модуль, вообще ничего лишнего не делают, но получают сразу полностью интегрированный продукт.

Мы же говорим о хуках и гибкости, которая необходима если вы будете ставить на свой проект стороннии плагины, и я к сожалению не увидел ни одного толкового ответа о том чем же modx удобен кроме как возможности расставлять хуки через админку, а не ковырянием в шаблоне.
avatar
Просто попробуйте поставить MODX и попробовать что-нибудь на нем напрограммировать. Вам так многое будет не понятно, так как парадигмы разработки вообще разные. Те, кто программирует и на Livestreet, и на MODX, понимают меня.
avatar
Те, кто программирует и на Livestreet, и на MODX, понимают меня.
пригласите их в топик
avatar
Fi1osof можете учитывать. Ну и меня с некоторой натяжкой :)
avatar
Там весь Livestreet со всеми плюшками, в том числе и для MODX ставится в пару кликов
А ЛС вообще сам по себе ставится в пару кликов. Так что не вижу, какие проблемы юзеров тут решаются. И если нужно будет на ЛС навешивать какие-то плагины или рисовать свои шаблоны, то это придется делать совершенно одинаково, что для «чистого» ЛС, что под MODX.

я стал бы выражать все свое мнение по поводу того, что livestreet.ru и livestreetcms.com — это два разных движка и две разные базы данных
Я сам этим крайне недоволен, но к движку и его возможностям это не имеет абсолютно никакого отношения
avatar
Так что те, кто ставят мой модуль
покажите их
avatar
какой лайвстрит убогий, а какой модкс молодец?
он наверное углубляться в возможности ЛС или код читать не хочет. док-и-то нет.
avatar
Нет, просто вероятней всего я достаточно хорошо уже разобрался и в LS, и в MODX. И могу аргументированно много в чем поспорить на счет LS. А ты сможешь со мной поспорить на счет MODX? Скорее всего нет, потому что не знаешь этого движка.
avatar
Она очень нужна в каталоге в виде модуля, а не в комментариях/топиках/холиварах с поучительным тоном.
Добавил еще 4-го числа, но до сих пор на премодерации.
avatar
Эх, давно не холиварили! :) ну, поехали!

Давайте сначала определимся — есть бизнес-логика, а есть логика отображения. В идеале в шаблоне не должно быть бизнес-логики вообще (для того и придуманы, собственно, шаблонизаторы). Но наличие в нем логики отображения — вполне нормальная вещь. Есть много вещей, которые вполне оправдано в шаблоне определяются динамически — классы, свойства и т.д. И утаскивать все это в экшены и модули, на мой взгляд, глупо.

Если мне в шаблоне где-то надо вставить просто сторонний HTML-блок, я в шаблоне воткну [[$chunk]]. Если мне надо вставить логику, то я вставлю сниппет [[Snippet]], и отделю логику от шаблонизации
Сниппет — это PHP-код. А что такое PHP-код в шаблоне, если не логика? И если на этот код не накладывается особых ограничений, то такой подход просто провоцирует на перенос бизнес-логики в шаблон. Т.е. получаем гораздо более худший вариант, чем в шаблонах Smarty.

При этом сниппеты можно вкладывать в чанки и другие сниппеты, а чанки в другие чанки и сниппеты. Это как раз типа ваших хуков
Нет, это, скорее, типа директивы {include}, которая включает код из другого шаблона, который может включать в себя коды из других шаблонов и т.д.

Да и где управление очередностью вызовов хуков? Какой плагин вперед инициализировался, того и тапки?
Ну я же говорил, что Вы еще не достаточно хорошо знаете ЛС. При регистрации хука можно задавать приоритет для него и таким образом управлять очередностью. А админка, кстати, еще и приоритеты самих плагинов поддерживает.

Вот у вас все выполняется в момент компиляции шаблона
Нет, неверно. Есть кеширование данных (это отдельная нативная функция движка), и есть кеширование шаблонов. А есть компиляция шаблонов. Т.е. это три разных, независимых друг от друга процесса. Сам Smarty позволяет весьма гибко управлять процессами компиляции и кеширования (чем, собственно, автор и воспользовался для реализации описанной выше идеи). Но надо признать, что на самом «верхнем» уровне движок таких инструментов не дает, и чтобы ими воспользоваться, нужно хорошо понимать архитектуру движка и самого шаблонизатора.

А если нужно выполнить какое-то действие глобально над всем документом, или до определения документа
Так а я что делаю в описанной реализации? Шаблонизатор позволяет выполнять любые действия над любым шаблоном аж в трех временнЫх точках — перед компиляцией шаблона, после компиляции шаблона, и непосредственно перед выводом готового HTML-кода. И это помимо всяких инклюдов, блоков и предопределенных шаблонных хуков. Можно делать с выводимым документом абсолютно что угодно без всяких ограничений. Но, повторюсь, эти возможности не лежат на поверхности, нужно копнуть чуть глубже.

В MODX нативно зарезервировано 168 системных событий
Сколько из в ЛС, я точно не знаю, но явно дофига — инициализация каждого экшена, начало и завершение вызова любого метода любого модуля и т.д., и т.п. — это все хуки, на которые можно цеплять методы своих плагинов, задавая приоритет вызова хуков. И, кстати, точно так же подгрузка классов плагина происходит по мере необходимости — грузятся только те, которые нужны.

В общем, чем больше я узнаю Livestreet, тем больше убеждаюсь, что интеграция с MODX — ему очень даже нужна
Пока я так этого и не увидел. Много слов, зачем Модексу нужен ЛС, но зачем проекту на ЛС нужен Модекс — не вижу. Но даже для первого случая такая тесная интеграция, которую Вы делаете — очень спорный вопрос. Кроме всего прочего — любой запрос страницы будет обрабатываться аж двумя движками. Вряд ли веб-серверу это будет полезно.
avatar
Эх, давно не холиварили! :) ну, поехали!
Не вопрос.
Сниппет — это PHP-код. А что такое PHP-код в шаблоне, если не логика?
Зайдите сюда: livestreet.ru/blog/
Там есть маленькое меню
Интересные
Новые +5
Обсуждаемые
TOP
Вот в шаблоне на это маленькое меню есть небольшой код в шаблоне:
{if $sMenuItemSelect=='index'}
	<ul class="nav nav-pills mb-30">
		<li {if $sMenuSubItemSelect=='good'}class="active"{/if}><a href="{cfg name='path.root.web'}/">{$aLang.blog_menu_all_good}</a></li>
		<li {if $sMenuSubItemSelect=='new'}class="active"{/if}>
			<a href="{router page='index'}newall/" title="{$aLang.blog_menu_top_period_all}">{$aLang.blog_menu_all_new}</a>
			{if $iCountTopicsNew>0}<a href="{router page='index'}new/" class="new" title="{$aLang.blog_menu_top_period_24h}">+{$iCountTopicsNew}</a>{/if}
		</li>
		<li {if $sMenuSubItemSelect=='discussed'}class="active"{/if}><a href="{router page='index'}discussed/">{$aLang.blog_menu_all_discussed}</a></li>
		<li {if $sMenuSubItemSelect=='top'}class="active"{/if}><a href="{router page='index'}top/">{$aLang.blog_menu_all_top}</a></li>
		{hook run='menu_blog_index_item'}
	</ul>
{/if}

{if $sMenuItemSelect=='blog'}
	<ul class="nav nav-pills mb-30">
		<li {if $sMenuSubItemSelect=='good'}class="active"{/if}><a href="{$sMenuSubBlogUrl}">{$aLang.blog_menu_collective_good}</a></li>
		<li {if $sMenuSubItemSelect=='new'}class="active"{/if}>
			<a href="{$sMenuSubBlogUrl}newall/" title="{$aLang.blog_menu_top_period_all}">{$aLang.blog_menu_collective_new}</a>
			{if $iCountTopicsBlogNew>0} <a href="{$sMenuSubBlogUrl}new/" class="new" title="{$aLang.blog_menu_top_period_24h}">+{$iCountTopicsBlogNew}</a>{/if}
		</li>
		<li {if $sMenuSubItemSelect=='discussed'}class="active"{/if}><a href="{$sMenuSubBlogUrl}discussed/">{$aLang.blog_menu_collective_discussed}</a></li>
		<li {if $sMenuSubItemSelect=='top'}class="active"{/if}><a href="{$sMenuSubBlogUrl}top/">{$aLang.blog_menu_collective_top}</a></li>
		{hook run='menu_blog_blog_item'}
	</ul>
{/if}

{if $sMenuItemSelect=='log'}
	<ul class="nav nav-pills mb-30">
		<li {if $sMenuSubItemSelect=='good'}class="active"{/if}><a href="{router page='personal_blog'}">{$aLang.blog_menu_personal_good}</a></li>
		<li {if $sMenuSubItemSelect=='new'}class="active"{/if}>
			<a href="{router page='personal_blog'}newall/" title="{$aLang.blog_menu_top_period_all}">{$aLang.blog_menu_personal_new}</a>
			{if $iCountTopicsPersonalNew>0}<a href="{router page='personal_blog'}new/" class="new" title="{$aLang.blog_menu_top_period_24h}">+{$iCountTopicsPersonalNew}</a>{/if}
		</li>
		<li {if $sMenuSubItemSelect=='discussed'}class="active"{/if}><a href="{router page='personal_blog'}discussed/">{$aLang.blog_menu_personal_discussed}</a></li>
		<li {if $sMenuSubItemSelect=='top'}class="active"{/if}><a href="{router page='personal_blog'}top/">{$aLang.blog_menu_personal_top}</a></li>
		{hook run='menu_blog_log_item'}
	</ul>
{/if}

{if $sPeriodSelectCurrent}
	<ul class="nav nav-pills nav-pills-dropdown mb-30">
		<li {if $sPeriodSelectCurrent=='1'}class="active"{/if}><a href="{$sPeriodSelectRoot}?period=1">{$aLang.blog_menu_top_period_24h}</a></li>
		<li {if $sPeriodSelectCurrent=='7'}class="active"{/if}><a href="{$sPeriodSelectRoot}?period=7">{$aLang.blog_menu_top_period_7d}</a></li>
		<li {if $sPeriodSelectCurrent=='30'}class="active"{/if}><a href="{$sPeriodSelectRoot}?period=30">{$aLang.blog_menu_top_period_30d}</a></li>
		<li {if $sPeriodSelectCurrent=='all'}class="active"{/if}><a href="{$sPeriodSelectRoot}?period=all">{$aLang.blog_menu_top_period_all}</a></li>
	</ul>
{/if}


Попробуйте дернуть этот шаблончик-меню себе в на другую страничку и немного подправить лигику.

В MODX там, где мне надо свое меню, я вставляю [[Wayfinder]]. Это все. Но это огорменный объект, который позволяет сделать какие угодно меню. Зайдите на http://modx.com/, вот какие менюшки найдете, в том числе и большое главное, все сделано на Wayfinder, и я вам гарантирую, что ни единая частица этого сниппета не была изменена, а все переоформляется через параметры.
Нет, это, скорее, типа директивы {include}, которая включает код из другого шаблона, который может включать в себя коды из других шаблонов и т.д.
Нет, это не одно и тоже. 1. Когда вы подгружаете include, вы подгружаете именно файл-шаблон, в котором будет HTML, и если вы захотите реализовать какую-то логику, то надо будет использовать API Smarty, и если надо выполнить хоть какие-то мелкие функции, их надо будет резервировать для Смарти. В MODX же вызывая сниппет, я вызываю чистый PHP.
2. Не все работаю со Смарти, им API Смарти может вообще не надо. В MODX можно вести разработку как со Смарти, так и без него.
Ну я же говорил, что Вы еще не достаточно хорошо знаете ЛС. При регистрации хука можно задавать приоритет для него и таким образом управлять очередностью. А админка, кстати, еще и приоритеты самих плагинов поддерживает.
Это глобально, а локально? Где мне в одном месте посмотреть какие хуки и в какой очередности будут вызваны именно в этом месте?
Сколько из в ЛС, я точно не знаю, но явно дофига — инициализация каждого экшена, начало и завершение вызова любого метода любого модуля и т.д., и т.п. — это все хуки, на которые можно цеплять методы своих плагинов, задавая приоритет вызова хуков. И, кстати, точно так же подгрузка классов плагина происходит по мере необходимости — грузятся только те, которые нужны.
Сколько из в ЛС, я точно не знаю, но явно дофига — инициализация каждого экшена, начало и завершение вызова любого метода любого модуля и т.д., и т.п. — это все хуки, на которые можно цеплять методы своих плагинов, задавая приоритет вызова хуков.
В классе ActionSettings 9 хуков. При этом взять даже этот кусочек
$this->Hook_Run('settings_tuning_save_before', array('oUser'=>$this->oUserCurrent));
if ($this->User_Update($this->oUserCurrent)) {
    $this->Message_AddNoticeSingle($this->Lang_Get('settings_tuning_submit_ok'));
    $this->Hook_Run('settings_tuning_save_after', array('oUser'=>$this->oUserCurrent));
} else {
    $this->Message_AddErrorSingle($this->Lang_Get('system_error'));
}
Да, хук выполняется. Ну а толку? Тут даже нет проверки каков результат выполнения хука. А стоит ли вообще дальше продолжать выполнение кода?
Единственный обработчик ошибок (пример), это
$this->Message_AddError($this->Lang_Get('settings_invite_available_no'),$this->Lang_Get('error'));
$bError=true;
Что он нам дает? Локальный флаг $bError = true, что ошибка в принципе есть, и сохранение ошибки $this->Message_AddError.
Это даже не $this->bError. А знаете почему $this->bError бессмысленно? Потому что в Livestreet все — $this.
Вот как выполняется логика в MODX:
$response = $modx->runProcessor($processorPath, $params);
if($response->isError()){
	return $response->getMessage();
}
$object = $response->getObject();
$message = $response->getMessage();
При этом процессор может вызывать другой процессор, а тот другой и так далее, но на выходе я все равно получу результат ->isError() и ошибку ->getMessage() независимо от того, в каком процессоре произошла ошибка.
В общем, я повторюсь, что в плане блого-движка со своей законченной логикой Livestreet — вполне достойный. Но в плане функциональных возможностей у него много ограничений, и хотя многое на нем можно сделать, это делается с лишними неоправданными сложностями. Это мы еще не коснулись политик доступов и т.п. Чтобы понять, что я имею ввиду, почитайте здесь: community.modx-cms.ru/blog/documentation/8918.html

Пока я так этого и не увидел. Много слов, зачем Модексу нужен ЛС, но зачем проекту на ЛС нужен Модекс — не вижу.
Результат вы очень скоро увидите. Маякну.

Кроме всего прочего — любой запрос страницы будет обрабатываться аж двумя движками. Вряд ли веб-серверу это будет полезно.
Рост нагрузки не очень большой. К тому же планируется более тесная интеграция (хочу выдернуть только самое важное из Livestreet и оформить конечную сборку MODX+Livestreet, и там нагрузка будет значительно меньше).

На сегодня холивары закончу, так как очень занят сейчас, но если надо будет, продолжу завтра.
avatar
На сегодня холивары закончу, так как очень занят сейчас, но если надо будет, продолжу завтра.
Не надо.
avatar
Вся первая половина этого большого текста уместилась бы в одной фразе — «в ЛС нет специального класса для создания и настройки меню, а в MODX — есть». Да, это так. И что?

Когда вы подгружаете include, вы подгружаете именно файл-шаблон, в котором будет HTML, и если вы захотите реализовать какую-то логику, то надо будет использовать API Smarty
И еще раз говорю Вам — глубже изучайте ЛС. Кроме include есть еще и insert для вставки элементов, называемых блоками, и в классе блока Вы можете на чистейшем PHP наворотить любую логику, какую только сможете себе вообразить, а потом отрендерить соответствующий шаблон, и полученный HTML-код будет вставлен в родительский шаблон

Что касается системы хуков — ну хорошо, пусть она в MODX лучше. Но если Вам нужно что-то изменить в экшене ЛС — Вы будете это делать средствами ЛС, хороши они или нет, и интеграция с MODX тут ни грамма не спасет.

Поэтому, если есть желание помочь в развитии ЛС, то с Вашей стороны было бы во сто крат более продуктивно предлагать какие-то решения для LiveStreet, учитывающие специфику и особенности этого движка. А все разговоры типа «в том движке вот это клево, а в ЛС это хреново» — бесполезны
avatar
Да и где управление очередностью вызовов хуков? Какой плагин вперед инициализировался, того и тапки? А что, если в одном шаблоне надо, чтобы сначала вызвался хук первого плагина, а потом второго, а в другом случае наоборот?
есть приоритеты.
В общем, чем больше я узнаю Livestreet, тем больше убеждаюсь, что интеграция с MODX — ему очень даже нужна, так как он получает много того, чего там скорее всего вообще никогда не появится в силу особенностей движка.
кому нужна? только потому что вы её развиваете? вот лучше бы сам код лс допиливали, имхо.
avatar
На мой взгляд, так было бы гораздо логичнее
$config['view']['hooks'] = array(
// ex. 1
    array(
        'template' => 'header_top.tpl',
        'selector' => '#nav-main li:nth-child(2):after',  // равнозначно 'selector' => '#nav-main li:eq(1)',
        'action' => 'insert',
        'content' => Plugin::GetTemplatePath('aceblogextender') . 'hook.header_top.li.tpl',
    ),
);
avatar
Не знаю, насколько это логичнее. Все же селектор указывает на элемент, а не на точку в шаблоне. Но, может, стоит и так сделать тоже, тогда параметр action можно вообще опускать
avatar
В одном примере replace (действие), а в другом after (контекстный указатель), предлагаю внести коррективы и использовать вместо after действие insert, а указание переместить в селектор с использованием псевдоэлемента :after. Таким образом, код будет более стройным, логичным и семантически выверенным.
avatar
Да, логично излагаешь. В свое оправдание скажу, что отталкивался от синтаксиса jQuery с его append(), after() и т.д. Но подумаю, как твое предложение реализовать. Хоть и непросто это — уж больно парсер геморройный получается
avatar
В моём предложении есть неточность — меня сбило с толку словечко after и я, не дочитав до примера вывода бросился писать комментарий.

:after в css работает несколько иначе, чем .after() в jquery: первый создаёт элемент внутри #nav-main li:nth-child(2), а а второй — после него. Получается, что :after не нужен (он работает как append()), достаточно селектора, указывающего на конкретный элемент.

В идеале было бы прекрасно, если бы он не содержал имени элемента, но если по каким-то причинам этого сделать нельзя, то более разумной выглядит такая конструкция #nav-main li:nth-of-type(2). Это предупредит ошибку в том случае, если в #nav-main перед элементами списка появится какой-либо другой элемент.

Тем не менее, актуальность именования экшена каким-либо действием (insert или paste) сохраняется. Наиболее логичным представляется конкретизация действия, например insertAfter или insertBefore.
avatar
Теперь насчет всей этой затеи свое мнение выскажу. Идея — очень клевая.

Есть два момента (один из них не касается админпанели вообще):
1)нестандартные шаблоны. Многие верстальщики не соблюдают структуру построения шаблона от стандартных скинов (developer'a). Файлы шаблона могут называться также, а внутренняя структура вообще другая, поэтому на dom ориентироваться не представляется возможным — надо переопределять. Это никак не относится к идее суперхуков и твоей реализации. Это относится к тому, что для ее полнцоенной работы и ее существования в самом ЛС должна быть стандартизованная сетка со стандартными классами и разработчики шаблонов должны ей следовать, чтобы обеспечить совместимость.

2)
4. Насколько использование этих хуков замедляют время отдачи сайтом контента?
Ни насколько!
Возможно суперхуки и не будут ничего кушать. Только сама админка начала жрать +4,5-5 мб на процесс на почти пустом тестовом сайте(сегодня все утро мониторил статистику пока работал с включенной/выключенной админкой), не помню чтобы админка для прошлого поколения была столь прожорлива. Это конечно незначительно в объемах того, сколько может сжирать конвертация серьезных фоток (поэтому большинство ставит 32+ и не заметит проблем, но все же).

Я это все к чему — почему дополнительный функционал необходимо паковать в админку? Мне кажется админка концептуально не подразумевает наличия в себе подобного и предназначена для более приземленных вещей, напрямую связанных с функциями админа на сайте: настройки конфига/редактирования юзеров итп.
Почему бы не сделать LSextendedpack плагин, куда запулять все эти крутые доработки, которые нужны не всем?
А плагины, использующие наработки из этого пака — указывали бы это в своем поле required.
avatar
По п.1 — да такая проблема есть. Собственно, для этого и вынесено все в настройки скина. Разумеется, дефолтные настройки расчитаны на дефолтный скин. Для нестандартных скинов нужно делать адаптацию. И она будет заключаться, главным образом, в том, что нужно будет изменить селекторы (т.е. определиться, куда делать вставки), и изменить CSS. Все же попроще будет, по-моему, чем переписывать шаблоны.

По п.2 — я был бы паталогическим идиотом, если б начал спорить и возражать. Но я таковым себя не считаю, поэтому скажу, что согласен на все 100% — да, все так, нужен отдельный плагин. И давно уже такая необходимость назрела. Бог даст — разрожусь, наконец :) Но не прямо сейчас
avatar
Вдогонку. Средние результаты замеров ( делал по 5 штук каждого вида на одной странице, приведены средние значения на 5 замеров)
Кеш отключен:
без админпанели: ~13,8мб
с админпанелью: ~20,5мб
С кешированием:
без админпанели: ~14,0мб
с админпанелью: ~18,5мб

То есть прирост прожорливости по памяти до 6,7мб (до 50%). Нехило конечно.
Сайт с 1000 юзеров, 6000 топиков, 100К комментов. Стоит десяток-полтора популярных плагинов, отключены некоторые стандартные блоки.
avatar
Хм, полезная инфа. Дело за «мелочью» — сообразить, кто конкретно память жрет
avatar
в самом ЛС должна быть стандартизованная сетка со стандартными классами и разработчики шаблонов должны ей следовать, чтобы обеспечить совместимость

очень, очень нужная штука. Нужны хотя бы самые примитивные гайдлайны по названиям и логике классов и элементов для шаблонов.
avatar
Livestreet. For Developers. By Developers.™ В который раз наблюдаю как в LS-холиварах «пользователь» выпадает из обсуждений и все идет в ключе «я разработчик, зачем мне это, в моем любимом LS?» А как же пользователь? Я пришел сюда больше года назад и за это время научился частично разбираться в html, css, js, даже php. Потому как без этого, к моему великому сожалению, работать с LS просто невозможно. Я мечтаю о том дне, когда сообщество LS в свою логику внесет директиву «для пользователя», спасибо вам avadim, за ваш вклад в развитие проекта в сторону пользователей. Не знаю что бы делал без ваших плагинов, когда начал свое знакомство с LS, наверное прошел бы мимо, искать «CMS моей мечты».
avatar
Я открываю топик об админке, а в результате читаю фанатические комментарии автора мода ЛС_старой_версии_+Модекс, который уверяет вот что все круто и быстро, а всем нужен именно этот мод.
avatar
Вадь, а чем оно православней нативного наследования шаблонов в смарти?
avatar
Да оно просто другое. И реально более гибкое. Наследование все равно выполняется в границах предопределенных блоков. А тут появляется возможность манпулировать с точностью до ДОМ-эелемнта. Простейший пример на базе того, что в статье — есть исходный текст шаблона:
<ul id="nav-main">
  <li>Item A</li>
  <li>Item B</li>
</ul>
Если я этот код оберну Смарти-блоком, то смогу при наследовании либо заменить его целиком, либо сделать вставку в начало блока или в конец. А в моем решении ты можешь вставить элемент в середину:
array(
  'template' => '...',
  'selector' => '#nav-main li:nth-child(1)',
  'action' => 'after',
  'content' => '<li>вставка</li>',
)
<ul id="nav-main">
  <li>Item A</li>
  <li>вставка</li>
  <li>Item B</li>
</ul>
А можешь добавить контент внутрь каждого li-элемента:
array(
  'template' => '...',
  'selector' => '#nav-main li',
  'action' => 'prepend',
  'content' => '***',
)
<ul id="nav-main">
  <li>***Item A</li>
  <li>***Item B</li>
</ul>

Ну и т.д. Т.е. как ты в jQuery манипулируешь документом, так и здесь.

Но вообще тема про наследование шаблонов — это отдельный разговор. Я почему-то почти уверен был, что скины для новой версии ЛС будут по этой схеме строиться. Но увы, такой отличный инструмент оказался не задействован.
avatar
я придумал для чего оно годно в этом виде :) для рекламных блоков по схеме «где хочу, там и будет».

Я почему-то почти уверен был, что скины для новой версии ЛС будут по этой схеме строиться.
я почему-то уверен, что верстальщики, берущиеся за лайвстрит и без того «задроченные» как в том анекдоте про бабушку и козу :) я сам не могу до сих пор со своими инструментами управиться, уж больно тошнит меня от возни с шаблонами
avatar
Да, с составными шаблонами всегда так — гемор для верстальщика выше крыши. Но переход на блочную систему Смарти положение не ухудшит ни на грош, в крайнем плохом случае получим тот же гемор, но вид сбоку. А в лучшем случае ситуация будет гораздо веселее по двум причинам:

1) Можно будет создавать «родительские» шаблоны (от которых пойдет наследование), в которых будет ВСЯ структура макета страницы, разбитая на блоки. Т.е. хоть в каких-то шаблонах можно будет окинуть одним взглядом весь макет целиком, чего сейчас нет.

2) Это позволило бы вообще отказаться от делегирования шаблонов. В нынешнем варианте если два плагина объявляют делегирование одного шаблона — это клинч. А при наследовании шаблонов хоть конфликты тоже могут быть, но клинчей не будет точно. Тут главное — тщательно блочный макет продумать.
avatar
подводя итог тому что я написал:
главное — механизм отслеживания этих изменений в шаблонах. а то получится очередная путаница.
avatar
Вадим, спасибо за очередную отличную фичу
Я согласен с замечаниями eXtravert и 1d10t по поводу привязке к DOM с разнообразием шаблонов и отслеживанию. Но точно для определенных задач будет не заменимо.

Не уловил один момент — если несколько плагинов с одним селектором внедрят свой html, применение селектора будет к изначальному html, или уже с учетом внедрений предыдущих плагинов? И что с приоритетами? Будет ли корректно отрабатывать, если шаблон ActionTopic/add.tpl переопределен другим плагином(через хак в классе Smarty)?
  • ort
  • 0
avatar
Я тоже согласен с замечаниями относительно разнообразия шаблонов. Но это общая проблема, она не только в этом случае вылезает, но при любой адаптации под новые скины. Вот onthefly давно ратует за то, что должны быть четко сформулированы стандарты разметки. А вообще — как сейчас приходится делать адаптации под нестандартные скины, так и в случае с этой фичей придется делать то же самое. И как сейчас неаккуратная (некграмотная, халтурная) адаптация одного плагина может поломать документ и конфликтовать со всеми на свете, так и с этой фичей это возможно.

если несколько плагинов с одним селектором внедрят свой html, применение селектора будет к изначальному html, или уже с учетом внедрений предыдущих плагинов?
Применение будет последовательным, т.е. с учетом изменений предыдущих плагинов.

И что с приоритетами?
Пока приоритеты не реализованы, хуки отрабатываются по мере их фиксации (т.е. порядок активации плагинов и порядок их объявления в конфиг-файле). Но, наверное, стоит это сделать

Будет ли корректно отрабатывать, если шаблон ActionTopic/add.tpl
Долго думал и прикидывал, и, в итоге, такой подход реализовал: задаваемое в хуке имя сравнивается с окончанием полного имени файла шаблона. Т.е. если задано template='add.tpl', то селектор будет применяться и к шаблону '.../ActionTopic/add.tpl' и к '.../ActionBlog/add.tpl'.

Если же задать template='ActionTopic/add.tpl', то, соответственно, к ActionBlog/add.tpl применяться не будет. Таким образом можно и вообще для шаблона конкретного плагина задать:
template='/otherplugin/templates/skin/default/template.tpl'

Было или нет делегирование шаблона — тут неважно, важно какое имя файла у шаблона. Допустим в хуке задано template='ActionTopic/add.tpl'. Если после переопределения шаблона новый файл заканчивается так же — он будет обработан хуком. А если переопределенный шаблон заканчивается, скажем, на ActionTopic/topic_add.tpl, то он будет игнорирован
avatar
Если после переопределения шаблона новый файл заканчивается так же — он будет обработан хуком. А если переопределенный шаблон заканчивается, скажем, на ActionTopic/topic_add.tpl, то он будет игнорирован
логичнее использовать исходное имя шаблона, а не результирующее, которое может быть вообще другим

Т.е. если задано template='add.tpl', то селектор будет применяться и к шаблону '.../ActionTopic/add.tpl' и к '.../ActionBlog/add.tpl'.
это скорее минус, т.к. в корне может лежать файл block.tpl и с таким же названием еще у плагинов/экшенов и т.п., в итоге будет что-то страшное.
avatar
В принципе, ты прав. Хотя, чтобы реально получилось что-то страшное, мало совпадений имен шаблонов, должно быть еще и совпадение по селектору. Понятно, если селектор будет обезличенный, типа «ul li a», то такие комбинации практически в любом шаблоне есть. Поэтому в обязательном порядке нужно юзать ид и классы элементов, чтоб четко выйти на конкретные элементы DOM-структуры.

Ну а вообще — это же все обсуждаемо. Тут задействован пре-фильтр Смарти, и в него передается полное имя файла. На текущем этапе выполняется просто сравнение, но можно ведь находить и делегируемого родителя, и его имя анализировать.

Дальше — больше: это сейчас задаются просто шаблоны для включения, но если кто-то хочет более серьезную логику организовать, то можно точно так же вешать на хук вызов класса и туда передавать текущий текст шаблона и дать инструмент для его обработки, типа такого:
// в переменной $oDom - DOM-объект обрабатываемого шаблона
$oElementSet = $oDom->find('#spec li.aaa.bbb a.ccc');
if ($oElementSet->length()) {
  // элементы найдены, работаем с ними
  $oElement->append('<span>cool!</span>');
} else {
  // элементы не найдены, работаем с другими
  $oElement->find('#spec li.aaa.bbb')->html('<a class="ccc">not cool</a>');
}
В общем, на мой взгляд, потенциал у этой технологии просто охрененный для тех, кто хочет и может копать глубоко и желает получить максимум контроля над процессом.

Причем, то, что я сейчас в примере описал — это сегодня уже реализовано именно в таком виде (поиск, методы вставки и замены и т.д.). Я просто пока не хочу афишировать, т.к. еще возможны серьезные изменения. Если сообществом разработчиков принципиально эта концепция будет принята, если практический интерес будет не только у меня, тогда имеет смысл уже обсуждать детали реализации, чтоб выработать наиболее оптимальные и гибкие подходы
avatar
Потенциально такая возможность может стать одной из ключевых в движке. Но без стандартизации внутренностей шаблонов от нее будет мало толку.
avatar
А как сейчас без стандартизации делается адаптация плагинов под разные скины? ;)
avatar
Со скрипом делается. Вручную. С доброй воли авторов.

Если будет единый внутренний стандарт верстки, «правильные» плагины будут сразу совместимы с «правильными» шаблонами — в рамках одной версии LS.

В принципе, предложенный тобой механизм в перспективе мог бы заменить хуки в шаблонах.
avatar
Не знаю, стоит ли отменять хуки в шаблонах, все же мой способ подразумевает, как мне кажется, более тонкую работу и высокую квалификацию разработчика. Поэтому, если его и включать в перечень штатных средств, то хуки тоже имеет смысл оставить. А вот делегирование шаблонов я бы предложил постепенно в разряд deprecated перевести
avatar
делегирование — да, зло.

но, имхо, проставить хуки в сверстанном шаблоне не труднее, чем проставить классы и айдишники с нужными названиями, а результат получится тот же.

Шаблонам в ls, кмк, отчаянно не хватает семантики — и разбиение на мелкие файлы не решило проблему
avatar
Если будет единый внутренний стандарт верстки, «правильные» плагины будут сразу совместимы с «правильными» шаблонами — в рамках одной версии LS.
Однозначно, да. Дело за малым — чтоб кто-то сел и этот стандарт расписал :)
avatar
В общем, на все комменты, что прозвучали здесь в мой адрес (вопросы, сомнения, обвинения и т.п.), вот мой ответ: community.modx-cms.ru/
Сообщество MODX теперь официально перешло на MODX Revolution + Livestreet. Связка выполнена мной с использованием модуля modLivestreet.
Для те кто поспокойней: данное решение очень заинтересовало одного из разработчиков MODX — Райана Треша. Так что кто бы тут что ни говорил, решение интересное и развитие у него будет. И я искренне надеюсь, что это решение добавит популярности и Livstreet-у, так как это бы дало толчок для его развития. А значит и modLivestreet будет становиться интересней.
А для ярых защитников Livestreet и противников всего остального: считайте это вызовом. Очень скоро вы заметите, насколько сайт сообщества MODX будет более продвинутый, чем ваш. Вы пока даже не представляете какие возможности дает MODX, но скоро вы будете с завистью смотреть и только негодовать «А почему у нас тут даже групп пользователей нету...»
avatar
Так что кто бы тут что ни говорил, решение интересное и развитие у него будет.
а вам кто-то что-либо говорил? вы же пришли в топик об админке и сообщили о вашем плагине.

у вас там даже валидация по почте не работает.
avatar
у вас там даже валидация по почте не работает.
Да, с валидацией действительно баг был. В синхронном режиме все ОК было, а тут пока в обычном работает, и не углядел.
Спасибо за подсказку!
avatar
Николай, постарайтесь больше не писать про свой modx в топиках, которые к нему (и к вам) не имеют никакого отношения. Создавайте топики и изливайте своё эпистолярное творчество туда, где все желающие смогут обойти их стороной.

Заранее большое спасибо.
avatar
Так что кто бы тут что ни говорил, решение интересное и развитие у него будет.
То, что это решение очень интересное для MODX — никто и не спорил. Но здесь разговор немного о другом.

считайте это вызовом. Очень скоро вы заметите, насколько сайт сообщества MODX будет более продвинутый, чем ваш. Вы пока даже не представляете какие возможности дает MODX, но скоро вы будете с завистью смотреть и только негодовать...
А вот это уже жирный троллинг от ярого сторонника продвинутого супердвижка, на котором можно сделать легко и просто все на свете, но такую простую вещь, как социалку за несколько лет так никто и не осилил.

Давай, все-таки, так: в темах по LS нужно писать про LS. Только не про то, какой он убогий и кривой (как бы ты не кичился, но тут есть немало людей, которые о недостатках и проблемах LS знают лучше тебя), а про то, как сделать LiveStreet лучше. Если есть конкретные предложения, как какие-то клевые фишки других движков внедрить в LS, есть соображения по реализации тех или иных фич — велкам. Более того, то я бы предложил тебе обратиться к ort , чтобы он создал новый блог, что-то типа «Интеграция LiveStreet с другими движками и CMS/CMF», куда ты мог бы постить рассказы по успешному развитию сообщества MODX на базе LS. Только для этого вести себя нужно чуть более адекватно.
avatar
Тема о стандартизации шаблонов, поднятая здесь в комментариях, была продолжена:
livestreet.ru/blog/wishlist/13103.html
livestreet.ru/blog/wishlist/13125.html
avatar
почему-то не получается…
в файл /templates/skin/social/settings/config/config.php вставил:
$config['view']['hooks'] = array(
	array(
		'template' => 'nav.tpl',
		'selector' => '.nav-main',
		'action' => 'replace',
		'content' => Plugin::GetTemplatePath('aceblogextender') . 'hook.new_nav.tpl',
	)
);


ессесно создал файл hook.new_nav.tpl.
почистил кеш, обновил, старая менюшка на месте :(

хотя похожий конфиг в конфиге aceblogextender работает…
:(
avatar
точно такой ж конфиг вставляю в /plugins/aceblogextender/templates/skin/social/settings/config/config.php и он работает.

т.е. этот конфиг задается по пути /templates/skin/<имя_скина>/settings/config/config.php относительно плагина aceblogextender, и он не работает еслри прописать его в конфиг самого скина. верно?
avatar
все, вроде разобрался.
судя по InitHooks() в /plugins/aceadminpanel/classes/modules/viewer/Viewer.class.php
хуки берутся только из плагинов, и в шаблоны не смотрят.
т.е. мне чтобы поменять чего-то, можно просто создать плагин, в котором будут только хуки шаблонов, и не нужно будет трогать ни конфиги плагинов других, ни конфиги шаблона. это еще круче, спасибо :)
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.