Как лучше оформить замены в тексте?
Приветствую.
Размышляю над тем, как сделать замены в тексте — слово заменить на ссылку. Надеюсь вы подскажете алгоритм. Есть несколько разных шаблонов и текст, в котором надо делать замены, размещен в разных блоках (в стандартных полях типа description и content, а также в дополнительных полях). Количество полей разное, зависит от шаблона — от двух до пяти. Мне понятно, вероятно я так думаю, что нужно взять все эти поля о объединить их в одно (добавить какой-нибудь разделитель), затем пройтись алгоритмом замены по объединенному тексту, а после разделить текст по разделителю и вернуть модифицированный текст в каждое поле.
Подскажите пожалуйста как конкретно это лучше всего реализовать?
Размышляю над тем, как сделать замены в тексте — слово заменить на ссылку. Надеюсь вы подскажете алгоритм. Есть несколько разных шаблонов и текст, в котором надо делать замены, размещен в разных блоках (в стандартных полях типа description и content, а также в дополнительных полях). Количество полей разное, зависит от шаблона — от двух до пяти. Мне понятно, вероятно я так думаю, что нужно взять все эти поля о объединить их в одно (добавить какой-нибудь разделитель), затем пройтись алгоритмом замены по объединенному тексту, а после разделить текст по разделителю и вернуть модифицированный текст в каждое поле.
Подскажите пожалуйста как конкретно это лучше всего реализовать?
Комментарии: 16
Сделайте сниппет с логикой замены и используйте его в качестве модификатора.
Например, сниппет link:
В шаблоне выводите:
Например, сниппет link:
<?php
// что меняем
$arr1 = array(
'_ссылка1_',
'_ссылка2_',
'_ссылка3_'
);
// на что меняем
$arr2 = array(
'<a href="[[~1]]">ссылка1</a>',
'<a href="[[~2]]">ссылка2</a>',
'<a href="[[~3]]">ссылка3</a>'
);
return str_replace($arr1, $arr1, $input);
В шаблоне выводите:
[[*content:link]]
[[*description:link]]
Над этим вариантом размышлял. Если надо будет сделать только по одной замене слова на странице, то с прикреплением одного и того же модификатора к нескольким полям замены будут проведены минимум два раза на одной страницы при условии, что искомые для замены слова будут встречаться сразу в двух полях. Поэтому этот вариант не подходит.
Сделайте свой сниппет для каждого поля или используйте опции:
Вывод:
<?php
switch ($options){
case 1:
// логика замены для поля 1
$out = '...';
break;
case 2:
// логика замены для поля 2
$out = '...';
break;
}
return $out;
Вывод:
[[*content:snippet=`1`]]
[[*description:snippet=`2`]]
Малость не понял. Поясню что я имел в виду выше. Допустим, есть список замен из 100 слов. Мне без разницы где встретится слово — в первом поле, втором или третьем, но если оно есть на странице в любом из них, то должно быть заменено. Я так понял, что вы предлагаете каким-то образом разделить список замен так, чтобы для каждого из поля (content, dexctiption и пр.) не было пересечений в списках замен. Вы это предлагаете? Или же вы предлагаете добавлять дополнительную логику и в ней проверять были ли замены в предыдущем блоке для следующего?
Я предложил второй вариант в ответ на Ваш комментарий про разные поля и он имеет смысл, если для content один набор замен, а для description другой.
Если Вам все равно, в каком поле встретится слово, то это как раз первый вариант. Прописываете в нем замену 100 слов и при парсинге шаблона система их заменит там, где они встречаются.
Можно вообще не привязываться к полям, а сделать плагин замены на событие OnWebPagePrerender и тогда будет обрабатываться вообще весь код страницы перед выводом в браузер.
Если Вам все равно, в каком поле встретится слово, то это как раз первый вариант. Прописываете в нем замену 100 слов и при парсинге шаблона система их заменит там, где они встречаются.
Можно вообще не привязываться к полям, а сделать плагин замены на событие OnWebPagePrerender и тогда будет обрабатываться вообще весь код страницы перед выводом в браузер.
Либо я не понимаю, либо плохо объяснил.
Давайте попробую еще раз. Для примера возьмем всего два поля и две замены. В первом и во втором полях встречаются по два искомых для замены слова. Используя первый вариант (через один и тот же модификатор для каждого поля), в каждом из двух полей мы получим по две замены. Этот вариант не подходит, так как в нем должно было бы замениться только два первых совпадения, а они встречаются в первом поле. Во втором же поле замен не должно было быть, так как по одной из них уже сделано было в первом поле.
Список замен один, общий для всех полей. Таким образом первый вариант не подходит из-за возможности повторения множественности замен, а второй — из-за того, что список замен общий для всех полей.
Третий предложенный вами вариант с обработкой всего кода страницы тоже не подход, так как нужна обработка данных именно в некоторых полях, а не во всех.
Давайте попробую еще раз. Для примера возьмем всего два поля и две замены. В первом и во втором полях встречаются по два искомых для замены слова. Используя первый вариант (через один и тот же модификатор для каждого поля), в каждом из двух полей мы получим по две замены. Этот вариант не подходит, так как в нем должно было бы замениться только два первых совпадения, а они встречаются в первом поле. Во втором же поле замен не должно было быть, так как по одной из них уже сделано было в первом поле.
Список замен один, общий для всех полей. Таким образом первый вариант не подходит из-за возможности повторения множественности замен, а второй — из-за того, что список замен общий для всех полей.
Третий предложенный вами вариант с обработкой всего кода страницы тоже не подход, так как нужна обработка данных именно в некоторых полях, а не во всех.
Да, честно говоря, непонятно )).
То есть если у Вас в поле description такой текст:
Lorem ipsum dolor слово1 sit amet, consectetur adipiscing слово2 elit.
А в поле content такой:
Lorem слово1 ipsum dolor sit amet, consectetur adipiscing слово2 elit слово3.
То в результате работы сниппета:
У Вас [[*description:snippet]] выведет:
Lorem ipsum dolor замена1 sit amet, consectetur adipiscing замена2 elit.
А [[*content:snippet]] выведет:
Lorem замена1 ipsum dolor sit amet, consectetur adipiscing замена2 elit замена3.
Этот вариант не подходит, так как в нем должно было бы замениться только два первых совпадения, а они встречаются в первом полеВ этом варианте заменятся все совпадения во всех полях. Модификатор вызывается по отдельности для каждого поля.
То есть если у Вас в поле description такой текст:
Lorem ipsum dolor слово1 sit amet, consectetur adipiscing слово2 elit.
А в поле content такой:
Lorem слово1 ipsum dolor sit amet, consectetur adipiscing слово2 elit слово3.
То в результате работы сниппета:
<?php
$arr1 = array(
'слово1',
'слово2',
'слово3'
);
$arr2 = array(
'замена1',
'замена2',
'замена3'
);
return str_replace($arr1, $arr1, $input);
У Вас [[*description:snippet]] выведет:
Lorem ipsum dolor замена1 sit amet, consectetur adipiscing замена2 elit.
А [[*content:snippet]] выведет:
Lorem замена1 ipsum dolor sit amet, consectetur adipiscing замена2 elit замена3.
Ладно, попробую еще раз объяснить.
Имеем три поля:
Имеем список замен (список будет исключительно в единичном экземпляре):
После преобразования должно получиться вот что:
Т. е. должна быть только одна замена из списка замен по всем полям, если их объединить.
Имеем три поля:
//Поле 1
зима, весна, лето, осень
//Поле 2
весна и лето — теплые времена года
//Поле 3
зима и осень — прохладные времена года. пьем кофе.
Имеем список замен (список будет исключительно в единичном экземпляре):
зима —> зима (холод)
весна —> весна (тепло)
лето —> лето (тепло)
осень —> осень (холод)
кофе —> кофе (горячий)
После преобразования должно получиться вот что:
//Поле 1 (4 совпадения, 4 замены)
зима (холод), весна (тепло), лето (тепло), осень (холод)
//Поле 2 (4 совпадения, 0 замен, так как замены уже были)
весна и лето — теплые времена года
//Поле 3 (1 совпадения, 1 замена)
зима и осень — прохладные времена года. пьем кофе (горячий).
Т. е. должна быть только одна замена из списка замен по всем полям, если их объединить.
Т. е. должна быть только одна замена из списка замен по всем полям, если их объединить.Из Ваших предыдущих сообщений не очевидно, что замена должна срабатывать только один раз ))).
А так да — объединяйте все в один текст, делите, меняйте, потом пишите результат в плейсхолдеры и выводите на страницу.
Возможно, именно этот момент мне и непонятен. Как получить нужные поля, обработать их — это понятно, а вот потом как вывести все обработанное в одном месте в разные поля — вот это вопрос.
Можно передавать сниппету поля:
В сниппете:
Выводите на страницу:
[[Snippet? &fields=`content,description,tv.tvname`]]
В сниппете:
<?php
$inarr = explode(',', $fields);
foreach($inarr as $field){
if(strpos($field, 'tv.') === false){
$content = $modx->resource->get($field);
}else{
$content = $modx->resource->getTVValue(str_replace('tv.', '', $field));
}
$text[] = $content;
}
$str = implode('--separator--', $text);
$result = '.......'; // заменяем что надо
$resarr = explode('--separator--', $result);
foreach($resarr as $key => $val){
$modx->setPlaceholder('new.'.$inarr[$key], $val);
}
return;
Выводите на страницу:
[[+new.content]]
[[+new.description]]
[[+new.tv.tvname]]
…
Правильно ли я понял? — Сначала в шаблоне один раз перед нужными полями мы запускаем сниппет с именем Snippet, передаем в него нужные нам поля (content,description,tv.tvname). Затем сниппет запускается, включается прописанная в нем логика (делает замены) и закрепляет результат за некими переменными, именуемыми по именам переданных полей (content,description,tv.tvname). После этого в шаблоне становится доступными результаты работы сниппета, доступ к которым можно получить через общий префикс и имена, которые были заданы в сниппете.
Я просто никогда раньше с плейсхолдерами не сталкивался.
Я просто никогда раньше с плейсхолдерами не сталкивался.
Да, именно так.
Класс, спасибо за разъяснения.
Может быть у вас завалялась ссылочка на полезный материал по этим плейсхолдерам. Посмотрел информацию по ссылке, данной вами выше, — она скудна и без объяснений подобно вашим не разберешься.
Может быть у вас завалялась ссылочка на полезный материал по этим плейсхолдерам. Посмотрел информацию по ссылке, данной вами выше, — она скудна и без объяснений подобно вашим не разберешься.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.