Николай Ланец
23 февр. 2015 г., 23:26

ShopModxBox-2.6.1 и modxSmarty-1.0.3

Сегодняшний релиз ShopModxBox довольно объемный (см. changelog), но не должен вызывать каких-то серьезных сложностей при обновлении последних версий, и в основном касается всяких мелких улучшений. Тем не менее если кто будет обновляться, советую внимательно изучить изменения, так как некоторые моменты могут немножко поломать что-либо. В любом случае, бекапы рулят, и если что, задавайте вопросы.

Изменения

1. Главное меню вынесено в отдельный шаблон inc/menu/mainmenu/menu.tpl
Теперь главное меню находится в отдельном шаблоне. Это дает несколько важных плюсов. Приведу пару:
  • Теперь его конечно же гораздо легче переопределять. А это немаловажно, ведь на то оно и главное меню.
  • Параметры шаблонов вэйфайндера вынесены из набора параметров @MainMenu в массив параметров $params. При этом чанки-шаблоны заменены на инлайн-шаблоны в параметрах. Таким образом мы и от чанков лишних избавляемся, и опять-таки переопределять легче.
Плюс к этому теперь меню «из коробки» двухуровневое, правильное, с нормальной кнопочкой при просмотре на мобильных и т.п. Трехуровневое нативно как сделать не нашел. Точнее как я понял, это уже только с использованием плагинов делается, типа из коробки бутстрап трехуровневое не дает, так как там уже горизонтально надо выводить подменюшки. Я не стал пилить в сборку стороннюю библиотеку для менюшек, так как если кому и надо будет более чем двухуровневое меню, наверняка у него будут свои пожелания на счет либы, их не мало, есть свои отличия и пусть каждый себе выбирает в соответствии с его приоритетами. Но если кто знает как сделать трехуровневое и более на чистом бутстрапе, подсказывайте.
2. Удалены некоторые чанки
В частности удалены за ненадобностью чанки dbt.mainmenu.outerTpl, dbt.mainmenu.rowTpl, dbt.lgnLoginTpl, dbt.lgnLogoutTpl. Их удалять не нужно, они кушать не просят и после обновления шаблонов они больше использоваться не будут. Но если вы их редактировали на своем сайте, то смотрите изменения и переносите их в шаблоны своего переопределяющего скина при необходимости.
3. Вывод информации об оплате в управлении заказами + уведомления
Теперь в управлении заказами видно когда, сколько и через какую платежную систему оплатили за заказ, а так же номер счета в платежной системе. Плюс к этому, что немаловажно, теперь на почту отправляются уведомления об оплате заказа, так же как и при оформлении заказа (и покупателю, и менеджерам магазина). Шаблончики.
4. Скрипты jquery.js и bootstrap.js перенесены из хеда в подвал
Вот это очень важно учитывать не только при обновлении, но и в дальнейшем при разработке сайтов на сборке ShopModxBox. Теперь нельзя просто так в любом месте взять и написать типа $(function(........)). Теперь это придется делать или дописывая в подвал, или вклиниваться в сборку фронта и пересобирать ее. Да-да, мне это тоже не очень нравится, но говорят это гораздо более православней и с точки зрения архитектуры приложения, и с точки зрения загрузки страницы.
5. Страницы оптимизированы в соответствии с рекомендациями гугла
Согласно данным Google PageSpeed Insights, для мобильных устройств: Скорость 66/100, Удобство для пользователей 96/100, для компьютеров: 83/100 Рекомендации. Данные по скорости на конечном сайте могут отличаться, так как на это влияет в том числе качество сжатия картинок, gzip-компрессия на уровне веб-сервера и т.п. Но в любом случае, сейчас фронт прибавил очков, так что и на вашем сервере будет лучше работать.
6. Сообщения Alertify переведены в верхний правый угол
Ранее уже немного обсуждали это окошко. Предложенный вариант редактирования JS-а самой библиотеки (да еще и min-файла) считаю не богоугодным, но и в принципе нормального механизма инициализации объекта alertify с передаваемыми в него конфигами так же нет, поэтому сделал так. Но так тоже пойдет.
Кстати, Alertify я вынес в отдельный блок, так что в своем переопределяющем layout-шаблоне вы можете писать так, к примеру:
{block name=shopmodx_scripts append} {/block}
Тогда сообщения будут выводиться в левом нижнем углу. В общем, здесь вам будет доступен объект alertify, делайте с ним что хотите (см. оффдоку Alertify).
На самом деле блок shopmodx_scripts depricated и вскоре будет удален, но я не совсем корректно определил блок footers, из-за чего я не могу правильно вклинить этот свой скриптик аккурат за вызовом app.js, поэтому привел пока рабочий пример такой. В дальнейшем он будет скорректирован. В любом случае следите за тем, какие блоки за чем идут в главном layout.tpl и там уже решайте какой блок расширять, лишь бы app.js шел раньше, а то он будет перетирать настройку alertify.defaults.notifier.position.
7. Добавлен JS-объект ShopMODX. Я, как наверняка и многие другие неискушенные веб-разработчики (не такие, как Сергей Прохоров), привык пользоваться Жучкой (jQuery) и привык просто на странице писать JS-код. К примеру, навесил на произвольную форму событие, при клике отправил Ajax-запрос на сервер, отработал ответ и радуюсь. Простейший пример:
$('.my_form [type=submit]').on('click', function(e){ var form = $(this).parents('form:first'); var data = form.serialize(); $.ajax({ url: 'some_url', data: data, error: onErrorHandler, success: onSuccessHandler }); return false; });
Наверняка многим подобный код покажется знакомым и любой, кто реализовывал Ajax-запросы, подобное писал. Но это простейший пример, урезанный. Здесь не прописаны еще Success-Error-хэндлеры, обработка и вывод ошибок и т.п. А еще и УРЛ каждый раз прописывать… А ведь все это уже Сергеем прописано в нашем API. Да вот только не доступно как бы… Чтобы этим пользоваться, надо вклиниваться во фронт, пересобирать его и все такое. На крупных проектах это очень даже оправдано, но на мелких и средних сайтах/магазинах слишком много телодвижений для реализации каких-либо мелких задач. В общем, мы тут с Сергеем всяко разно со всех сторон обсуждали этот момент и сошлись на том, что в дальнейшем он фронт конечно же еще прокачает, и будет много всяких правильных вещей, а пока я набыдлкодю, выдав глобальный объект ShopMODX, в котором в свою очередь будет доступен объект Request. Вот теперь я счастлив как ребенок! :) Можно теперь просто делать так: ShopMODX.Request.run('login'); Попробуйте сами установить новую сборку и в консоли окна выполнить. Будет выполнен запрос на коннектор сайта и вы получите стандартизированное уже Alertify-окошко с сообщением «Неправильное имя пользователя или пароль. Пожалуйста, проверьте введённые данные и попытайтесь снова.». красота! :)
Попробуем чуть-чуть переписать вышеприведенный пример на новый лад:
$('.my_form [type=submit]').on('click', function(e){ var form = $(this).parents('form:first'); var data = form.serialize(); var action = 'login'; ShopMODX.Request.run(action, data). then(function(resp){ if(resp.success){ alertify.success(resp.message || "Вы успешно авторизованы!"); } }); return false; });
Всё. Ошибки обработает сам ShopMODX.Request, в том числе выведет сообщение об ошибке, а успешное сообщение мы сами обработаем и решим что делать. Мне так больше нравится :) Легко делать всякие формы заказа обратного звонка и т.п.
8. В метод ShopMODX.Request.run() добавлен четвертый параметр — url. Было три параметра:
  • action — учитывается в публичном action-процессоре, чтобы рулить какой процессор вызывать (это чтобы не были все процессоры доступны извне).
  • data — параметры запроса (например, передаваемые в него данные формы).
  • event — объект события окна. Его не обязательно передавать.
Проблема была в том, что запрос обязательно отправлялся на базовый коннектор и все. Сейчас можно передать свой собственный УРЛ, куда и будет выполнен запрос, например ShopMODX.Request.run(some_action, some_data, null, '/ajax.html'). Главное, чтобы ответ был JSON-formated. На счет не JSON-ответов будем потом думать.
9. modxSmarty-1.0.3 и параметр $main_menu_is_cached
И наконец главная фишка этой сборки — обновленная версия modxSmarty. Изменения там совсем не много, и касаются только тега {snippet}, но зато какие! :) Теперь в вызов {snippet ...} можно передавать параметр as_tag=1, и тогда этот кешируемый smarty-тег, выполняемый сразу же, превращается в некешируемый MODX-тег вида [[!snippet_name?params...]]. Это на самом деле такая крутотень! :) Давайте еще раз и более внимательно посмотрим на новый код подгружаемого шаблона главного меню, о котором мы говорили в п.1 текущего перечня изменений:
{* Главное меню *} {block menu_params} {$params = [ "parentRowTpl" => '@CODE <li[[+wf.id]][[+wf.classes]]> <a href="[[+wf.link]]" title="[[+wf.title]]" [[+wf.attributes]] class="dropdown-toggle" data-toggle="dropdown">[[+wf.linktext]] <span class="caret"></span></a> [[+wf.wrapper]] </li>', "outerClass" => 'nav navbar-nav', "innerClass" => 'dropdown-menu' ]} {/block} {block menu_wrapper} <div class="navbar navbar-default"> <div class="container"> <div class="navbar-header"> <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="collapse navbar-collapse"> {snippet name="Wayfinder@MainMenu" params=$params as_tag=!$main_menu_is_cached} </div> </div> </div> {/block}
Особенно обратите внимание на вызов сниппета: {snippet name=«Wayfinder@MainMenu» params=$params as_tag=!$main_menu_is_cached}
Как известно, у нас в MODX-шаблонах бывает настройка phptemplates.non-cached, которая в данной сборке по умолчанию = true, что заставляет даже на закешированных MODX-ресурсах при каждом обращении к странице повторно вызывать Smarty-шаблоны. Это нам нужно на время разработки, чтобы не приходилось каждый раз после редактирования Smarty-шаблонов обновлять весь кеш сайта, чтобы увидеть изменения на странице. Но на продакшене мы выставляем phptemplates.non-cached = false, в результате чего при повторном запросе к странице Smarty-шаблон уже не вызывается, а сразу отдается HTML-код из кеша страницы, что значительно снижает нагрузку на сервер и увеличивает скорость загрузки страницы. При этом все теги типа {snippet...}, {chunk...} и т.п. в смарти-шаблонах отрабатываются на уровне самого Smarty, то есть MODX-у отдается сразу же конечный HTML-код. Это хорошо на статических блоках страницы, но совсем не хорошо с динамическим содержимым, например, если в меню есть документы с ограниченным доступом и для разных пользователей может быть в итоге разное меню. Для этого приходится писать некешируемый MODX-сниппет, то есть, к примеру [[!Wayfinder?.....]]. Такой тег уже MODX будет отрабатывать каждый раз при заходе на страницу.
Так в чем же фишка? Зачем нам надо именно вызывать через {snippet… as_tag=1}? На самом деле нам так просто гораздо удобней.
Во-первых, у нас параметры сниппета прописаны массивом, MODX-теги [[!.. ]] не умеют принимать массивы. Нам бы пришлось писать все параметры стандартной MODX-строкой типа '?var=`foo`&var2=`foo`...', но тогда бы мы не могли расширять наши параметры. Сейчас, если мы захотим изменить outerClass, нам достаточно в своем переопределяющем скине создать свой шаблон inc/menu/mainmenu/menu.tpl и прописать там такой код:
{extends "[main]inc/menu/mainmenu/menu.tpl"} {block menu_params append} {$params = array_merge((array)$params,[ "outerClass" => 'new_outer_class' ]} {/block}
И всё. Все другие параметры останутся прежними. Со строковыми параметрами такого уже не получилось бы.
Во-вторых, теперь, чтобы превратить кешируемое меню в некешируемое, просто достаточно изменить в layout.tpl параметр {$main_menu_is_cached = true} с true на false и всё. В вызове сниппета меню параметр as_tag=!$main_menu_is_cached получит это значение и уже не сразу вернет кешируемый код менюшки, а вернет некешируемый MODX-тег [[!Wayfinder?...]] со всеми переданными параметрами $params. Такми образом меню станет некешируемым и будет выводиться каждому пользователю его индивидуальное меню.
Само собой не следует редактировать layout.tpl в самом скине shopmodx, а следует его переопределить в своем скине.
Благодаря этой фишке постепенно шаблонизация сборки будет приведена к единому виду, без перемешки MODX- и Smarty- тегов, а кеширование и прочие параметры будут рулиться в настройках layout-шаблона.
На этом все с основными изменениями. Есть и другие мелкие правки, но они не особо значительные. Кто ценит наши труды, поддерживайте рублем (форма внизу, сумму можно менять как в большую, так и в меньшую сторону). Все это требует не мало калорий, которые напрямую далеко не всегда оплачиваются, и часто чтобы это все делать приходится сидеть в дополнительные часы и в выходные/праздничные. Вот я сегодня на это затратил 9 часов, плюс на написание статьи еще 4 с лишним часа, чтобы вы знали что и как правильней использовать. Плюс ко всему еще и в чателке JivoSite частенько отвечаю на вопросы новичков и не только. Так что каждый ваш донейт существенно добавляет возможности выделить дополнительные часы на доработку сборки. К слову, большое спасибо тем, кто уже прислал свои донейты. Отдельное огромное спасибо Саше Маркову, который в этом только месяце прислал два донейта, существенно крупнее базовой суммы в донейт-форме (хотя и раньше присылал не раз помощь), и другим товарищам, поддержавших нас рублем. Я не жадничаю, но хотелось бы, чтобы и другие тоже хоть чуть-чуть поддерживали. Чем больше донейтов будет, тем больше будет и доработок, и более качественных консультаций, и видео-уроков и вебинаров. Постепенно хотелось бы уйти в сторону от сторонних коммерческих проектов и больше сосредоточиться на развитии сборки ShopModxBox и MODX-Клуба (я молчу про ту кучу всяких классностей, которые планирую сделать здесь в обозримом будущем).
Для тех, у кого уже есть работающие магазины на ShopModxBox, и кто хотел бы обновиться до последней версии сборки со всеми ее вкусностями, но сам не может этого сделать по различным причинам, предлагаю платное обновление моими силами. Как правило на это хватает часа-двух даже с теми магазинами, которые разработаны не по фэншую. Час стоит 2000 рублей. Деньги не особо большие, но зато гораздо надежней и правильней все будет. За одно оптимизацию пользовательского кода выполню и аудит производительности, дам советы по месту. Заинтересованные пишите на n.lanets@modxclub.ru
Есть вопросик именно по этой, последней сборки. Ибо в прошлых и предыдущих данной проблемы не было. Не могу никак понять логику шаблонов для Личного кабинета. На самой странице дублируется контент, вернее не контент а полностью шаблон в шаблоне. как то так clip2net.com/s/3e9lnrZ (это если убраю $smarty.block.parent) вместе с шапкой с подвалом и тд, хотя переопределен так же как и на всем сайте, в скине, через {block name=content}. С $smarty.block.parent в скине, в шаблоне inc/office/index.tpl почему то вообще загружает основной шаблон из shopmodx и отображает его вложенным в layout.tpl скина. clip2net.com/s/3e9qHQ4
Но у нас-то такого нет, и больше вообще никто не жаловался на подобное. Значит что-то не так в ваших шаблонах. Где-то не то расширили, где-то не то указали.
Кстати, может вот что быть: (я не раз натыкался). Бывает так, что мы комментируем не актуальные блоки, типа вот так:
{* Этот блок кода не актуальный {block name=content} some code {/block} *}
Так вот, блоки внутри комментариев не игнорируются :) То есть они учитываются и выполняются шаблоном.
так все уже перепроверил. В файле скина между body:
{block name=content} ........ {/block}
В файле office.tpl изменений нет:
{extends file="layout.tpl"} {block name=Breadcrumbs}{/block} {block name=content} <div class="lk-content"> <div class="row"> <div class="col-md-2 sidebar"> {snippet name=Wayfinder params="startId=`110`&outerClass=`nav nav-sidebar nav-tabs nav-stacked`"} </div> <div class="col-md-10"> {$smarty.block.parent} </div> </div> </div> {/block}
Файлы и папки личного кабинета перенес в скин. Скин в настройках назначен. И как что-то можно не дописать, нето указать, если файлы кабинета не трогались. И все на сайте отображается без ошибок, кроме кабинета. Настройки страницы clip2net.com/s/3e9uiCO, хоть так clip2net.com/s/3e9uBhC разницы нет.
На гист выложите весь код шаблона layout.tpl, как есть.
Ага, есть засада :)
А еще недавно выяснил, что не обязательно соблюдать вложенность. Пример: Есть шаблон. В нем блоки:
{block b1} {block b2} {/block} {/block}
В расширяющем можно так писать:
{block b2} ffff {/block} {block b1 append} fewfwf {/block}
То есть за структуру используется именно родительский шаблон, переопределенный блок из расширяющего шаблона будет использован именно в месте его изначального определения.
Мне просто в блоке формы в расширяющем шаблоне надо было скрыть одно поле, а поле в другом блоке и этот блок уже переопределяется. Оказалось пофиг — за пределами вынес и все.
Вот и ответ: у вас шаблон расширяет основной шаблон самой сборки. А как я написал ниже, вложенность блоков в расширяющем шаблоне не играет роли особой. Переписав весь блок {block body} вы не перетираете особо имеющиеся вложенные блоки внутри главного шаблона. Попробуйте не ресширить [main]layout.tpl, а именно написать полностью свой layout.tpl, без расширения. Должно помочь.
Да, я тоже недавно открыл благодаря тебе append,prepend,parent,child. Полезные фичи. Но все равно читабельность гробят, стараюсь по возможности без них писать.
да точно, убрал расширение [main]layout.tpl и все встало на свои места. Спасибо. Я почему то был уверен что они перетираются. Будем теперь знать.
Не, это не линейная замена одной текстовой части шаблона другой. Шаблон компиллируется в php-класс, и расширяя его другим шаблоном (другим php-классом) мы просто так ничего не меняем в исходном классе.
Привет :) Давно меня не было видно.
А, если надо делать 2 меню верхнее и боковое. Как можно {block menu_params} переопределять?
Привет, Алишер!
Никак. Если сетка сильно отличается, значит полностью свой layout.tpl на замену писать.
А все, вопрос снял :)
нужно просто приинклюдить другой файл.
Именно. Только не в самом скине shopmodx, а в кастомном скине создать свой layout.tpl. Читай внимательно это.
Спасибо, нашел ответ :)
Добрый день! Переписываю под себя layout.tpl и обнаружил, что в исходном коде в футере формируются скрипты
Хотя в самом layout.tpl их нет. Как от них избавиться?
Там же путь прописан «assets/components/directresize/....». Отключите плагин directresize И будет вам счастье.
Поэтому и пишу, что плагин отключил, а коды остались.
Так вы тогда и пишите, что в футере видите скрипты плагина, который на самом деле отключен. Сбросьте кеш сайта. В самой сборке этой проблемы нет. Сейчас только свежую поставил и все ОК.
Не поверите, перед тем, как написать, раз 5 обновлял кэш. Но только после вашего ответа скрипты пропали. Спасибо!
Поверю. Пожалуйста!
Добрый день. А какие action можно вызывать кроме login ShopMODX.Request.run, в частности интересны для формы обратной связи подобно
var action = 'submit'; ShopMODX.Request.run(action, data)
Согласно примеру дописал в action-процессор
case 'submit': require_once dirname(dirname(__FILE__)) . '/forms/feedback.class.php'; self::$actualClassName = "modWebFormsFeedbackProcessor"; break;
В инспекторе кода вижу ошибку
VM15095:1 Uncaught SyntaxError: Unexpected token < in JSON at position 0
<br /> <b>Fatal error</b>: Call to a member function assign() on a non-object in <b>../core/components/modxsite/processors/site/web/form.class.php</b> on line <b>172</b><br />
Получается недоступен
$this->modx->smarty
в процессоре form если отправлять запрос через аякс. Кто может подсказать как быть?
Всегда говорил: гуглите. Информации полно на множество вопросов :)

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