Расширение pdoTools

Представляю законченное решение для работы с файловыми элементами, собранное в пакет. Оно добавляет в pdoTools модификаторы chunk, snippet, template и code. Синтаксис точно такой же, как и в pdoTools — в названии элементов можно вставлять префиксы @FILE, @INLINE, @CODE и т.д. Поэтому вызовы элементов, описанные в прошлой статье, теперь немного изменились.

Инструкция


Устанавливаем пакет. Затем в системной настройке pdoTools.class нужно указать новый класс «pdotools.pdotoolsplus».
По-умолчанию, путь к файлам элементов core/elements/(chunks|snippets|plugins|templates). Но его можно переопределить с помощью параметра «tplPath».

Теперь подробнее про то, как этим пользоваться.

Чанки

  • Получаем MODX чанк 'head'.
    {'head' | chunk}

  • Получаем чанк из файла core/elements/chunks/head.tpl.
    {'@FILE head.tpl' | chunk}

  • Получаем чанк из файла assets/tpl/main/head.tpl.
    {'@FILE head.tpl' | chunk : ['tplPath'=>'assets/tpl/main/']}

  • Получаем чанк из файла assets/tpl/main/head.tpl.
    {'@FILE main/head.tpl' | chunk : ['tplPath'=>'assets/tpl/']}

  • Получаем inline чанк.
    {'@INLINE <p>Это inline чанк </p>' | chunk}

  • Передаем плейсхолдеры в чанк.
    {'@INLINE <p>Значение плейсхолдера pls - [[+pls]]</p>' | chunk : ['pls'=>'some value'].}

  • Загружаем MODX шаблон 'Bootstrap.Main'.
    {'@TEMPLATE Bootstrap.Main' | chunk}

Данные теги указываются в чанках, шаблонах и ресурсах. Для чанков разрешены расширения 'html' и 'tpl'.

Сниппеты

  • Загружает MODX сниппет 'mySnippet'.
    {'mySnippet' | snippet}

  • Загружает сниппет из файла core/elements/snippets/mysnippet.php.
    {'@FILE mysnippet' | snippet}

  • Загружает сниппет из файла assets/snippets/products/head.tpl.
    {'@FILE mysnippet' | snippet : ['tplPath'=>'assets/snippets/products/']}

  • Загружает сниппет из файла assets/snippets/products/head.tpl.
    {'@FILE products/mysnippet' | snippet : ['tplPath'=>'assets/snippets/products/']}

  • Передаем массив параметров $scriptProperties в сниппет.
    {'@FILE mysnippet' | snippet : ['var1'=>'val1', 'var2'=>'val2']}

  • Передаём параметр в inline сниппет. Также можно использовать префикс @INLINE.
    {'@CODE return "Документ создан " . date("m.d.Y", strtotime($createdon));' | snippet : ['createdon'=>'[[*createdon]]']}

  • Модификатор code вместо префикса @CODE.
    {'return "Документ создан " . date("m.d.Y", strtotime($createdon));' | code : ['createdon'=>'[[*createdon]]']}


Важно!

Inline сниппеты доступны, если системные настройки «pdotools_fenom_modx» и «pdotools_fenom_php» установлены в TRUE.

Указанные выше примеры используются в чанках, шаблонах и ресурсах. В PHP коде для загрузки кода из файла вы можете использовать метод pdoTools::runSnippet(). Он поддерживает префикс @FILE в названии сниппета. Если префикс не указан, то pdoTools запускает метод $modx->runSnippet().

$pdoTools = $modx->getService('pdoTools');
$result = $pdoTools->runSnippet('mySnippet', $arrayOfProperties); // будет запущен MODX method runSnippet('mySnippet', $arrayOfProperties).
$result = $pdoTools->runSnippet('@FILE mysnippet', $arrayOfProperties); // pdoTools загрузит файл core/elements/snippets/mysnippet.php.
Чтобы изменить путь к файлу, в массиве параметров нужно в ключе «tplPath» передать новый путь.

Шаблоны

Существует несколько способов для работы с шаблонами. В первом случае вы создаёте столько шаблонов, сколько вам нужно. И в каждом шаблоне указываете тег фенома.
  • Загрузка MODX шаблона
    {'Bootstrap.Main' | template}

  • Загрузка шаблона из файла core/elements/templates/mainpage.html
    {'@FILE mainpage.html' | template}
Соответственно для каждого ресурса указывается свой шаблон как и раньше.

Второй способ — это перенести всю логику в файл сниппета, который вызывается в шаблоне. И этот шаблон указывается для всех ресурсов.
{@FILE 'gettemplate' | snippet : ['resource'=>$_modx->resource]}

В параметрах передаётся массив с данными ресурса в сниппет.

Код сниппета может быть таким:
<?php  
$output = '';  
switch (true) {  
    // Определяем шаблон для единичных ресурсов
    case ($resource['id'] ==1): // Проверяем id документа  
        $output = $pdoTools->getChunk('@FILE main.html', array('tplPath'=>'core/elements/templates'));  
        break;  
    case ($resource['id'] == 7):
        $output = $pdoTools->getChunk('@FILE contacts.html, array('tplPath'=>'core/elements/templates')');
        break;
    // Определяем шаблон для группы ресурсов. 
    // Если ресурс переместить в другого родителя, то шаблон поменяется автоматически в соответствии с условием.
    case in_array($resource['parent'], array(2,3)): 
        $output = $pdoTools->getChunk('@FILE services.html, array('tplPath'=>'core/elements/templates')');
        break;
    case in_array($resource['parent'], array(4,5)): 
        $output = $pdoTools->getChunk('@FILE news.html, array('tplPath'=>'core/elements/templates')');
        break;        
    default:
        $output = $resource['content']; // Пустой шаблон - только контент страницы.
        break;
}
return $output;

Второй способ немного сложнее первого, но гораздо гибче. Его можно использовать для небольших сайтов. Вы можете объединять эти два способа.

Плагины

Создаём плагин со следующим содержанием:
<?php
if (!empty($this->static_file) && file_exists($this->static_file)) include_once $this->static_file;
Отмечаем событие 'OnMODXInit'.
Теперь нам нужно привязать файл к плагину. Для этого нужно выполнить 4 шага:
  • Отмечаем чекбокс «Статичный файл».
  • В открывшемся поле выбираем наш файл или прописываем руками (core/elements/plugins/myplugin.php).
  • Убираем чекбокс «Статичный файл», чтобы MODX не синхронизировал файл с базой данных.
  • Сохраняем плагин.
Следующим шагом создаем файл плагина и вставляем следующий код:
<?php
// 1. Перечисляем в массиве необходимые события(для примера, "OnWebPagePrerender")  
$events = array('OnWebPagePrerender');
// Две следующие строчки обязательны!
$pdoTools = $modx->getService('pdoTools');
if (!$pdoTools->initPlugin($this, $events, false)); // Третий параметр отвечает за отключение плагина: true - отключает.

// 2. Ваш код для указанных событий
switch ($modx->event->name) {
    case 'OnWebPagePrerender':
        /* Ваш код */
        break;
}
Указываем нужные события, прописываем для них код. Лазить в админку, чтобы отмечать галочки для событий не нужно.

На этом всё. На самом деле всё не так сложно как кажется с первого взгляда.

Преимущества данного решения


  • Все элементы хранятся на диске. Никаких элементов в базе данных. Никаких элементов в дереве элементов.
  • Изменения отражаются сразу же после сохранения файлы.
  • MODX не удаляет кэш всего сайта после изменения элемента.
  • Получаем наслаждение от работы в любимом IDE редакторе.
  • Полноценный контроль версий.

Заключение


Важно знать, что такие элементы не кэшируются MODX. Поэтому, если у вас есть тяжёлые сниппеты или чанки, вам нужно самостоятельно позаботиться о кэшировании результатов. Для этого можно использовать методы setCache() и getCache() класса pdoTools или методы менеджера кэширования MODX modCacheManager.
Теперь вам не нужно так часто ходить в админку. Пробуйте. Это реально очень удобно.
Скачать пакет можно отсюда пока он проходит модерацию в modstore.pro.

П.С. Вполне возможно, что такой функционал в скором времени появится в pdoTools. Но пока Василий занят другими делами, можно экспериментировать с этим решением.
Сергей Шлоков
18 мая 2016, 06:54
modx.pro
7
2 659
+4
Поблагодарить автора Отправить деньги

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

Василий Наумкин
18 мая 2016, 10:41
0
Выполнение произвольного PHP кода без доступа к сниппетам через @CODE — это большая дырка в безопасности.

Комментирование тегов в Fenom делается через звёздочки. Вот так
{*'mySnippet' | snippet*}
А не так
{'@OFF mySnippet' | snippet}

Я рекомендовал modstore.pro не ободрять этот пакет, потому что будущего у него всё равно нет, одна только путаница. Кому нужно — скачают с GitHub.
    Сергей Шлоков
    18 мая 2016, 11:16
    +1
    Выполнение произвольного PHP кода без доступа к сниппетам через @CODE — это большая дырка в безопасности.
    Эта возможность отключается ключами «pdotools_fenom_modx» и «pdotools_fenom_php». Для выполнения кода создается временный сниппет MODX. Могу ошибаться, но мне кажется, что безопасности здесь не меньше, чем в обычных сниппетах.
    Комментирование тегов в Fenom делается через звёздочки.
    Не знал. Не нашёл в документации. У себя комментировал через HTML комментирование.
    Я рекомендовал modstore.pro не ободрять этот пакет, потому что будущего у него всё равно нет
    Вот это странный приговор. Звучит, мягко говоря, очень неуважительно.
      Василий Наумкин
      18 мая 2016, 11:24
      +1
      Пропустил проверку прав, пардон.

      А будущего нет, потому что этот функционал рано или поздно появится в оригинальном pdoTools и далеко не факт, что он будет совместим с твоим.
      Функционал загрузки чанков из файлов там был давным-давно, распространение его на остальные элементы — дело времени и спроса. Которого, кстати говоря, не так-то и много.

      На мой взгляд, неуважительно называть свой компонент pdoToolsPlus.
        Сергей Шлоков
        18 мая 2016, 11:52
        0
        А будущего нет, потому что этот функционал рано или поздно появится в оригинальном pdoTools и далеко не факт, что он будет совместим с твоим.
        Я всего лишь добавил 4 модификатора. Ни один из них сейчас не используется в pdoTools. И логика у них наследуется от pdoTools, в отличие от моего первого варианта в предыдущей статье.
        Функционал загрузки чанков из файлов там был давным-давно, распространение его на остальные элементы — дело времени и спроса. Которого, кстати говоря, не так-то и много.
        Был и есть, но использовать его можно только в параметрах сниппетов. Я сделал такую возможность через модификатор, который вызывает метод pdoTools::getChunk(). Только и всего.
        А по спросу… всё-таки не правильно решать это за пользователей. В магазине есть пакеты, количество скачиваний у который ниже 10.
        На мой взгляд неуважительно называть свой компонент pdoToolsPlus.
        Теперь понятно откуда такая реакция. Приношу извинения. Готов переименовать. Просто я исходил из логики, что это расширение pdoTools. Его нельзя поставить без pdoTools. Как в своё время я делал TicketMessages. Как сейчас называют пакеты для miniShop2. Такое название, например, ptElements будет допустимо?
          Василий Наумкин
          18 мая 2016, 12:12
          0
          Еще раз — этот функционал будет в pdoTools. Зачем тогда нужен этот пакет?

          Его удалять потом из магазина, или ты будешь параллельно свою версию пилить? Сейчас ты меня просто пытаешься вынудить бросить работу с ms2 и побежать пилить этот функционал в pdoTools, чтобы не допустить ненужного размытия функционала.

          Обычно принято присылать PR, но тебе же не терпится. Не нужно так делать.
            Сергей Шлоков
            18 мая 2016, 12:33
            +1
            Обычно принято присылать PR, но тебе же не терпится.
            Я только за. Я тебе в той же теме и намекал по PR. Ты ответил отрицательно. А пакет сделал как раз для того, чтобы тебя не отвлекать от дел. Мне торопится некуда. Сайт у меня и так уже работает с этим функционалом. На нём я и тестировал.
            PR гораздо лучшее решение, чем пакеты. Ничего своего пилить у меня желания нет. Потом допиливать и перепиливать. Тем более, что мне всего хватает в pdoTools. Ну почти всего. )
            П.С. Мы уже больше 3-х лет общаемся. Не проще было сказать «Пришли PR, гляну» вместо слов о рекомендациях modstore не ободрять пакет, про отсутствие будущего и ещё много много других малоприятных слов?
              Василий Наумкин
              18 мая 2016, 12:55
              +3
              Вопрос был «Может пулреквест ускорит процесс? )», ответ «не ускорит».

              Видимо ты прочёл это как «ни в коем случае ничего не присылай!»
              А я имел в виду «сначала очередная версия ms2, а потом всё остальное».
                Сергей Шлоков
                18 мая 2016, 17:49
                0
                Видимо ты прочёл это как «ни в коем случае ничего не присылай!»
                Так точно. Ведь ты написал «Давно уже об этом думаю». И после ответа «Нет, не ускорит», я решил, что ты уже продумал эту тему и как появится время сделаешь.
                Поняли друг друга называется. )

                П.С. Чего-то у меня в FF комментарии добавляются только после обновления страницы.
                  Василий Наумкин
                  18 мая 2016, 19:47
                  +1
                  Давно уже об этом думаю — значит, всё не так просто.

                  Когда выпущу свою версию файловых элементов — сравнишь.
                    Сергей Шлоков
                    18 мая 2016, 20:22
                    +1
                    Ну в данном решении я не стал бы делать акцент на файловые элементы. Это всего лишь 4 модификатора фенома, которые дополняют список твоих модификаторов объектов — user, lexicon и resource. Причем для чанков и шаблонов не пришлось писать ни строчки — используется функционал pdoTools. Добавил только для сниппетов. А загрузка элементов из файлов — это всего лишь одна из возможностей.
                    // Вот загрузка чанка MODX
                    {'myChunk' | chunk}
                    // Вот inline чанк
                    {'@INLINE <p>Динамически созданный чанк</p>' | chunk}
                    // Вот загрузка шаблона MODX
                    {'@TEMPLATE myTemplate' | chunk}
                    // Тоже самое
                    {'myTemplate' | template}
                    Работа только с элементами MODX.
                    Единственный момент — метод initPlugin(). Вот он нужен конкретно для работы с файлом плагина. Если его убрать, то добавляются всего лишь модификаторы для работы с элементами.
                    П.С. Вникаю потихоньку в Fenom. Очень нравятся его возможности.
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    10