Цитирование чанков и сниппетов в Modx

Добрый день, столкнулся с такой проблемой — не цитируются чанки, сниппет итд в pre\code, они отрабатываются CMS, т.е вместо например
[[++site_name]]
В материале отображается отработанный параметр, подскажите как экранировать подобные вызовы?
Arahort
12 января 2019, 17:05
89
0

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

Андрей
12 января 2019, 17:24
+1
FixedPre — должно помочь.
    Arahort
    12 января 2019, 19:01
    0
    Спасибо, попробовал, увы работает он очень криво, у него свой тег который вставлять геморно вручную каждый раз и он ломает табуляцию итд
    Я использую CKEditor + codesnippet. Т.е в админке я вставляю код через codesnippet например
    <form class="sisea-search-form" action="[[~[[+landing:default=`[[*id]]`]]]]" method="[[+method:default=`get`]]">
      <fieldset>
        <label for="[[+searchIndex]]"></label>
        <input type="text" name="[[+searchIndex]]" id="[[+searchIndex]]" value="[[+searchValue]]" autocomplete="off" />
        <input type="hidden" name="id" value="[[+landing:default=[[*id]]]]" /> 
        <input type="submit" value="Поиск" />
      </fieldset>
    </form>
    <div id="site-search-results" class="site-search-results"></div>
    Выглядит следующим образом:
    Вставка joxi.ru/1A5BZnlHnqJoWr
    Админка joxi.ru/eAO9eK3cx1Dyzm
    joxi.ru/KAgaYzlt4z7Rzm
    Сайт (подсветка синтаксиса через JS) joxi.ru/nAyGYwPSYxbOEm
    Приходится вручную в коде убирать [[ ]] что бы он не интерпритировался
      Андрей
      12 января 2019, 21:41
      +1
      Ну ещё вариант поставить Jevix, и выводить контент так:
      [[*content:Jevix]]
      Только подсветку подключить останется.
        Arahort
        12 января 2019, 22:13
        0
        Это вроде можно делать и просто
        [[*content:tag]]
        Но каждому тегу всегда дописывать :tag долго, хочется автоматизировать
Александр Мельник
12 января 2019, 21:23
0
А поделитесь, что вообще такое «цитирование сниппетов» в контексте фреймворка MODX? Впервые просто слышу такой термин.
Arahort
12 января 2019, 21:27
0
UPD Возможно достаточно просто сделать автозамену в CKEditor [ и ] на спецсимволы, пока что ищу как…
Arahort
13 января 2019, 00:31
0
UPD 2
В manager\assets\components\ckeditor\ckeditor\config.js
Подключил autocorrect
config.extraPlugins = 'codesnippet,autocorrect';
Добавляю в
CKEDITOR.config.autocorrect_replacementTable = {
        "--\>": "→",
        "-+": "∓",
        "->": "→",
        "...": "…",
        "©": "©",
        "(e)": "€",
        "®": "®",
        "(tm)": "™",
        "(o)": "˚",
        "+-": "±",
        "<-": "←",
        "<--": "←",
        "<--\>": "↔",
        "<->": "↔",
        "<<": "«",
        ">>": "»",
        "~=": "≈",
        "1/2": "½",
        "1/4": "¼",
        "3/4": "¾"
    };
Через config.js
CKEDITOR.config.autocorrect_replacementTable["["] = "&#91;";
CKEDITOR.config.autocorrect_replacementTable["]"] = "&#93;";
Но увы не работает, что я делаю не так?)
При этом например автозамена ( c ) => © работает нормально
Arahort
13 января 2019, 16:28
0
Так и не удалось заставить заменять символы в CKEditor нашёл статью Михаила , к сожалению плагин отказался работать, пробовал вешать его на событие OnLoadWebDocument вместо OnWebPagePrerender, но тогда возвращается пустой контент.
Упростил и чуть-чуть изменил скрипт что бы попытаться найти причину проблемы, может у кого то есть идеи?
<?
$templates = [2];
if (!in_array($modx->resource->get('template'), $templates)) {
    return;
}

if (!function_exists('getTextBetweenCodeTags')) {
	function getTextBetweenCodeTags($text)
	{
    	$pattern = "/<pre><code(.*?)>(.*?)<\/code><\/pre>/s";
    	preg_match_all($pattern, $text, $matches);
    	return $matches;
	}
}

$html = &$modx->resource->_output;
$codes = getTextBetweenCodeTags($html);
$codes = (isset($codes[1])) ? $codes[1] : array();

foreach ($codes as &$code)
{
	$codeNew = $code;
	$codeNew = htmlentities($codeNew);
	$codeNew = str_replace("&amp;#91;", '[', $codeNew);
	$codeNew = str_replace("&amp;#93;", ']', $codeNew);
	$html = str_replace($code, $codeNew, $html);
}
$modx->resource->set('content', $html);
Arahort
13 января 2019, 17:51
0
В PHP не силён, но поставил Consloe и набросал свой код, операясь на пример Михаила, вот что получилось
<?php
function CodeScreening($res){
	$pattern = "/<pre><code(.*?)>(.*?)<\/code><\/pre>/s";
	preg_match_all($pattern, $res, $matches);
	return $matches;
}

$id = $modx->resource->get('id');
$res = $modx->getObject('modResource',$id);
$res = $res->get('content');
$codes = CodeScreening($res);
$codes = (isset($codes[2])) ? $codes[2] : array();

foreach ($codes as &$code)
{
	$codeNew = $code;
	$codeNew = htmlentities($codeNew);
	$codeNew = str_replace("[", '&#91;', $codeNew);
	$codeNew = str_replace("]", '&#93;', $codeNew);
	$res = str_replace($code, $codeNew, $res);
}
$newRes = $modx->getObject('modResource',$id);
$newRes = $newRes->set('content', $res);
Вопрос 1 — Как правильно вернуть получившуюся замену в данном случае обратно в content?
Вопрос 2 — как правильно сделать форич в функции CodeScreening что бы возвращался в массив не только первый тег?
Arahort
15 января 2019, 07:29
0
Опять я)) Вернулся к этой проблеме, переписал ещё раз скрипт (уверен что в глазах тех, кто нормально знает php он выглядит ужасно, но сильно не пинайте =) ) в консоли от отрабатывает нормально, но на странице после применения плагина результатов нету, в консоли я вместо
$id = $modx->resource->get('id');
Подставляю сразу числовое значение, а эту строку комментирую, в чем проблема? У меня предположение что либо я неправильно получаю id ресурса или же как то неправильно сохраняю.
Скрипт
<?php
/*Функция поиска кода по регулярному выражению*/
function CodeScreening($res){
	$pattern = "/<pre(.*?)>(.*?)<code(.*?)>(.*?)<\/code>(.*?)<\/pre>/s";
	preg_match_all($pattern, $res, $matches);
	foreach ($matches as $keyCodes){
	    return $keyCodes;
    }
}
/*Получаем id страницы*/
$id = $modx->resource->get('id');
/*Получаем страницу по её id*/
$res = $modx->getObject('modResource',$id);
/*Получаем контент страницы*/
$res = $res->get('content');
/*Ищем код в контенте страницы*/
$codes = CodeScreening($res);
$codes = (isset($codes)) ? $codes : array();
/*Функция замены символов*/
function CodeScreeningResult($codes){
    $codeScrArr = [];
    foreach ($codes as &$code){
        $codeScr = $code;
        $codeScr = htmlentities($codeScr);
        $codeScr = str_replace("[", '&#91;', $codeScr);
        $codeScr = str_replace("]", '&#93;', $codeScr);
        $codeScrArr[] = $codeScr;
    }
    return $codeScrArr;
}
/*Получаем результат замены символов*/
$codeScrResult = CodeScreeningResult($codes);
/*Меняем в тексте старый код на новый*/
$resResult = str_replace($codes, $codeScrResult, $res);
/*Отсылаем изменённый текст обратно в контент*/
$resSend = $modx->getObject('modResource',$id);
$resSend->set('content', $resResult);
$resSend->save();
Событие OnWebPagePrerender
    Василий Наумкин
    15 января 2019, 07:39
    +1
    Похоже, ты пытаешься изобрести Jevix.

    Лучше используй сразу его, он умеет и теги MODX экранировать, и опасные HTML и теги вырезать, и всякие автозамены делать. Он прямо сейчас здесь весь контент фильтрует.
      Arahort
      15 января 2019, 09:44
      0
      Спасибо, развернул jevix на локальной копии для теста. Изначально просто хотелось фильтровать контент только внутри тегов pre\code, т.к иногда бывает полезно использовать теги Modx внутри текста (те же ссылки через id например) + когда переносил старый сайт на Modx и читал различные материалы — люди иногда сталкивались с проблемами из-за Jevix, да и как правило стараюсь не использовать большие плагины\библиотеки для решения маленьких простых задач в целях оптимизации)
      Заметил уже пару недочётов в своем скрипте, поробую допилить возможно в будущем.
      Сейчас как временное решение поставил
      [[*content:replace=`[==&#91;`:replace=`]==&#93;`]]
      К сожалению :tag и :esc отказываются работать на сниппетах