[pdoTools] 2.0.0-beta c шаблонизатором Fenom


Представляю вам новую версию pdoTools со встроенным шаблонизатором Fenom.

Это очередная попытка решить вопрос с очень бедным MODX шаблонизатором, который умеет очень мало. Первая «велосипедная» попытка была представлена здесь, а сейчас всё гораздо серьёзнее.

Если вы не знакомы с Fenom, то советую прочитать вот эту заметку на Хабре, а потом пробежаться по документации на GitHub.

Возможности

  • Включение поддержки Fenom раздельно для каждого сниппета pdoTools.
  • Можно использовать плейсхолдеры MODX и теги Fenom одновременно. Но быстрее будет использовать что-то одно.
  • Если в чанке нет плейсхолдеров MODX, то парсер MODX не запускается
  • Если в чанке нет тегов Fenom, то он тоже не запускается.
  • @INLINE чанки работают
В отличии от других решений, вам не нужно никаким образом менять или переписывать свои сниппеты — всё крутится через методы pdoTools::getChunk() и pdoTools::parseChunk() автоматически.

Особенности

Для включения шаблонизатора в вызове любого сниппета pdoTools нужно указать
&useFenom=`1`

Все ошибки компиляции пишутся в системный журнал. Если видите сырые теги — смотрите там, в чем беда.

У вас есть доступ к объектам $modx и $pdoTools, а также всем их свойствам и методам. Теперь вы можете делать разные проверки переменных и оформлять вывод как вам захочется без фильтров вывода и прочих сложных конструкций.
Адрес сайта: {$modx->config.site_url}

{if $modx->user->isAuthenticated($modx->context->key)}
	Юзер авторизован в контексте
{else}
	Это гость
{/if}

Шаблоны компилируюся и сохраняются в директорию /cache/fenom/. При очистке кэша сайта они удаляются.

Строковые плейсхолдеры [[+section.pagetitle]] превращаются в {$section_pagetitle}, так как Fenom ожидает через точку ключ массива. То есть {$section.pagetitle} — это для него $section['pagetitle'].

Тестирование

Лично я уже переписал основные чанки modx.pro на синтаксис Fenom — багов пока не замечено. Даже на моих старых полностью оптимизированных чанках, максимально разогнанных в pdoTools, я заметил прирост от 20% до 50% при более удобном синтаксисе.

Например, наша самая большая тема с 437 комментариями раньше открывалась за 1.3-1.5 сек, теперь за 0.7-0.9 сек.

Синтетический тест из этой темы показывает небольшой перевес чистого pdoTools над Fenom, если в чанке нет ни одного фильтра вывода (то есть, работает только str_replace(), без парсера MODX).

pdoTools
0.0005119: Created inline chunk
0.1967380: Total time
3 670 016: Memory usage
Fenom
0.0004470: Created inline chunk
0.2136431: Total time
3 407 872: Memory usage

А вот если добавить всего один плейсхолдер, который должен быть разобран парсером MODX
// pdoTools
$tpl1 = '@INLINE <p>[[++site_name]] [[+val1]] - [[+val2]] - [[+val3]]</p>';
// Fenom
$tpl2 = '@INLINE <p>{$modx->config.site_name} {$val1} - {$val2} - {$val3}</p>';

То результат будет совсем иной:
pdoTools
0.0003500: Created inline chunk
1.8580759: Total time
3 670 016: Memory usage
Fenom
0.0004060: Created inline chunk
0.2227199: Total time
3 932 160: Memory usage
Да-да, это не ошибка!

Fenom может работать с объектом MODX напрямую, и ему не нужно парсить его плейсхолдеры — отсюда практически полное отсутствие тормозов при проверках переменных и вызове системных методов.

Скомпилированный шаблон выглядит вот так:
<?php 
/** Fenom template 'cd20f5e1f2f6add74ba06c086f8b8242.fenom.tpl' compiled at 2015-05-18 21:44:23 */
return new Fenom\Render($fenom, function ($var, $tpl) {
?><p><?php
/* cd20f5e1f2f6add74ba06c086f8b8242.fenom.tpl:1: {$modx->config.site_name} */
 echo $var["modx"]->config["site_name"]; ?> <?php
/* cd20f5e1f2f6add74ba06c086f8b8242.fenom.tpl:1: {$val1} */
 echo $var["val1"]; ?> - <?php
/* cd20f5e1f2f6add74ba06c086f8b8242.fenom.tpl:1: {$val2} */
 echo $var["val2"]; ?> - <?php
/* cd20f5e1f2f6add74ba06c086f8b8242.fenom.tpl:1: {$val3} */
 echo $var["val3"]; ?></p><?php
}, array(
	'options' => 0,
	'provider' => false,
	'name' => 'cd20f5e1f2f6add74ba06c086f8b8242.fenom.tpl',
	'base_name' => 'cd20f5e1f2f6add74ba06c086f8b8242.fenom.tpl',
	'time' => 1431974663,
	'depends' => array (
  0 => 
  array (
    'cd20f5e1f2f6add74ba06c086f8b8242.fenom.tpl' => 1431974663,
  ),
),
	'macros' => array(),

        ));
Ну и напоследок несколько примеров для гладкого переезда.

Примеры

Замена плейсхолдеров:
[[+pagetitle]]	- {$pagetitle}
[[*pagetitle]]	- {$modx->resource->pagetitle}
[[%lexicon]]	- {$modx->lexicon('lexicon')}
[[~[[+id]]]]	- {$modx->makeUrl($id)}

Вот какой был старый чанк tpl.Tickets.comment.wrapper блока комментариев.
А вот как я переписал его на Fenom:
<div class="comments">
	{if $modx->user->isAuthenticated($modx->context->key)}
	<span class="comments-subscribe pull-right">
		<label for="comments-subscribe" class="checkbox">
			<input type="checkbox" name="" id="comments-subscribe" value="1" {$subscribed != '' ? 'checked' : ''} /> {$modx->lexicon('ticket_comment_notify')}
		</label>
	</span>
	{/if}
 
	<h4 class="title">{$modx->lexicon('comments')} (<span id="comment-total">{$total}</span>)</h4>
 
	<div id="comments-wrapper">
		<ol class="comment-list" id="comments">{$comments}</ol>
	</div>
 
	<div id="comments-tpanel">
		<div id="tpanel-refresh"></div>
		<div id="tpanel-new"></div>
	</div>
</div>

Еще пример старого чанка tpl.Tickets.comment.list.row.
И новая Fenom-версия:
<div class="ticket-comment-row ticket-comment" id="comment-{$id}" data-id="{$id}">
	<div class="ticket-comment-body {$guest ? 'ticket-comment-guest' : ''}">
		<div class="ticket-comment-header">
			<div class="user-avatar-wrapper">
				<img src="{$avatar}" class="ticket-avatar" alt="" />
			</div>
			<span class="ticket-comment-author">{$fullname}</span>
			<span class="ticket-comment-createdon">{$date_ago}</span>
			<span class="ticket-comment-link"><a href="{$url}#comment-{$id}">#</a></span>
			<span class="ticket-comment-star {$can_star ? 'active' : ''}">
				<i class="glyphicon glyphicon-star {$stared ? 'stared' : 'unstared'} star"></i>
			</span>

			<span class="ticket-comment-rating {$can_vote ? 'active' : 'inactive'}">
				<span class="rating {$rating_positive ? 'positive' : ''}{$rating_negative ? 'negative' : ''}" title="Всего: {$rating_total}: ↑{$rating_plus} и ↓{$rating_minus}">{$rating}</span>
				<span class="vote plus {$voted_plus ? 'voted' : ''}" title="Нравится"><i class="glyphicon glyphicon-arrow-up"></i></span>
				<span class="vote minus {$voted_minus ? 'voted' : ''}" title="Не нравится"><i class="glyphicon glyphicon-arrow-down"></i></span>
			</span>
		</div>
		<div class="ticket-comment-text">
			{$text}
		</div>
	</div>

	<div class="ticket-comment-meta">
		<a href="{$modx->makeUrl($section_id)}" class="ticket-comment-section"><i class="glyphicon glyphicon-folder-open"></i> {$section_pagetitle}</a> →
		<a href="{$modx->makeUrl($ticket_id)}" class="ticket-comment-ticket">{$ticket_pagetitle}</a>  
		<span class="ticket-comment-comments">
			<small><i class="glyphicon glyphicon-comment"></i> {$comments}</small>
		</span>
	</div>
</div>
Обратите внимание на свободный вызов {$modx->makeUrl()} и другие интересные конструкции.

А вот вообще отмороженный пример:
[[!pdoResources?
	&useFenom=`1`
	&parents=`999999`
	&wrapIfEmpty=`1`
	&tplWrapper=`@INLINE 
		{set $collection = $pdoTools->getCollection('modResource', null, ['parents' => 0, 'limit' => 10])}
		{foreach $collection as $idx => $res}
			<p>{$res.id} - {$res.pagetitle}</p>
			{$pdoTools->addTime('Строка ' ~ $idx)}
		{/foreach}
		<pre>{$pdoTools->getTime()}</pre>
	`
]]
Вызов метода pdoTools с присвоением его результата переменной и разбор её в цикле.

pdoResources тут нужен только для запуска шаблона с Fenom.

Заключение

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

Технически в pdoTools изменений немного, но по факту — это огромный тектонический сдвиг в разработке сайтов с использованием библиотеки. Поэтому версия теперь 2.0.0-beta.

Наверное, будут вопросы, а почему именно Fenom, а не Twig, Smarty или кто-то еще? Вот мой список причин:
  • Использование токенайзера вместо регулярок — выше скорость и ниже расход ОЗУ
  • Автор — русскоговорящий и пишет документацию на родном языке
  • Приятный php-подобный синтаксис, особенно что касается работы с массивами и объектами.
  • Приятный исходный код.
  • Судя по активности на GitHub, впереди у проекта светлое будущее
  • Ну и наконец, я уже использовал его для работы на одном крупном кинопортале и остался доволен.
Обновляемся, тестируем, пишем отзывы.

Обновлено 20.05.2015

Выложил в репозиторий версию 2.0.0-rc, в которой pdoParser уже использует Fenom. Теперь новый синтакис можно использовать прямо в контенте документов и шаблонах.

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

Обновлено 21.05.2015

Итак, после долгих размышлений и тестов я переписал работу с Fenom так, чтобы скомпилированные шаблоны кэшировались только в ОЗУ.

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

Чанки MODX не пишутся на диск, а Fenom не кэширует компилированные шаблоны рядом. Никакого мусора, всё быстро и красиво. Теперь Fenom показывает небольшой отрыв даже на простейших чанках без фильтров.

Ошибки компиляции, как и прежде, пишутся в журнал MODX. Так как исходники вам теперь посмотреть негде, на уровне INFO в лог отправляется и сам шаблон. Просто переключите системную настройку MODX log_level, чтобы это увидеть.

Так как Fenom предъявляет требования к именам переменных такие же, как и PHP, наши привычные плейхолдеры просто ломают компиляцию. Поэтому в новой версии все переданные плейсхолдеры можно найти в {$_pls}.
Например, плейсхолдеры превьюшек галереи получаем вот так:
[[!ms2GalleryResources?
	&typeOfJoin=`inner`
	&parents=`0`
	&tpl=`@INLINE
		<p><a href="{$uri}"><img src="{$_pls['120x90']}" /></a> {$rank}</p>
	`
]]
Точно так же получаем и плейсхолдеры с точкой:
{$_pls['section.uri']}
Больше никакой замены точек на подчеркивание в именах переменных — всё ради повышенной скорости работы.

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

Новая версия pdoTools 2.0.0-rc2 уже доступна в репозитории, обновляйтесь!

Анонс стабильной версии с множеством дополнительных настроек.
18 мая 2015, 22:11    Василий Наумкин   G+  
10    6150 +17

Комментарии (176)

  1. Aleksandr PL 18 мая 2015, 22:17 # 0
    Василий, такой вопрос: после обновления на 2.0.0 в попытке обновить сайт (очистить кеш) в консоли появилась ошибка

    Консоль запущена…
    PHP warning: Invalid argument supplied for foreach()
    Очистка основного кэша: pdoTools

    Этого предупреждения на прошлой версии pdoTools пару минут назад не было.
    Это как-то связано с этим обновлением похоже. В логах ошибок сайта пусто.
    1. Василий Наумкин 18 мая 2015, 22:22 # 0
      Это ерунда.

      При очистке кэша происходит удаление скомпилированных шаблонов, а у тебя еще нет этой директории. Просто игнорируй, больше не должно появляться.
      1. Aleksandr PL 18 мая 2015, 22:33 # 0
        Понимаю, что это не ошибка, а предупреждение. Да и все работает. Только предупреждение это не исчезает и выскакивает при каждой очистке кеша. Проверил на другом сайте — тоже есть. Может стоит добавить проверку на существование папки шаблонов Fenom (для тех, кто пока не использует Fenom), чтобы народ не волновался?
        1. Василий Наумкин 18 мая 2015, 22:41 # 0
          Если не хочешь волноваться — не обновляйся на beta версии.

          Конечно я это поправлю, но потом.
          1. Aleksandr PL 18 мая 2015, 22:50 # 0
            Спасибо.
            1. Василий Наумкин 18 мая 2015, 22:51 # 0
              Уже поправил этот баг и еще такой же мелкий =)

              Правда, если ты не планируешь пробовать Fenom, то обновляться вовсе не нужно — там больше нет никаких изменений.
    2. Сергей Скат 18 мая 2015, 23:29 # 0
      Я так понимаю что наличие этого шаблонизатора в коробке pdoTools позволит создавать более сложную логику? например мат операции и тд и тп? просто никогда не работал со Smarty, а документацию пробежал мельком, я вот чем то задним чувствую что это здорово и надо начать этим пользоваться, только пока не очень пойму как и зачем?
      1. Сергей Скат 18 мая 2015, 23:31 # 0
        в смысле зачем понятно, не понятно как
        1. Василий Наумкин 18 мая 2015, 23:42 # 0
          Например, вот так:
          [[!pdoResources?
          	&useFenom=`1`
          	&parents=`0`
          	&tpl=`@INLINE <p>{$id} - {$menutitle != '' ? $menutitle : $pagetitle}</p>`
          ]]
          
          Плюс посмотри в заметке примеры, а дальше читать уже в документации Fenom.
          1. Сергей Скат 18 мая 2015, 23:51 # 0
            ага, т/е получается все стандартные теги modx типа [[*pagetitle]] заменяются тегами шаблонизатора {{$pagetitle}}? в таком случае какой именно pagetitle подгрузится? этот [[*pagetitle]] или этот [[+pagetitle]]?
            1. Василий Наумкин 18 мая 2015, 23:54 # 0
              Включай фантазию!

              [[+pagetitle]]	- {$pagetitle}
              [[*pagetitle]]	- {$modx->resource->pagetitle}
              [[%lexicon]]	- {$modx->lexicon('lexicon')}
              [[~[[+id]]]]	- {$modx->makeUrl($id)}
              1. Сергей Скат 18 мая 2015, 23:57 # 0
                ага ясно, более или менее, ответь еще все же пожалуйста поконкретнее про мат операции, меня это часто волнует, а писать мелкие сниппеты или через js делать часто не очень хочется, хочется чтобы вычисление происходило сразу в чанке, с fenom это возможно?
                  1. Сергей Скат 18 мая 2015, 23:59 # 0
                    фантазия есть, я пытаюсь понять спектр возможностей, большое спасибо за умные ответы на глупые вопросы, буду разбираться
      2. Володя 18 мая 2015, 23:49 # +3
        Это просто Ах… О очень замечательно! Нет слов…
        1. Виталий Серый 19 мая 2015, 01:37 # 0
          Уже ради одних тернарных операторов хочется пользовать.
          Очень порадовало, что в @INLINE чанках нормально отрабатывают сложные логические конструкции.
          Спасибо!
          1. Мордынский Николай 19 мая 2015, 01:42 # 0
            Василий, добавь пожалуйста примеры перехода с modx парсера на Fenom при применении фильтра к плейсхолдеру для общего понимания.

            К примеру:
            [[+price:default=`ноль`:eq=`5`:then=`пять`]]
            Думаю актуално не только для меня.Спасибо!!!

            А все вижу пример ))
            {$id} - {$menutitle != '' ? $menutitle : $pagetitle}
            1. Григорий Коленько 19 мая 2015, 02:10 # 0
              Прочитал статью на хабре. Просто какое-то невероятное решение, состоящее из одних плюсов. Если так, то надо выкидывать парсер мод икса и использовать только феном :)
              1. Сергей Скат 19 мая 2015, 02:41 # 0
                беда в том что он у нас есть только в pdoTools, интересно насколько возможно полностью перейти на другой шаблонизатор?
                1. Dmitry Rodionov 19 мая 2015, 02:51 # +1
                  интересно, перепишу интернет магазин с 10к+ товарами посмотрим прирост
                  1. Dmitry Rodionov 19 мая 2015, 02:58 # 0
                    Можно включить парсер для всего сайта? Например чанки которые не вызываются в pdoTools как парсить?
                    1. Василий Наумкин 19 мая 2015, 06:05 # 0
                      Парсер работает иначе, так что пока — никак.
                      1. Dmitry Rodionov 19 мая 2015, 11:56 # 0
                        Надеюсь в будущем это изменится, филосов modSmarty же двигает, но феном реально по скорости и памятижорству эффективнее. Интересно было бы если бы феном вешался на текущие конструкции modx и парсил их)))
                        Удачи с парсером, мы все с замиранием сердца наблюдаем за этим ;)
                        1. Василий Наумкин 19 мая 2015, 12:00 # 0
                          Позже поэксперементирую, а пока давайте осваивать новые чанки.
                          1. Андрей 20 мая 2015, 00:22 # 0
                            А с чем связана такая тормознутость родного парсера MODX? Казалось бы, даже не на рекурсивных вызовах тормоза налицо.
                            И осталась ли возможность использовать специальные плейсхолдеры типа [[#12.pagetitle]]?

                            P.S. блин, только все чанки в ИМ на 50к товаров переписал на «быстрые плейсхолдеры». Прошла неделя — бам, новый pdoTools)))
                            1. Василий Наумкин 20 мая 2015, 00:31 # +1
                              Как минимум с тем, что парсер MODX выбирает теги регулярками, создаёт из них объекты и запускает на выполнение.

                              pdoParser пробует их выполнить без объектов, а если не может — отдаёт в парсер MODX.

                              Ну а Fenom просто и без затей компилирует шаблон в исполняемый PHP код, который полюбому будет быстрее.

                              И осталась ли возможность использовать специальные плейсхолдеры типа [[#12.pagetitle]]?
                              Конечно. Теперь можно даже так:
                              {$modx->getObject('modResource', 12)->pagetitle}
                              1. Андрей 20 мая 2015, 01:04 # 0
                                Конечно. Теперь можно даже так:
                                {$modx->getObject('modResource', 12)->pagetitle}
                                Подразумеваю, что это будет практически одно и то же по скорости с [[#12.pagetitle]], а если вызвать в коде ресурса сниппет с кодом:
                                $res = $modx->getObject('modResource', 12);
                                return $res->pagetitle;
                                то это будет дольше из-за выше приведенных причин парсера MODX, правильно понимаю?

                                Василий, ещё такой вопрос. Что будет быстрее работать, если вызвать в коде ресурса с id 10?
                                [[~[[*id]]]] - долго, рекурсивно
                                [[~10]] - долго, с makeUrl
                                [[*uri]] - быстрее
                                [[#[[*id]].uri]] - долго, рекурсивно с парсером MODX
                                [[#10.uri]] - быстрее
                                {$modx->resource->uri} - аналогично верхнему
                                {$resource->uri} (можно??)
                                Просто каша в голове от нового синтаксиса шаблонизатора. Надо поспать, чтобы уложилось))
                                1. Василий Наумкин 20 мая 2015, 06:35 # 0
                                  Предлагаю это всё тебе протестировать самостоятельно, когда выспишься.
                                  1. Андрей 20 мая 2015, 13:31 # 0
                                    Василий, на тестовых сайтах modhost у pdoTools по умолчанию отключен pdoParser. Может, стоит включить по дефолту.
                                    При переустановке опции тоже не выбрать. Приходится или сносить и заново ставить пакет или искать и вбивать значения настроек parser_class и parser_class_path.
                                    1. Василий Наумкин 20 мая 2015, 13:39 # 0
                                      Просто устанавливай пакет вручную.

                                      По умолчанию парсер я не буду включать по многим причинам.
                                      1. Андрей 20 мая 2015, 13:52 # 0
                                        Хозяин — барин…
                                        Тогда этот коммент останется для потомков, чтобы знали, что pdoParser на тестовых сайтах при автоустановке по умолчанию выключен.
                                        Значение настроек:
                                        Ключ - Значение
                                        parser_class - pdoParser
                                        parser_class_path - {core_path}components/pdotools/model/pdotools/
                      2. Виталий Киреев 19 мая 2015, 07:13 # 0
                        А вложенные сниппеты можно как-нибудь вызывать? Например,
                        {$modx->runSnippet('TicketMeta', array('id' => $id, 'tpl' => 'Project.row.Star', 'getSection'=>0, 'getUser'=>0, 'getFiles'=>0, 'unusedFiles'=>0))}
                        ругается на
                        Unexpected token 'array' in argument list in 676e9e1966946be21d1ccec95e5b8917.fenom.tpl line 36, near '{$modx->runSnippet('TicketMeta', array' < — there
                        1. Виталий Киреев 19 мая 2015, 07:28 # 0
                          Вместо array получилось в квадратных скобках, но это получается только для PHP>=5.4. В документации не обнаружил, с какой поддерживается.

                          А что с кешированием? Получается вложенные будут выполняться каждый раз?
                          1. Василий Наумкин 19 мая 2015, 07:47 # +1
                            Это же шаблон, а не чистый php, смотри во что он компилируется:
                            <?php
                            /* 24c0b6e2dc0f6d70b87e26de577f6829.fenom.tpl:9: {$modx->runSnippet("TicketMeta", [
                            	"id" => $id,
                            	"tpl" => "Project.row.Star",
                            	"getSection"=>0,
                            	"getUser"=>0,
                            	"getFiles"=>0,
                            	"unusedFiles"=>0
                            ])} */
                             echo $var["modx"]->runSnippet("TicketMeta", array("id" => $var["id"], "tpl" => "Project.row.Star", "getSection" => 0, "getUser" => 0, "getFiles" => 0, "unusedFiles" => 0));
                            Fenom требует PHP 5.3.

                            А что с кешированием? Получается вложенные будут выполняться каждый раз?
                            А кэшированием тебе придётся озаботиться самостоятельно.
                            1. Для долговремнного хранения есть {$modx->cacheManager->get()} и {$modx->cacheManager->set()}
                            4. Для кэширования во время выполнения {$pdoTools->getStore()} и {$pdoTools->setStore()}.
                            3. Можно даже сохранять в произвольные файлы через {$.php.file_put_contents()}.

                            github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md
                          2. Василий Наумкин 19 мая 2015, 07:37 # 0
                            Fenom позволяет добавлять свои функции и упрощалки синтаксиса, так что в будущем я этим еще займусь.

                            А пока можно делать вот так:
                            {$modx->runSnippet("TicketMeta", [
                            	'id' => $id,
                            	'tpl' => 'Project.row.Star',
                            	'getSection' => 0,
                            	'getUser' => 0,
                            	'getFiles' => 0,
                            	'unusedFiles' => 0
                            ])}
                            1. Spam 19 мая 2015, 08:31 # 0
                              не подскажешь как получить pagetitle и uri родителя
                              1. Василий Наумкин 19 мая 2015, 08:43 # +1
                                [[!pdoResources?
                                	&useFenom=`1`
                                	&parents=`0`
                                	&tpl=`@INLINE
                                	<p>Данные ресурса: {$id} - {$pagetitle}
                                		{if $parent != 0}
                                			{set $doc = $pdoTools->getArray('modResource', $parent, ['select' => 'pagetitle,uri'])}
                                			{if $doc}
                                				<ul>Данные родителя: {$doc.pagetitle} - {$doc.uri}</ul>
                                			{/if}
                                		{/if}
                                	</p>
                                	`
                                ]]
                                1. Spam 22 мая 2015, 14:32 # 0
                                  а если надо вывести в шаблоне, без pdoResource. Тогда легче будет [[#[[*parent]].pagetitle]]?
                                  1. Василий Наумкин 22 мая 2015, 14:53 # 0
                                    Ну а эта конструкция, по твоему, как-то магически данные получает, без запросов в БД?

                                    Бери плейсхолдер [^t^], делай разные запросы и замеряй производительность.
                                    1. Spam 22 мая 2015, 14:56 # 0
                                      ну я имел виду, что данная конструкция не работает за рпеделами pdoResource, мне неоходимо вывести в шаблоне main и page как пример в хедере
                                      1. Василий Наумкин 22 мая 2015, 14:59 # 0
                                        Что-то мне надоело угадывать, что ты имел в виду.

                                        Давай дальше сам.
                            2. Сергей Шлоков 19 мая 2015, 08:46 # +1
                              Реально большой прорыв. Отличная новость!
                              1. Dmitry Rodionov 19 мая 2015, 12:44 # 0
                                Я так понимаю надо переписать дефолтные чанки например у pdoMenu и включить феном чтобы все работало эффективнее?
                                1. Василий Наумкин 19 мая 2015, 13:09 # 0
                                  В родных чанках pdoTools нет никаких фильтров вывода и условий, так что там вряд ли что-то ускорится.

                                  Но попробовать можно, почему бы и нет? Напиши о результатах, если будешь делать.
                                  1. Dmitry Rodionov 19 мая 2015, 13:20 # 0
                                    Проверил на 200 категориях уровень вложенности 3, разброс на генерацию от 1.7-2.2c с феномом так же, значит разницы нет.
                                    1. Василий Наумкин 19 мая 2015, 13:23 # 0
                                      О чем и речь, да.

                                      А вот если ты захочешь понапихать в чанки разных проверок — то Fenom будет гораздо быстрее.
                                      1. Dmitry Rodionov 19 мая 2015, 13:30 # 0
                                        Интересно было бы ускорить генерацию меню если это возможно, а то на 900 категориях это 10-12 секунд, и при вызове каждой страницы оно кешируется по новой, хотя наверное если ускорять пропадет универсальность…
                                        1. Spam 19 мая 2015, 13:39 # 0
                                          попробуй
                                          &cache=`1`
                                          &cacheTime=`0`
                                          &cache_key=`bestMenu`
                                          чтобы менюшка сейвило под 1 ключом для всех страниц, если конечно от этого ничего не поломается
                                          1. Dmitry Rodionov 19 мая 2015, 13:44 # 0
                                            ну тогда наверное выделение пунктов меню будет неверным или же оно будет кешироваться для одной страницы только
                                            1. Spam 19 мая 2015, 13:44 # 0
                                              ну так попробуй, pdoPage идеально работает, же
                                              1. Dmitry Rodionov 19 мая 2015, 14:04 # 0
                                                так не работает, я и пишу что 10-12 секунд когда вызов не кешируем, в итоге после кеширования конечно все норм, но при 10к+ товаров и ежедневном обновлении цен и наличия и возможно картинок с описанием кеш очищается и все по новой

                                                Я написал свой сниппет для генерации меню и теперь меня все устраивает, просто вопрос был именно в том чтобы ускорить pdoMenu, и не писать свои обработчики
                                                1. Spam 19 мая 2015, 14:20 # 0
                                                  попробуйте вручную удалять папку с кэшем (минишопа), который требуется обновить. Если это возможно
                                                  modx/core/cache/ВАША_ПАПКА_КЭША
                                              2. Василий Наумкин 19 мая 2015, 14:01 # 0
                                                Нет, кэшируются только данные, а не отрендеренные чанки.

                                                Так что попробуй, может сработать.
                                                1. Dmitry Rodionov 19 мая 2015, 14:10 # 0
                                                  у меня такие настройки были:
                                                  &cache=`1`
                                                  &cacheTime=`0`
                                                  &cache_user=`0`
                                                  &cache_key=`left_menu`
                                                  1. Василий Наумкин 19 мая 2015, 14:11 # 0
                                                    Да, я посмотрел исходники. Это хорошо работает для pdoPage, а для pdoMenu — нет.

                                                    В первом случае одна страница, а во втором несколько, вот в этом и разница.
                                                    1. Dmitry Rodionov 19 мая 2015, 14:22 # +2
                                                      В итоге для категорий товара я пришел к простому решению, в 2 этапа:
                                                      1)сниппет с 1 sql запросом и рекурсивной генерацией меню, для большей быстроты генерации на лету вес можно еще хранить
                                                      2)js скрипт который пробегается по дереву и проставляет текущий пункт и родителей

                                                      Скорость генерации сократилась с 10s до 1s при первом вызове и потом до 0.05s при кешировании
                                    2. Алексей Карташов 19 мая 2015, 19:17 # +1
                                      Я сейчас буду блаженно материться…

                                      ДА. ЭТО. ЖЕ. ПРОСТО. О.УЕННО!!!

                                      Чанки в чанках, грёбанные строки в виде всяких там плейсхолдеров теперь идут НАХЕР!
                                      Циклы! Наконец-то, мать их, циклы!!!
                                      Условия! Наконец-то, мать их, человеческие условия!

                                      Наконец-то есть работа с ДАННЫМИ, а не с какими-то грёбанными строками, которые после обработки всех вложенностей и 10й итерации парсера вылезают хрен пойми где и хрен пойми как, ломая напрочь всю разметку.

                                      Циклы, omfg, да это же ЦИКЛЫ!!! Как мало для счастья надо xD xD

                                      Сколько же я на себе волос повыдирал, когда бодался с этим долбанным парсером. Когда логика фронтенда становится чуть сложнее простого вывода данных, то всё — логика у парсера отключается и активируется режим «Угадай, что получится». Я даже хотел писать статью-ненависти-поток-сознания, в которой хотел по косточкам пройтись по косякам парсера. Теперь всё это идёт НАХЕР! xD

                                      Теперь достаточно написать один простенький сниппет (чтобы не извращаться через tplWrapper pdoResource'а), который подключает pdoTools и с помощью него выводит чанк из параметров сниппета (а в чанке уже можно писать что угодно) и всё, мать его, ВСЁ! xD

                                      p.s. Славься В! Славься В! Славься В!
                                      1. Василий Наумкин 19 мая 2015, 20:19 # +1
                                        Теперь достаточно написать один простенький сниппет (чтобы не извращаться через tplWrapper pdoResource'а), который подключает pdoTools и с помощью него выводит чанк из параметров сниппета (а в чанке уже можно писать что угодно) и всё, мать его, ВСЁ! xD

                                        Не спеши, скоро будет обновление с улучшенным pdoParser:

                                        1. Алексей Карташов 19 мая 2015, 20:43 # 0
                                          А чего там спешить-то?))
                                          if (!function_exists('getArray')) {
                                            function getArray ($input, $separator = ',') {
                                              if (is_array($input)) {
                                                return $input;
                                              } else
                                                if (is_string($input)) {
                                                  $trimmedInput = trim($input);
                                                  $firstLetter = substr($trimmedInput, 0, 1);
                                                  $lastLetter = substr($trimmedInput, mb_strlen($trimmedInput,'UTF-8') - 1, 1);
                                                  if (
                                                    ($firstLetter == '{' && $lastLetter == '}') ||
                                                    ($firstLetter == '[' && $lastLetter == ']')
                                                  ) {
                                                    $tmp = json_decode($input, 1);
                                                    if ($tmp) {
                                                      return $tmp;
                                                    }
                                                  } else
                                                    // check for not empty string
                                                    if (trim($input)) {
                                                      $tmp = array_map('trim', explode($separator, $input));
                                                      return $tmp;
                                                    }
                                                }
                                              return ($input && !is_object($input)) ? array($input) : array();
                                            }
                                          }
                                          
                                          $output = '';
                                          $options = (!empty($scriptProperties['options'])) ? getArray($scriptProperties['options']) : array();
                                          $options = array_merge($options, array('useFenom' => 1));
                                          if (!is_object($modx->pdoTools) || !($modx->pdoTools instanceof pdoTools)) {
                                            $fqn = $modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true);
                                            if ($pdoClass = $modx->loadClass($fqn, '', false, true)) {
                                              $pdoTools = new $pdoClass($modx, $options);
                                            }
                                            elseif ($pdoClass = $modx->loadClass($fqn, MODX_CORE_PATH . 'components/pdotools/model/', false, true)) {
                                              $pdoTools = new $pdoClass($modx, $options);
                                            }
                                            else {
                                              $modx->log(modX::LOG_LEVEL_ERROR, 'Could not load pdoFetch from "MODX_CORE_PATH/components/pdotools/model/".');
                                              return $output;
                                            }
                                          } else {
                                            $modx->pdoTools->setConfig($options);
                                            $pdoTools = &$modx->pdoTools;
                                          }
                                          
                                          $tpl = (!empty($scriptProperties['tpl'])) ? $scriptProperties['tpl'] : '';
                                          if ($tpl) {
                                            $data = (!empty($scriptProperties['data'])) ? getArray($scriptProperties['data']) : array();
                                            $output = $pdoTools->getChunk($tpl, $data);
                                          }
                                          return $output;
                                          

                                          Но такая глобальная шаблонизация из коробки — это, конечно, будет просто сказка! Ждём-с :)
                                          1. Василий Наумкин 19 мая 2015, 22:36 # +4
                                            Ну ты и навелосипедил!

                                            Обновляйся на 2.0.0-rc, включай pdoParser при установке, и можно использовать Fenom на страницах сайта и в шаблонах.

                                            Вообще, короче, везде можно.
                                            1. Алексей Карташов 19 мая 2015, 23:14 # 0
                                              Еее, счас бум тестить!

                                              p.s. а в чём там велосипедность-то?) Небольшая функция, подключение pdoTools'а и вывод чанка, в который можно данные передать — куда ж проще-то?)
                                              1. Илья Уткин 20 мая 2015, 11:08 # 0
                                                Обрадовался, побежал пробовать и что-то, видимо, упустил. Добавил строку в админке, а вот как она отображается на фронтенде. Файл в кеше был сгенерирован успешно.
                                                1. Василий Наумкин 20 мая 2015, 11:13 # 0
                                                  pdoParser включен? Лог сайта без ошибок? Кэш почистил?
                                                  1. Илья Уткин 20 мая 2015, 11:18 # 0
                                                    Включен. [[#13.pagetitle]] работает. Кэш чистил. А в логе следующее:

                                                    [2015-05-20 08:16:40] (ERROR @ /index.php) Unexpected tag 'prevText' in web/resources/1/72ff9c7b66dedf43897182eb4a87a8c3.fenom.tpl line 138, near '{prevText:' <- there
                                                    1. Илья Уткин 20 мая 2015, 11:20 # 0
                                                      блин. это объет javascript на странице прописан между
                                                      <script></script>
                                                      Надо скрипт будет в файл, значит, выносить)
                                                      1. Василий Наумкин 20 мая 2015, 11:22 # 0
                                                        Просто используй {ignore}
                                                        1. Илья Уткин 20 мая 2015, 11:24 # 0
                                                          А, ну да.))
                                                    2. Илья Уткин 20 мая 2015, 11:22 # 0
                                                      Короче, разобрался)
                                          2. Виктор 20 мая 2015, 11:51 # 0
                                            А как выводить твшки? и картинки [[+150x120]]?
                                            {$150x120} ломает парсер.
                                            [2015-05-20 11:47:30] (ERROR @ /index.php) Unexpected token '150' in expression, expect '.' in 813a86bbda364c6febcdcf125bfe082d.fenom.tpl line 7, near '{$150' <- there
                                            1. Василий Наумкин 20 мая 2015, 11:53 # 0
                                              Наверное, придётся это пока оставить как [[+150x120]] — старые теги тоже должны работать.

                                              Может, как-то получится это экранировать, но я пока не придумал как именно.
                                              1. Василий Наумкин 20 мая 2015, 21:39 # +2
                                                В новой версии к ним можно обращаться как {$_pls['150x120']}
                                              2. Ryan Murphy 20 мая 2015, 12:20 # +4
                                                Просто хочу выразить благодарность тебе, Василий, за твою работу. Я твой фанат =)
                                                1. Илья Уткин 20 мая 2015, 12:23 # 0
                                                  А что сначала выполняется? Fenom или парсер MODX?

                                                  Это верная конструкция или сначала будет распарсен чанк, а уже после Fenom решит показывать его или нет?
                                                  {if $modx->resource->id != $modx->getOption('site_start')}
                                                      [[$asideLeft]]
                                                  {/if}

                                                  И про эту конструкцию такой же вопрос
                                                  {if $modx->resource->id != $modx->getOption('site_start')}
                                                      {$pdoTools->getChunk('asideLeft')}
                                                  {/if}
                                                  1. Василий Наумкин 20 мая 2015, 12:55 # 0
                                                    Если это в чанке, то сначала отработает Fenom
                                                    Если на странице — то MODX, потому что чанк кэшированный.
                                                    Если чанк на странице некэшированный, то первым сработает Fenom.
                                                    1. Виктор 21 мая 2015, 13:22 # 0
                                                      А fenom так же изнутри работает? Т.е. во втором примере выше, мы получим сначала чанк, а потом проверим выводить ли его? Если да, то возможно ли как то оптимизировать это?

                                                      Хотя судя по тому что нижние примеры не срабатывают (1-ый ломает парсер, второй ничего не выводит), оно работает внутрь.
                                                      {{if true}
                                                      		$pdoTools->getChunk('header')
                                                      	{/if}}
                                                      {$pdoTools->getChunk('{if true}header{/if}')}
                                                      1. Василий Наумкин 21 мая 2015, 13:33 # 0
                                                        Нет, Fenom работает как PHP. Если условие не срабатывает — ничего внутри не запускается.

                                                        Можно смело делать вот так:
                                                        {if $.get.test == 1}
                                                            [[!pdoResources?
                                                                &parents=`0`
                                                            ]]
                                                        {else}
                                                            [[!pdoMenu?
                                                                &parents=`0`
                                                            ]]
                                                        {/if}
                                                        
                                                        И проверять страницу, передавая параметр ?test=1 или ?test=0

                                                        А пример у тебя неверный, не знаю, где ты такое вычитал.
                                                        1. Виктор 21 мая 2015, 13:47 # +1
                                                          Пример это эксперименты с попыткой воссоздать:
                                                          [[$[[*id:is=`1`:then=`chunk1`:else=`chunk2`]]]]
                                                          Хм.
                                                          Без всего:
                                                          Использовано памяти: 4.54 мб., MySQL: 0.0132 s, 88 request(s), PHP: 0.5319 s, total: 0.5451 s, from cache.
                                                          {if $.get.test == 1}
                                                          {else}
                                                          {/if}
                                                          [[!pdoResources?
                                                              &parents=`0`
                                                          ]]
                                                          [[!pdoMenu?
                                                              &parents=`0`
                                                          ]]
                                                          Использовано памяти: 5.69 мб., MySQL: 0.0195 s, 109 request(s), PHP: 0.7325 s, total: 0.7520 s, from cache.
                                                          {if $.get.test == 1}
                                                          [[!pdoResources?
                                                              &parents=`0`
                                                          ]]
                                                          [[!pdoMenu?
                                                              &parents=`0`
                                                          ]]
                                                          {/if}
                                                          Использовано памяти: 5.69 мб., MySQL: 0.0200 s, 109 request(s), PHP: 0.7373 s, total: 0.7573 s, from cache.
                                                          {if $.get.test == 1}
                                                              [[!pdoResources?
                                                                  &parents=`0`
                                                              ]]
                                                          {else}
                                                              [[!pdoMenu?
                                                                  &parents=`0`
                                                              ]]
                                                          {/if}
                                                          Использовано памяти: 5.69 мб., MySQL: 0.0220 s, 109 request(s), PHP: 0.7495 s, total: 0.7715 s, from cache.
                                                          {if $.get.test == 1}
                                                              [[!pdoResources?
                                                                  &parents=`0`
                                                              ]]
                                                          {else}
                                                          {/if}
                                                          Использовано памяти: 5.48 мб., MySQL: 0.0125 s, 92 request(s), PHP: 0.5108 s, total: 0.5233 s, from cache.
                                                          1. Виктор 21 мая 2015, 13:53 # +1
                                                            а вот
                                                            {if $.get.test == 1}
                                                            	{$modx->runSnippet("pdoResources", [
                                                            		'parents' => 0
                                                            	])}
                                                            	{$modx->runSnippet("pdoMenu", [
                                                            		'parents' => 0
                                                            	])}
                                                            {/if}
                                                            Использовано памяти: 4.54 мб., MySQL: 0.0121 s, 88 request(s), PHP: 0.5129 s, total: 0.5250 s, from cache.

                                                            Тут и во всех примерах выше гет запрос пустой.
                                                            1. Василий Наумкин 21 мая 2015, 14:15 # +1
                                                              Нашел в чем дело, в новой версии будет исправлено.

                                                              А пока можно просто переписать на Fenom вот так:
                                                              {$modx->getChunk($modx->resource->id == 1 ? 'chunk1' : 'chunk2')}
                                                              
                                                              1. Виктор 21 мая 2015, 14:43 # +1
                                                                Спасибо, я пока просто играюсь с синтаксисом;)
                                                                Вот еще особенность, при попытке получить пустой чанк:
                                                                Пустой старт: 88 request(s)

                                                                {$pdoTools->getChunk()}
                                                                88 request(s)

                                                                {$modx->getChunk()}
                                                                89 request(s)

                                                                {$modx->getChunk()}
                                                                {$modx->getChunk()}
                                                                90 request(s)

                                                                Но
                                                                {$modx->getChunk('footer')}
                                                                88 request(s)

                                                                {$modx->getChunk('footer')}
                                                                {$modx->getChunk('footer')}
                                                                88 request(s)

                                                                {$pdoTools->getChunk('footer')}
                                                                89 request(s)

                                                                {$pdoTools->getChunk('footer')}
                                                                {$pdoTools->getChunk('footer')}
                                                                89 request(s)

                                                                И просто для вида:
                                                                [[$footer]]
                                                                [[$footer]]
                                                                88 request(s)

                                                                Чанк существует.
                                                            2. Василий Наумкин 21 мая 2015, 13:56 # 0
                                                              Да, похоже парсер MODX где-то успевает подлезть.

                                                              Попробую разобраться.
                                                    2. Андрей 20 мая 2015, 14:13 # -3
                                                      С Fenom кэш MODX станет ещё больше. На каждое изменение ресурса он генерит в кэше по два новых файла, а старые оставляет.
                                                      1. Василий Наумкин 20 мая 2015, 15:11 # +2
                                                        Это не кэш MODX, это кэш Fenom, и он очищается при очистке системного.
                                                        1. Андрей 20 мая 2015, 15:25 # -3
                                                          Я имел ввиду общий кэш системы.
                                                          Он очищается при ПОЛНОЙ очистке системного, а при обычном сохранении ресурса с очисткой кэша он раздувается.
                                                          1. Андрей 20 мая 2015, 15:43 # -3
                                                            Нехило так после нескольких пересохранений раздуло и даже при отключенном кэшировании ресурса.
                                                            1. Василий Наумкин 20 мая 2015, 16:18 # +1
                                                              И что?

                                                              Каждый раз, как ты что-то меняешь — генерируется новый кэш. Как, по твоему, вообще должен работать шаблонизатор, без компиляции что ли?
                                                              1. Андрей 20 мая 2015, 16:45 # -4
                                                                А что в этом хорошего? На 10к+ ресурсах при редактировании в каждом файле будет код целой страницы! Ты считаешь, что это хорошо?
                                                                По-моему он должен работать с очисткой предыдущего кэша данной страницы, зачем плодить ненужный кэш?
                                                                1. Василий Наумкин 20 мая 2015, 16:48 # 0
                                                                  Друг, тебя никто не заставлять этого делать. Работай как раньше, не нужно переживать.

                                                                  Такое происходит только если вызывать новые теги прямо на страницах, а чанки кэшируются по хэшу своего содержимого.

                                                                  То, что сейчас в кэше MODX точно так же хранится код каждой страницы никого, почему-то, не беспокоит.
                                                                  1. Андрей 20 мая 2015, 17:01 # -4
                                                                    В кэше MODX он хранится для каждого ресурса в одном файле, а не в 30+ разных.

                                                                    О да, это просто гениальный ответ, именно такие я всегда жду от тебя. Только не забудь вспомнить, когда будешь переписывать механизм кэширования.
                                                                    1. Василий Наумкин 20 мая 2015, 17:08 # +3
                                                                      Исходный код на GitHub — перепиши сам, как тебе нужно.

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

                                                                      Не жди ничего, поработай самостоятельно.

                                                                      P.S.
                                                                      Сейчас-то хоть дошло, почему я не включаю эксперементальный парсер по умолчанию?
                                                                      1. Андрей 20 мая 2015, 17:16 # -3
                                                                        Я не претендую на важность своего мнения. Всего лишь указал на недостаток.
                                                                        А мне кажется совсем наоборот — ты считаешь своё мнение сверх важным всегда. До этого я высказал своё мнение по поводу rel=canonical — наткнулся на вилы с твоей стороны и предложение сделать самому. Хорошо, я сделал сам. Хотя насчёт rel=next и rel=prev ты кого-то послушал, и сделал.
                                                                        Вот и теперь также.

                                                                        P.S. но эти самые rel=next Яндексом даже не поддерживаются. А насчёт rel=canonical ты почему-то полез в документацию именно Яндекса, когда захотел мне возразить.
                                                                        1. Василий Наумкин 20 мая 2015, 17:22 # +3
                                                                          ты считаешь своё мнение сверх важным всегда
                                                                          Наверное потому, что я понимаю, что делаю.

                                                                          Если бы не понимал, ты бы сейчас давал свои советы кому-то другому.

                                                                          P.S. но эти самые rel=next Яндексом даже не поддерживаются. А насчёт rel=canonical ты почему-то полез в документацию именно Яндекса, когда захотел мне возразить.
                                                                          Со временем, боль утихнет.
                                                                        2. Андрей 20 мая 2015, 17:19 # -7
                                                                          P.S.
                                                                          Сейчас-то хоть дошло, почему я не включаю эксперементальный парсер по умолчанию?
                                                                          Слово «дошло» здесь не уместно, так как ты об это и не говорил. Скорее, одну из причин я понял))

                                                                          Каждый разбирается в своём предмете лучше. Если это твой компонент, то логично же, что именно тебе пишут о его недостатках. Пусть даже в чём-то эти недостатки мнимые. Если ты хорошо знаешь свой «предмет», то просто объясни людям, в чём их заблуждение. Не нужно тыкать пальцем и писать ёрнические фразы.
                                                                          1. Алексей 20 мая 2015, 20:20 # +4
                                                                            дополнение же бесплатное, очень многие разработчики просто ничего не публикуют, только за скачивание такой удивительной фишки как феном в модикс можно уже смело делать знатный донэйт) критика конечно хорошо, но не в такой мере)
                                                                            1. Василий Наумкин 20 мая 2015, 20:52 # +3
                                                                              Нет, всё должно быть идеально с первой же версии. А если, вдруг, что-то непонятно — автор должен сразу прибежать и объяснить.

                                                                              А если плохо объяснил — должен извиниться, и впредь вести себя вежливо и предупредительно.

                                                                              Пользователь, понятное дело, ничего такого не должен. Это же автору нужно бегать за пользователем, а никак не наоборот.
                                                                              1. Андрей 20 мая 2015, 21:27 # -3
                                                                                Кто сказал, что с первой версии? Правильно тебе уже писал Андрей Чирко, что ты свои фантазии за действительное выдаёшь.
                                                                                Ты же хочешь, чтобы твой компонент был лучше всех? Хочешь. Ты же хочешь, чтобы искали баги — хочешь? Так в чём проблема? В чье-то критике?
                                                                                P.S.
                                                                                А между тем выходит версия 2.0.0-rc2 Но ты же всегда прав…
                                                                                P.S.S. в логе изменений ошибочка, кстати:
                                                                                Complied
                                                                                1. Василий Наумкин 20 мая 2015, 21:32 # +2
                                                                                  А между тем выходит версия 2.0.0-rc2 Но ты же всегда прав…
                                                                                  Конечно выходит, а потом выйдет и pl, и 2.0.1 — независимо от твоей «критики».

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

                                                                                  Или ты думаешь, что я весь день плевал в потолок и только после твоих невероятно ценных замечаний, за 5 часов всё переписал, протестировал и выложил?

                                                                                  Ты себе льстишь, серьёзно.
                                                                                  1. Андрей 20 мая 2015, 21:46 # -3
                                                                                    Конечно, точно так же как и ты себе…
                                                                                    1. Андрей Сухомозгий 20 мая 2015, 21:56 # -1
                                                                                      да заткнись ты уже!
                                                                                      1. jale 20 мая 2015, 22:04 # -2
                                                                                        Вот на это ты только и способен — заблочил аккаунт. Вообще то позиционируется как «Крупнейшее русскоязычное MODX сообщество».
                                                                                        1. Василий Наумкин 20 мая 2015, 22:05 # 0
                                                                                          Ну а что еще делать с занудными дурачками? Где-то раз в неделю обязательно такие находятся.

                                                                                          Удачи тебе в поисках Правды на других ресурсах.
                                                                                          1. Комментарий был удален.
                                                                                            1. Комментарий был удален.
                                                                                              1. Комментарий был удален.
                                                                              2. Владимир 20 мая 2015, 22:38 # +1
                                                                                Василий! Спасибо тебе за твои идеи, дополнения и новые фишки!
                                                                                После чтения «критики», в данной ветке особенно, хочется тебя поблагодарить и поддержать.
                                                                                1. Василий Наумкин 20 мая 2015, 22:43 # +1
                                                                                  На здоровье!

                                                                                  К яростным мстителям я давно привык — не первый год рулю сообществом.
                                                                                  1. Комментарий был удален.
                                                                                  2. Николай Загумённов 23 мая 2015, 23:36 # 0
                                                                                    Не разбираюсь в шаблонизаторах, но по замерам очень круто! Спасибо, Василий!

                                                                                    Подскажите, кто-нибудь как вывести TV'шку с помощью синтаксиса шаблонизатора ?)
                                                                                    1. Василий Наумкин 24 мая 2015, 03:35 # +1
                                                                                      Вывести, если оно уже получено сниппетом, примерно так же как и раньше:
                                                                                      {$tvname}

                                                                                      А получить прямо из шаблона или чанка можно так
                                                                                      {$modx->getObject('modResource', 15)->getTVValue('tvname')}

                                                                                      Если ресурса с id 15 нет, то будет ошибка. Поэтому, безопаснее вот так:
                                                                                      {set $resource = $modx->getObject('modResource', 15)}
                                                                                      {if $resource}
                                                                                      	{$resource->getTVValue('tvname')}
                                                                                      {/if}
                                                                                      1. Николай Загумённов 26 мая 2015, 17:21 # 0
                                                                                        [[!pdoResources?
                                                                                             &parents=`378`
                                                                                             &depth=`0`
                                                                                             &tpl=`@INLINE <li><img src="{$modx->runSnippet("phpthumbon", [ 'input' => $modx->getObject('modResource', $id)->getTVValue('image'), 'options' => '&w=340&h=540&zc=1' ])}" /></li>`
                                                                                              &limit=`6`
                                                                                              &includeTVs=`image`
                                                                                              &sortby=`{"publishedon":"DESC"}`
                                                                                        ]]
                                                                                        
                                                                                        Вот так вывел, через {$tvname} не получилось.
                                                                                        1. Evgeny Epifanov 10 июня 2015, 20:22 # 0
                                                                                          Василий, а не знаешь ли ты, как можно получить категорию, в которой находится TV?
                                                                                          1. Евгений 14 октября 2015, 10:26 # 0
                                                                                            Василий, что все таки надо сделать чтобы можно было писать TV внутри чанков в виде {$name}?
                                                                                            если оно уже получено сниппетом
                                                                                            Как это сделать? Например, в pdoResources делаю и &includeTVs со списком tv и подготавливаю и обрабатываю их через &prepareTVs=`1` и &processTVs=`1` и все равно внутри чанка можно получить значение этих переменных только в виде:
                                                                                            {$modx->getObject('modResource', $id)->getTVValue('name')}
                                                                                            а для этого надо включать pdotools_fenom_modx, что не очень хорошо для безопасности. Тот же самый вызов только с $_modx не работает. Из этого следует, что внутри чанков по сути получается использовать в формате {$name} только стандартные поля ресурсов, а для получения значений TV надо писать каждый раз огромный код, что конечно «убивает» все удобство написания кода. Так что же я делаю не так? Или просто я что-то не так понял, такой возможности нет и мне пора бы уже сделать себе хоткей в редакторе для TV? :)
                                                                                            1. EarlCherry 02 декабря 2015, 23:41 # 0
                                                                                              Нашлось решение проблемы? Тоже самое у меня сейчас.
                                                                                              1. Воеводский Михаил 02 декабря 2015, 23:45 # 0
                                                                                                {$_modx->resource.tvname}
                                                                                                1. Евгений 03 декабря 2015, 18:30 # 0
                                                                                                  Ваш вариант подходит только для получения значений в шаблонах, но не в чанках, про которые и шла речь.
                                                                                                  1. Воеводский Михаил 03 декабря 2015, 18:39 # 0
                                                                                                    {$_pls['tvname']}
                                                                                                  1. Евгений 03 декабря 2015, 18:42 # 0
                                                                                                    У меня на последней версии modx revo 2.4.2 и pdoTools 2.1.17 ничего не изменилось, также продолжает не работать в чанках $_modx, ошибок в журнале никаких нет, ну и на выходе имеем просто пустую страницу.
                                                                                                    1. Василий Наумкин 03 декабря 2015, 18:45 # 0
                                                                                                      Да как обычно, всё работает только у меня и больше нигде.

                                                                                                      Между {$modx} и {$_modx} есть очень серьёзная разница, и если ты пытаешься использовать вторую переменную как первую, то и будет fatal error.
                                                                                                      1. Евгений 03 декабря 2015, 18:52 # 0
                                                                                                        Я ее пытался использовать вот так:
                                                                                                        {$_modx->getObject('modResource', $id)->getTVValue('name')}
                                                                                                        
                                                                                                        При этом имя TV без тире, точек и т.д.
                                                                                                        В чем именно тут ошибка использования? для $_modx нет getObject?
                                                                                                        1. Василий Наумкин 03 декабря 2015, 18:55 # 0
                                                                                                          В чем именно тут ошибка использования? для $_modx нет getObject?
                                                                                                          Именно.

                                                                                                          Может, прочитаешь уже документацию, а?
                                                                                                          1. Евгений 03 декабря 2015, 19:11 # 0
                                                                                                            В том то ж и дело что я ее читал, видимо пропустил что не все методы $modx доступны для $_modx. Но все равно кроме как:
                                                                                                            {$modx->getObject('modResource', $id)->getTVValue('tvName')}
                                                                                                            
                                                                                                            или стандартно
                                                                                                            
                                                                                                            [[+tvName]]
                                                                                                            
                                                                                                            в чанках не выходит получить значение tv. Имена tv не имеют тире, точек, подчеркиваний, поэтому, как я понял, использовать $_pls (куда ведет ваша ссылка) не имеет смысла. Так есть ли возможность как-то по-другому получать значение tv в чанках? Я в документации такого не нашел…
                                                                                                            1. Воеводский Михаил 03 декабря 2015, 19:14 # 0
                                                                                                              А попробовать получить значение TV так, как написано в документации? Не додумывать, а просто попробовать.
                                                                                                              1. Евгений 03 декабря 2015, 19:21 # 0
                                                                                                                я пробовал такими способами:

                                                                                                                {$_modx->resource.tvName}
                                                                                                                {$_pls['tvName']}
                                                                                                                {$_modx->getObject('modResource', $id)->getTVValue('name')}
                                                                                                                
                                                                                                                Ну с последним вариантом я уже понял в чем дело…
                                                                                                                Первый вариант как я и говорил он предназначен для вывода значения тв для текущего ресурса. ([[*tvName]] а нужен аналог [[+tvName]])
                                                                                                                Ну а с $_pls просто ничего не выдается.

                                                                                                                >>>Не додумывать, а просто попробовать.
                                                                                                                Я обычно так и делаю, чтобы не быть голословным я сначала пробую, а потом пытаюсь додумать, что не так…
                                                                                                                1. Василий Наумкин 03 декабря 2015, 19:24 # 0
                                                                                                                  Ну создай тестовый сайт и покажи нам эту проблему воочию — разберёмся.
                                                                                                                  1. Воеводский Михаил 03 декабря 2015, 19:26 # 0
                                                                                                                    Напиши вызов сниппета, в котором обрабатывается чанк.
                                                                                                                    1. Евгений 03 декабря 2015, 20:03 # 0
                                                                                                                      s3651.h2.modhost.pro/manager/
                                                                                                                      login: s3651
                                                                                                                      pass: 3kEaiHzCM9IY
                                                                                                                      1. Василий Наумкин 03 декабря 2015, 20:10 # 0
                                                                                                                        Смешно.
                                                                                                                        &tvPrefix=``
                                                                                                                        1. Евгений 03 декабря 2015, 20:15 # 0
                                                                                                                          Это вообще очень смешно, особенно если об этом нигде в документации не указано, что для того чтобы tv нормально можно было по имени вызывать в виде
                                                                                                                          {$tvName}
                                                                                                                          
                                                                                                                          надо при вызове сниппета, напр. pdoResource, использовать параметр
                                                                                                                          &tvPrefix=``
                                                                                                                          
                                                                                                                          Ну хотя бы сейчас из этого сообщения люди смогут об этом узнать.
                                                                                                                          1. Василий Наумкин 03 декабря 2015, 20:20 # 0
                                                                                                                            Ну естественно, это мега-тайна, что все ТВ выбираются с префиксом tv. по умолчанию. В документации прям нет этого параметра. includeTVs, prepareTVs, processTVs и дальше пустота.

                                                                                                                            Можно и не делать пустой &tvPrefix, но тогда, не поверишь, нужно выводить ТВ вот так:
                                                                                                                            [[+tv.name]] - MODX
                                                                                                                            {$_pls['tv.name']} - Fenom
                                                                                                                            Про вывод через точку я тебе давал ссылку еще 2 часа назад.

                                                                                                                            А вообще, можно увидеть все плейсхолдеры, если просто не указывать чанк.
                                                                                                                            1. Евгений 03 декабря 2015, 20:48 # 0
                                                                                                                              Если бы вышеприведенные две строчки были в документации, то этого всего разговора не было бы. Во всяком случае, спасибо, теперь хоть смогу нормально пользоваться tv в чанках! :)
                                                                                                                              1. Василий Наумкин 04 декабря 2015, 05:25 # +1
                                                                                                                                Документация у нас открытая, можно редактировать через GitHub.

                                                                                                                                Допиши, что считаешь нужным, и пришли pull-request. Тогда эта информация добавится на сайте.

                                                                                                                                Все сетуют на плохую документацию, но никто, почему-то, не хочет её улучшать.
                                                                                                              2. Марат Марабар 08 июня 2015, 17:31 # 0
                                                                                                                Никак лексиконы победить не могу.
                                                                                                                Через пространство имён создано новое имя sitetranslations, /core/components/sitetranslations/lexicon/ содержит два языка — русский и английский. Раньше выводил так:
                                                                                                                [[%lexicon_name? &namespace=`sitetranslations`]]
                                                                                                                
                                                                                                                Решил попробовать шаблонизатор, пробую варианты:
                                                                                                                {$modx->lexicon('lexicon_name', ['namespace' => 'sitetranslations'])}
                                                                                                                {$modx->lexicon('lexicon_name',  'sitetranslations')}
                                                                                                                {$modx->lexicon('lexicon_name')}
                                                                                                                
                                                                                                                Выводит — lexicon_name. Но ежели в шаблоне оставить хоть один вывод MODX
                                                                                                                [[%lexicon_name? &namespace=`sitetranslations`]]
                                                                                                                
                                                                                                                То Fenome начинает работать и без указания пакета, выводится так:
                                                                                                                {$modx->lexicon('lexicon_name_to')}
                                                                                                                
                                                                                                                1. Василий Наумкин 08 июня 2015, 17:33 # +1
                                                                                                                  Лексикон нужно загрузить, для этого есть отдельный метод.

                                                                                                                  Попробуй так:
                                                                                                                  {$modx->lexicon->load('sitetranslations')}
                                                                                                                  {$modx->lexicon('lexicon_name')}
                                                                                                                  
                                                                                                                  1. Марат Марабар 08 июня 2015, 18:02 # 0
                                                                                                                    Нет, не хочет.
                                                                                                                    И в документации про load() ничего не вижу. Да я понимаю, что надо загрузить лексикон, только не грузится он у меня без вмешательства MODX.
                                                                                                                    1. Василий Наумкин 08 июня 2015, 18:08 # +1
                                                                                                                      У меня работает:
                                                                                                                      {$modx->lexicon->load('tickets:setting')}
                                                                                                                      {$modx->lexicon('area_tickets.mail')}
                                                                                                                      выводит «Почтовые уведомления». Без первой строчки выводит «area_tickets.mail».

                                                                                                                      Видимо, тебе тоже нужно указать раздел через двоеточие. По идее:
                                                                                                                      {$modx->lexicon->load('sitetranslations:default')}

                                                                                                                      Кстати говоря, документацию лучше смотреть вот так.
                                                                                                                      1. Марат Марабар 08 июня 2015, 18:13 # 0
                                                                                                                        О. Заработало. Отличную вещь ты, Василий, сделал — пошёл дальше осваивать. Спасибо!!!

                                                                                                                        зы. Отлично.
                                                                                                                        1. Василий Наумкин 08 июня 2015, 19:31 # +2
                                                                                                                          Не сделал, а прикрутил.

                                                                                                                          Но да, мне тоже очень нравится =)
                                                                                                                          1. Марат Марабар 08 июня 2015, 20:08 # +2
                                                                                                                            Ну конечно же, не так выразился — Отличную вещь ты, Василий, сделал, что прикрутил Fenom!
                                                                                                                2. Максим Степанов 24 июня 2015, 08:44 # 0
                                                                                                                  Василий скажите почему может не работать такой вывод?
                                                                                                                  $tpl1 = '@INLINE <p><a href="[[~[[+id]]">[[+pagetitle]]</a></p>'
                                                                                                                  
                                                                                                                  Не работает именно [[~[[+id]]. Ссылка выходит такая Товар 1. Такая проблема появилась после обновления pdoTools Fenom. Если задать поместить [[+pagetitle]] в чанк то все работает.

                                                                                                                  И ошибка в отчете:
                                                                                                                  `[[+id]]` is not a valid integer and may not be passed to makeUrl()
                                                                                                                    1. Максим Степанов 24 июня 2015, 09:07 # 0
                                                                                                                      Выходит что такая конструкция [[~[[+id]]]] не будет работать? Но ее можно заменить эти {$modx->makeUrl($id)}?
                                                                                                                      1. Илья Уткин 24 июня 2015, 09:24 # 0
                                                                                                                        Можно заменить на [[+uri]], если включены дружественные URL
                                                                                                                        1. Максим Степанов 24 июня 2015, 09:27 # 0
                                                                                                                          Спасибо за помощь, невнимательно прочитал.
                                                                                                                      2. Максим Степанов 24 июня 2015, 09:09 # 0
                                                                                                                        Все понял, прошу прощения
                                                                                                                    2. Григорий Коленько 25 июня 2015, 14:30 # 0
                                                                                                                      переменные переданные в чанк не отрабатывает или я что-то не так делаю?
                                                                                                                      [[$input?
                                                                                                                                     $input_error=`test`
                                                                                                                                  ]]
                                                                                                                      [[+input_error]]
                                                                                                                      1. Василий Наумкин 25 июня 2015, 14:38 # 0
                                                                                                                        У меня такое ощущение, что вы прям соревнуетесь иногда, кто глупее вопрос задаст.

                                                                                                                        Трудно внимательно посмотреть на код и подумать, а вдруг там опечатка? Может, заместо $input_error нужно указать &input_error?
                                                                                                                        1. Григорий Коленько 25 июня 2015, 14:42 # 0
                                                                                                                          Это я сейчас, когда писал комментарий опечатался. На сайте все как надо
                                                                                                                          вызов чанка:
                                                                                                                          [[$input?
                                                                                                                          &input_error=`test`
                                                                                                                          ]]
                                                                                                                          чанк:
                                                                                                                          {$input_error}
                                                                                                                          1. Василий Наумкин 25 июня 2015, 15:06 # 0
                                                                                                                            Fenom срабатывает раньше, так что можно делать вот так:
                                                                                                                            {set $input_error = 'test'}
                                                                                                                            [[$input]]
                                                                                                                            
                                                                                                                            Но это попахивает уже каким-то извращением, на мой взгляд.
                                                                                                                            1. Григорий Коленько 25 июня 2015, 15:11 # 0
                                                                                                                              Да. Действительно, извращение :) Хотелось все привести к единообразию, а то несколько разных синтаксисов режет глаза. Спасибо.

                                                                                                                              Тут словил вот такую вещь. Сайт падает, когда пользователь не суперадмин. В логах сервера это:
                                                                                                                              [25-Jun-2015 14:07:45 Europe/Prague] PHP Fatal error:  Call to a member function toArray() on null in /core/components/pdotools/model/pdotools/pdotools.class.php on line 493
                                                                                                                              
                                                                                                                              т.е. на этой строке:
                                                                                                                              $item = array_merge($this->modx->user->Profile->toArray(), $item);
                                                                                                                              
                                                                                                                              Версия pdoTools 2.0.3-pl, modx 2.3.4.
                                                                                                                              1. Василий Наумкин 25 июня 2015, 15:40 # 0
                                                                                                                                А блин, это вообще по ошибке попало в релиз. Щас выложу обновление.

                                                                                                                                Всё, обновляйся.
                                                                                                                                1. Григорий Коленько 25 июня 2015, 15:47 # 0
                                                                                                                                  Gracias!
                                                                                                                      2. Виктор Долгий 03 августа 2015, 18:13 # 0
                                                                                                                        Кто-нибудь подскажет, как вывести Феномом (экранировать) такие вот плэйсхолдеры:
                                                                                                                        [[!+fi.error.email]]
                                                                                                                        ?
                                                                                                                        1. Александр Котлов 14 декабря 2015, 18:57 # 0
                                                                                                                          Присоединюсь к вопросу. Не получается в письме для AjaxForm получить плейсхолдеры.
                                                                                                                        2. Evgeny Epifanov 07 августа 2015, 12:01 # 0
                                                                                                                          Подскажите, а как можно получить превьюшку произвольного ресурса с помощью Fenom?
                                                                                                                          1. Григорий Коленько 12 сентября 2015, 16:25 # 0
                                                                                                                            Ребят, а кто-то разобрался как тег {use} работает? Я что-то потыкался, не нашел нормального описания.
                                                                                                                            Вызываем чанк:
                                                                                                                            {use 'header'}
                                                                                                                            А что дальше делать? Или как это работает?
                                                                                                                            1. Максим 30 сентября 2016, 20:42 # 0
                                                                                                                              видимо совместно с тегом {paste 'header'}, который не работает в pdoTools
                                                                                                                            2. Сергей 27 сентября 2015, 11:39 # 0
                                                                                                                              Подскажите пожалуйста. Если, например, меняю в чанках pdoResources
                                                                                                                              [[+pagetitle]]
                                                                                                                              на
                                                                                                                              {$pagetitle}
                                                                                                                              , то они не отрабатываются в кэшированном сниппете, в некэшированном отрабатываются, но так увеличивается время генерации страницы. Каким образом мне получить, например,
                                                                                                                              {$pagetitle}
                                                                                                                              в кэшированном сниппете?
                                                                                                                              И еще один вопрос. Каким образом можно заменить, например, такую конструкцию
                                                                                                                              [[+content:ellipsis=`200`]]
                                                                                                                              в рамках Fenom?
                                                                                                                              1. Руслан Кундиус 27 сентября 2015, 23:32 # +1
                                                                                                                                И еще один вопрос. Каким образом можно заменить, например, такую конструкцию
                                                                                                                                [[+content:ellipsis=`200`]] в рамках Fenom?
                                                                                                                                {$content|truncate:200}
                                                                                                                                github.com/fenom-template/fenom/blob/master/docs/ru/mods/truncate.md
                                                                                                                                1. Сергей 27 сентября 2015, 23:34 # 0
                                                                                                                                  Руслан, спасибо! Полезная ссылка)
                                                                                                                              2. Алексей 26 октября 2015, 20:54 # 0
                                                                                                                                как выводить плэйсхолдер результатов для mFilter2?
                                                                                                                                dвот так работает
                                                                                                                                [[!+my.results]]
                                                                                                                                а вот так уже нет
                                                                                                                                {$_pls['my.results']}
                                                                                                                                1. Николай 15 января 2016, 08:34 # 0
                                                                                                                                  Возникла такая проблемка. Если на странице используются фигурные скобки, то парсер не работает уже…

                                                                                                                                  Скажем, вызываю на странице pdoResources, в котором есть параметр:

                                                                                                                                  &where=`{"template":5}`
                                                                                                                                  и парсер перестаёт работать… Что делать, кто знает? Можно ли как-нибудь экранировать скобки?
                                                                                                                                    1. Владимир 15 января 2016, 08:37 # +1
                                                                                                                                      добавлять пробел (если это не феном)
                                                                                                                                      1. Василий Столейков 15 января 2016, 09:27 # +1
                                                                                                                                        &where=`{ "template":5 }`
                                                                                                                                        1. Николай 15 января 2016, 15:36 # 0
                                                                                                                                          Спасибо за ответы! Теперь всё работает)
                                                                                                                                        2. Максим Степанов 11 февраля 2016, 13:19 # 0
                                                                                                                                          Подскажите как выводить Теги fastField с помощью fenom?
                                                                                                                                          с примеру [[#GET.key3]]?
                                                                                                                                          1. Сергей Шлоков 11 февраля 2016, 14:02 # +1
                                                                                                                                            {$.get.key3}
                                                                                                                                            1. Максим Степанов 11 февраля 2016, 14:07 # 0
                                                                                                                                              Супер! Спасибо!
                                                                                                                                              1. Сергей Шлоков 11 февраля 2016, 14:25 # +1
                                                                                                                                                Вот секретная документация. При попытке её достать пропали без вести несколько программистов. Герой, который её достал, провез её через таможню в том же месте, в котором отец Брюса Виллиса в «Криминальном чтиве» хранил 50 лет часы. :)
                                                                                                                                                1. Максим Степанов 11 февраля 2016, 14:31 # 0
                                                                                                                                                  Спасибо за документацию, а история просто душераздирающая)
                                                                                                                                          2. Антон Соловьёв 14 апреля 2016, 15:10 # 0
                                                                                                                                            подскажите пожалуйста, что-то не соображу, как в феном закомментировать строку. Что-то типа {-- или {/* и выражение в скобках бы не действовало?
                                                                                                                                            1. Воеводский Михаил 14 апреля 2016, 15:42 # +2
                                                                                                                                              {* comment *}
                                                                                                                                              1. Антон Соловьёв 14 апреля 2016, 16:06 # 0
                                                                                                                                                спасибо. Чет не нашел в документации, просмотрел наверное.
                                                                                                                                            2. Антон Соловьёв 15 апреля 2016, 15:10 # 0
                                                                                                                                              Почему-то с if и просто для вывода доступ к массиву гет ($.get.) работает, а вот такие вот вещи — нет
                                                                                                                                              {var_dump($.get.city)}
                                                                                                                                              {empty($.get.city)}
                                                                                                                                              Хотел обернуть тернарным оператором !empty($.get.city)? «бла-бла»: «ой!» — и не вышло, облом.
                                                                                                                                              А я б еще и такие вещи вотворил htmlspecialchars(strip_tags(stripslashes(trim($.get.city)))). А то я на смарти-шаблонизаторе часто вызывал процессоры прям на странице и почистить переменную перед вводом тут бы было очень кстати.
                                                                                                                                              Вы должны авторизоваться, чтобы оставлять комментарии.