[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
10 412

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

Роман
29 мая 2016, 18:17
Просто супер!!!
    Евгений Ка
    29 мая 2016, 23:08
    Правильно ли я понимаю, что раньше вызов runSnippet был всегда некешированный?!
    Хотя странное спросил. Вроде как по логике runSnippet это системная функция.
    Aliaksandr Katlou
    29 мая 2016, 23:12
    Сделал тестовый сайт, парсер вкючил, 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
      elements должен быть внутри core, по умолчанию. А у тебя было вот так:


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

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

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

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

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

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

              Попробуй сравнить самостоятельно и рассказать про это нам.
              Евгений Генералов
              06 июня 2016, 12:29
              Отлично! Попробуем!
                Юрий
                06 июня 2016, 22:56
                У меня ядро вынесено за пределы корневого 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
                Василий, подскажи, пожалуйста, как выводить плейсхолдер некэшированным, по документации не нашел, может плохо искал.
                Добавил кастомное поле даты в свойства товара, в первый раз выводит правильно, обновляю страницу – неправильно)
                Код:
                {'datestart'|placeholder} | {$_modx->getPlaceholder('datestart')} | {$_pls["datestart"]}
                Результат:
                В первый раз:

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

                        Спасибо, Василий!
                  Alexander V
                  10 июля 2016, 22:57
                  Вот такая конструкция в чанке почему-то не сработала. Всё отображается, как надо, но по ссылке logout и авторизации просто обновляется страница. При этом стандартный вызов работает нормально.
                  {$_modx->runSnippet('!HybridAuth', [
                  'providers' => 'yandex,google'
                  'groups' => 'Users:1'
                  ])}
                    Григорий Коленько
                    09 августа 2016, 13:16
                    В стандартном модификаторе 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
                      Как кэшироват вызов сниппета
                      {$_modx->runSnippet('@FILE snippets/game.php', ['param' => 'value'])}

                      V
                      V
                      18 января 2018, 00:22
                      Можно ли закэшировать такой чанк? Кучу запросов к базе делает. Как вообще лучше писать сложные чанки с многими условиями, чтобы кучу чанков не плодить?
                      {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',
                      ]}
                        V
                        V
                        23 января 2018, 20:50
                        выяснил, что передача этой переменной все время генерирует дополнительные запросы к БД:
                        {include 'file:chunks/Cars.tpl' $inTextCarType='sedani'}
                        {'pdoResources' | snippet : [
                            'tplWrapper'=>'@FILE chunks/CarsWrapperTpl.tpl',
                            'tpl'=>'@FILE chunks/CarTpl.tpl',
                            'inTextCarType'=>$inTextCarType,
                        ]}
                        почему так происходит?
                          V
                          V
                          24 января 2018, 22:54
                          del
                        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                        46