[pdoTools] 2.5.0 - файловые элементы

Представляю вам новую версию с улучшенной поддержкой загрузки элементов из файлов.

Теперь из файлов можно грузить не только оформление, но и запускать PHP код. Это позволяет вынести в них почти все элементы системы: шаблоны, чанки, плагины и сниппеты.

Подробная документация, как обычно, вот здесь, а под катом список изменений

Все элементы по умолчанию загружаются из директории, указанной в системной настройке pdotools_elements_path, по умолчанию там
MODX_CORE_PATH . 'elements'
Если вы хотите использовать файловые элементы — то нужно создать её самостоятельно.

Дальше можно загружать сниппеты и чанки через методы pdoTools:
if ($pdoTools = $modx->getService('pdoTools')) {
    $chunk = $pdoTools->getChunk('@FILE chunks/my_chunk.tpl', array('placeholder' => 'value'));

    $snippet = $pdoTools->runSnippet('@FILE snippets/my_snippet.php', array('param' => 'value'));
}

Fenom может делать это двумя способами:
{$_modx->getChunk('@FILE chunks/my_chunk.tpl', ['placeholder' => 'value'])}
{'@FILE chunks/my_chunk.tpl' | chunk : ['placeholder' => 'value']}

{$_modx->runSnippet('@FILE snippets/my_snippet.php', ['param' => 'value'])}
{'@FILE snippets/my_snippet.php' | snippet : ['param' => 'value']}

Так как Fenom изначально рассчитан на работу с файловыми шаблонами, теперь можно использовать его родной провайдер файлов как file:
{include 'file:chunks/my_chunk.tpl'}
А расширение как и раньше, только с указанием file:
{extends 'file:chunks/my_chunk.tpl'}

{block 'myblock'}
    Hello world!
{/block}
Это рекомендуемый способ загрузки файлов из Fenom.

Обычные чанки, которые хранятся в БД, грузятся примерно так же:
{include 'my_chunk'}

Кэширование всех скомпилированных шаблонов включается настройкой pdotools_fenom_cache. Кэш обычных чанков из БД хранится с помощью MODX, а кэшем для file: рулит сам Fenom.

Именно поэтому для файлов в Fenom лучше использовать его собственные методы — он сможет проверить изменения и перегенерировать кэш без обращения к MODX.

Чтобы почистить этот кэш нужно удалить директорию core/cache/default/pdotools или сбросить весь кэш сайта.

Остальные изменения


— Добавлен вывод текущего лога в метод $_modx::getInfo(). Лучше использовать его с модификатором print:
{$_modx->getInfo() | print}
Полезно для отладки.

— Улучшена поддержка debugParser, добавлено логирование основных модификаторов.

— Улучшена загрузка моделей при вызове сниппетов. Теперь можно указывать префиксы.

Заключение


Хочу выразить благодарность за идею и направление реализации Сергею Шлокову.

Теперь с помощью pdoTools и Fenom можно вынести основные элементы в файлы, подключить к ним Git и применять изменения просто выгрузкой на сервер.

Например, создаём шаблон и назначаем его ресурсу. Внутрь пишем
{include 'file:templates/base.tpl'}
Нужно включить системную настройку pdotools_fenom_parser, чтобы Fenom обработал этот шаблон и загрузил его из файла. Дальше мы уже рулим всем оформлением прямо в этом файле.

Например, вот так:
<!doctype html>
<html lang="en">
<head>
    {include 'file:chunks/head.tpl'}
</head>
<body>
<div class="nav-container">
    <nav>
        {include 'file:chunks/header.tpl'}
    </nav>
</div>

<div class="main-container">
    {include 'file:chunks/slider.tpl'}
    {block 'content'}
    {/block}
</div>
{include 'file:chunks/footer.tpl'}
</body>
Эти чанки уже работают чисто из файлов, в БД MODX про них ничего нет. Внутри могут быть вызовы любых сниппетов и чанков системы, как файловых, так и обычных.

Более того, второй шаблон может расширять первый. Его тоже придётся создать в MODX, чтобы назначить ресурсам, а дальше:
{extends 'file:templates/base.tpl'}

{block 'content'}
    {$_modx->getInfo() | print}
{/block}
Расширяем первый шаблон и выводим в контенте информацию.

Обновлено 30.05.2016


Выложил версию 2.5.1-pl, в которой исправлено излишнее кэширование сниппетов.
Василий Наумкин
29 мая 2016, 03:44
modx.pro
16
6 588
+21
Поблагодарить автора Отправить деньги

Комментарии: 46

Роман
29 мая 2016, 18:17
0
Просто супер!!!
    Евгений Ка
    29 мая 2016, 23:08
    0
    Правильно ли я понимаю, что раньше вызов runSnippet был всегда некешированный?!
    Хотя странное спросил. Вроде как по логике runSnippet это системная функция.
    Александр Котлов
    29 мая 2016, 23:12
    0
    Сделал тестовый сайт, парсер вкючил, elements создал, там templates и в ней base.tpl
    получил
    [2016-05-29 23:07:33] (ERROR @ /home/s5520/www/core/components/pdotools/model/pdotools/pdotools.class.php : 944) Template templates/base.tpl not found in fca37e72e79b626b786a3b7dd8147b57 line 1, near '{include 'file:templates/base.tpl'' <- there
    Попробовал на другом — тоже самое. Кто-нибудь проверял уже? Норм работает? Кавычка смущает в логе лишняя…
      Василий Наумкин
      30 мая 2016, 06:26
      0
      elements должен быть внутри core, по умолчанию. А у тебя было вот так:


      Перенёс директорию, заработало.
        Александр Котлов
        30 мая 2016, 10:37
        0
        Василий, спасибо!
          Владимир
          03 июня 2016, 07:54
          0
          Василий, скажи, а не уместен ли теперь новый источник файлов с путем core/elements/ устанавливаемый с pdoTools, типа pdoToolsStaticElements?
            Василий Наумкин
            03 июня 2016, 07:57
            +1
            Неа, источник файлов точно не нужен.

            Да и не советую устанавливать что-то по умолчанию не в components.
              Владимир
              03 июня 2016, 08:07
              0
              Ок, спасибо. Перенес в core/components/elements
              В админке так проще искать новые статичные файлы, с источником ))
                Василий Наумкин
                03 июня 2016, 10:06
                +1
                Я имел в виду, что разработчики MODX сильно не одобряют, когда компонент что-то ставит не в components.

                Например, меня прям отдельно просили убрать из pdoTools классы, которые копировались в core/model/modx.

                А на своём-то сайте ты можешь делать что хочешь, и хранить шаблоны где угодно.
        Paul B.
        30 мая 2016, 04:14
        0
        Вот капец! А я только соорудил «костыли» с помощью какого-то старинного костыля для пдотулс, чтобы хоть частично вынести все чанки и шаблоны через чанки. Но тут вышло это дополнение)))
        Спасибо, очень крутое!
          Klike
          30 мая 2016, 12:26
          1
          0
          del
          Klike
          30 мая 2016, 12:26
          0
          Внимание! После обновления советую проверить кэшированные вызовы {$_modx->runSnippet('Сниппет')} в чанках оформления результатов.
          Василий, на сайте используется несколько вызовов pdoResources, в первом чанк используется обычный, а в других – INLINE. Оба вызова кэшированные, и первый чанк в итоге подставляется в остальные. Если первый вызов сделать некэшированныем, то всё хорошо вроде. Теперь нужно всегда некэшированными сниппеты вызывать? А на скорости это разве не отразится?
            Василий Наумкин
            30 мая 2016, 12:27
            +1
            Это ошибка, только что выложил исправление — обновись, почисти кэш и проверяй.
              Klike
              30 мая 2016, 12:29
              0
              Спасибо, Василий! Теперь всё хорошо)
            Sem
            Sem
            30 мая 2016, 23:05
            0
            Крутой апгрейд pdoTools! Спасибо автору.
            И походу вопрос — Коснулось ли это параметров сниппетов? ну например pdoResources в параметре tpl вызвать чанк, который лежит в файле или по-старинке через параметр tplPath? И у меня почему-то перестал работать параметр tpl c @INLINE, у кого-то были такие проблемы?
              Sem
              Sem
              30 мая 2016, 23:24
              0
              C @INLINE разобрался — руки мои кривые.
              Sem
              Sem
              31 мая 2016, 07:19
              0
              Вчера поздно писал — мозг уже плохо формулировал мысли — сам сегодня перечитал свой комментарий и не совсем понял о чём там — суть хотел передать следующую — в сниппетах pdoTools можно писать tpl параметр через @FILE, который по-умолчанию /assets/elements/chunks/ — так может его теперь тоже core/elements/ сделать — место очень удобное выбрано близко от корня и закрыто как и ядро, да и при написании сниппетов не придётся постоянно параметр tplPath указывать.
                Василий Наумкин
                31 мая 2016, 07:38
                0
                Так и сделано, просто не указывай больше &tplPath.
                  Sem
                  Sem
                  31 мая 2016, 07:42
                  0
                  Круто! Василий, спасибо большое за твой труд. Теперь реально можно слезать с modxSmarty — Fenom рулит!!!
                Sem
                Sem
                01 июня 2016, 22:43
                0
                Не могу нарадоваться тому что теперь все проекты можно разрабатывать в любимой IDE да ещё и с Fenom-ом, и тут меня посетила давняя мысль — в компоненте modxSmarty с которого я сейчас по-тихоньку слезаю, автором была заявлена очень интересная фича — когда ты залогинен в контексте mgr системная настройка с путём ко всем шаблонам могла быть изменена только для тебя — это бы дало возможность дорабатывать страницы, редизайнить их и экспериментировать на живом проекте и с живыми данными, но как бы со своим оформлением, в моей работе это очень актуальный вопрос — клиенты просят побыстрее запустить сайт и потом походу его дорабатывать, но на живом сайте вести доработки, особенно визуальные, которые надо тестить постоянно не очень то удобно, да и пользователям видеть эти полу-доработки ни к чему. В MODX есть классная штука, что, будучи авторизованным в mgr можно смотреть ещё не опубликованные ресурсы, но если шаблоны для этих ресурсов содержат хоть сколько нибудь сложную структуру с вызовами кучи сниппетов — это надо постоянно везде указывать параметры типа showUnpublished, а они есть не у всех сниппетов. Так вот к чему я это всё — было бы круто выставить допустим админу настройку pdotools_elements_path с другим путем отличным от общих шаблонов и если он авторизован в mgr то ему показывать шаблоны из этого пути, давая возможность параллельно вести доработку проекта. Что скажете? Вообще кому нибудь ещё интересна и полезна такая штука?
                  Василий Наумкин
                  02 июня 2016, 05:09
                  +1
                  Скажу что все файлы грузятся из пути, указанного в pdotools_elements_path. Это системная настройка, которая перекрывается настройками пользователя.

                  Осталось сложить 2 + 2.
                    Sem
                    Sem
                    02 июня 2016, 07:22
                    0
                    Работает))
                      Василий Наумкин
                      02 июня 2016, 07:31
                      +2
                      Может, юзер должен быть авторизован в контексте, чтобы применялись его настройки, как думаешь?
                        Sem
                        Sem
                        02 июня 2016, 07:34
                        0
                        Да, Василий, беру слова обратно — всё работает как часы. Спасибо за столь ранний ответ.
                  Руслан Кундиус
                  02 июня 2016, 15:53
                  +1
                  Не уверен с какой версии, но появилась следующая проблема: если на странице два(и более) одинаковых сниппета с разными наборами параметров, во всех будет использован первый набор. Вот пример (второй блок должен быть желтым).

                  Насколько я понимаю, здесь ключом является только название сниппета, без параметров, и все последующие наборы игнорируются.
                  Семён Лобачевский
                  05 июня 2016, 12:12
                  0
                  А если сравнивать скорость работы через хранение в файлах или в базе, где выше?
                    Василий Наумкин
                    05 июня 2016, 12:25
                    +1
                    Не знаю.

                    Попробуй сравнить самостоятельно и рассказать про это нам.
                    Eugene Generalov
                    06 июня 2016, 12:29
                    0
                    Отлично! Попробуем!
                      Юрий
                      06 июня 2016, 22:56
                      0
                      У меня ядро вынесено за пределы корневого web-каталога. При этом при работе pdoTools в корневом каталоге создается директория путь_до_ядра/cache/default/pdotools/file, согласно строке 33 файла _fenom.php

                      pdoTools 2.5.2
                      MODX 2.5.0
                      PHP 7.0.7
                      Klike
                      05 июля 2016, 18:06
                      0
                      Василий, подскажи, пожалуйста, как выводить плейсхолдер некэшированным, по документации не нашел, может плохо искал.
                      Добавил кастомное поле даты в свойства товара, в первый раз выводит правильно, обновляю страницу – неправильно)
                      Код:
                      {'datestart'|placeholder} | {$_modx->getPlaceholder('datestart')} | {$_pls["datestart"]}
                      Результат:
                      В первый раз:

                      После обновления страницы:
                        Василий Наумкин
                        06 июля 2016, 04:42
                        0
                        Выглядит как версия miniShop2.4-beta2, а не rc.
                          Klike
                          06 июля 2016, 05:42
                          0
                          miniShop2.2.0-pl2))
                            Василий Наумкин
                            06 июля 2016, 05:45
                            +1
                            Еще лучше. Тогда, наверное, только делать страницу некэшированной.
                              Klike
                              06 июля 2016, 05:50
                              0
                              Да, некэшированная страница помогла, но так быстрее загружается:
                              [[+datestart:strtotime:date=`%d %b`]]

                              Спасибо, Василий!
                        Alexander V
                        10 июля 2016, 22:57
                        0
                        Вот такая конструкция в чанке почему-то не сработала. Всё отображается, как надо, но по ссылке logout и авторизации просто обновляется страница. При этом стандартный вызов работает нормально.
                        {$_modx->runSnippet('!HybridAuth', [
                        'providers' => 'yandex,google'
                        'groups' => 'Users:1'
                        ])}
                          Григорий Коленько
                          09 августа 2016, 13:16
                          0
                          В стандартном модификаторе fuzzydate есть строки
                          if ($time >= strtotime('today')) {
                                              $output = $modx->lexicon('today_at', array('time' => strftime('%I:%M %p', $time)));
                                          } elseif ($time >= strtotime('yesterday')) {
                                              $output = $modx->lexicon('yesterday_at', array('time' => strftime('%I:%M %p', $time)));
                                          } else {
                                              $output = strftime($format, $time);
                                          }
                          Они выводят следующее, если дата публикации, к примеру 00:13, то получим: «сегодня в 12:13»
                          Т.е. пользователя это может ввести в заблуждение по поводу даты публикации. Так задумывалось?
                          Не было бы вернее заменить %I на %k, чтобы вывело «сегодня в 0:13»?
                          Или я что-то упустил
                            TITAN-UZ
                            02 сентября 2016, 22:47
                            0
                            Как кэшироват вызов сниппета
                            {$_modx->runSnippet('@FILE snippets/game.php', ['param' => 'value'])}

                            Viktor
                            18 января 2018, 00:22
                            0
                            Можно ли закэшировать такой чанк? Кучу запросов к базе делает. Как вообще лучше писать сложные чанки с многими условиями, чтобы кучу чанков не плодить?
                            {include 'file:chunks/Cars.tpl' $inTextCarType='limo' $limit='0'}
                            Cars.tpl:
                            {if $limit != null}
                                {var $limit = $limit}
                                {else}
                                {var $limit = 4}
                            {/if}
                            {if $inTextCarType?}
                                {switch $inTextCarType}
                                    {case 'limo'}
                                        {var $catalogID = 12}
                                    {case 'sedani'}
                                        {var $catalogID = 9}
                                    {case 'dzhipi'}
                                        {var $catalogID = 10}
                                    {case 'retro'}
                                        {var $catalogID = 11}
                                    {case 'mikroBus'}
                                        {var $catalogID = 134}
                                {/switch}
                                
                                {else}
                                
                                {var $catalogID = $_modx->resource.parent}
                                {var $resourcesNeeded = -$_modx->resource.id}
                                {switch $catalogID}
                                    {case 12}
                                        {var $header = '<div class="headline"><h3>Другие популярные <a href="'~$catalogID|url~'">лимузины</a></h3></div>'}
                                    {case 9}
                                        {var $header = '<div class="headline"><h3>Другие популярные <a href="'~$catalogID|url~'">седаны</a></h3></div>'}
                                    {case 10}
                                        {var $header = '<div class="headline"><h3>Другие популярные <a href="'~$catalogID|url~'">джипы</a></h3></div>'}
                                    {case 11}
                                        {var $header = '<div class="headline"><h3>Другие популярные <a href="'~$catalogID|url~'">ретро авто</a></h3></div>'}
                                    {case 134}
                                        {var $header = '<div class="headline"><h3>Другие популярные <a href="'~$catalogID|url~'">микроавтобусы</a></h3></div>'}
                                    {case default}
                                        {var $header = '<div class="headline"><h3>Популярные <a href="'~3|url~'">авто</a></h3></div>'}
                                        {var $catalogID = '9,10,11,12,134'}
                                        {var $resourcesNeeded = '13,27,26,25'}
                                {/switch}
                            {/if}
                            
                            
                            {'pdoResources' | snippet : [
                                'tplWrapper'=>'@FILE chunks/CarsWrapperTpl.tpl',
                                'tpl'=>'@FILE chunks/CarTpl.tpl',
                                'parents'=>$catalogID,
                                'resources'=>$resourcesNeeded,
                                'header'=>$header,
                                'inTextCarType'=>$inTextCarType,
                                'limit'=>$limit,
                                'sortby'=>'menuindex',
                            ]}
                              Viktor
                              23 января 2018, 20:50
                              0
                              выяснил, что передача этой переменной все время генерирует дополнительные запросы к БД:
                              {include 'file:chunks/Cars.tpl' $inTextCarType='sedani'}
                              {'pdoResources' | snippet : [
                                  'tplWrapper'=>'@FILE chunks/CarsWrapperTpl.tpl',
                                  'tpl'=>'@FILE chunks/CarTpl.tpl',
                                  'inTextCarType'=>$inTextCarType,
                              ]}
                              почему так происходит?
                                Viktor
                                24 января 2018, 22:54
                                0
                                del
                              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                              46