О сниппетах битрикс есть много статей, они представляют собой вставку фрагмента html кода в текст визуального редактора, но что делать, если нужно вставить динамический блок?
Расскажу как я использую сниппеты для вставки в тексты статей динамических блоков, например форму записи на прием или список врачей оказывающих услугу.
Приведу пример как работает вставка акции в услугу.
Есть инфоблок с элементами

Нужно на соответствующих страницах добавлять баннеры с акцией.
Создать сниппет в админке


Вставляться будет не изображение баннера, а html-комментарий <!-- action_insert id="" -->. Сниппет добавляется в текст перетаскиванием мышкой.

Двойным кликом открывается редактирование комментария и вставляется id баннера, который нужно вывести

Теперь при выводе статьи на странице выводится невидимый комментарий. Добавим его обработку.
В файле /local/php_interface/init.php подключаем файл events.php, в нем добавляем следующий код
AddEventHandler("main", "OnEndBufferContent", "AddBlocksToContent");
function AddBlocksToContent(&$content) {
if (defined("ADMIN_SECTION")) {
//код работает в админке и подменяет текст
return false;
}
global $APPLICATION;
$blocks = [
'action_insert' => '<!-- action_insert id="(.*)" -->',
// тут другие сниппеты
];
foreach ($blocks as $block => $tag) {
if (preg_match_all('/' . $tag . '/', $content, $matches)) {
$allMatches = $matches[1] ?? $matches[0];
$htmls = [];
foreach($allMatches as $index => $match) {
ob_start();
$params = [
'text' => $match,
];
for($i = 1; $i <= sizeof($matches) - 1; $i++) {
$params['matches'][] = $matches[$i][$index];
}
$APPLICATION->IncludeFile('includes/inserts/' . $block . '.php', $params, []);
$htmls[] = ob_get_clean();
}
$content = str_replace($matches[0], $htmls, $content);
}
}
}
Добавляется обработчик события OnEndBufferContent в который передается вся сгенерированная html страница &$content
Регулярным выражением на странице находится комментарий из сниппета и подменяется содержимым файла из includes/inserts/action_insert.php
В переменной $params['mathches'][0] добавляются значение найденного параметра "id"
<?php
$action = CIBlockElement::GetByID($matches[0])->Fetch();
if($matches[0] > 0 && $action && $action['ACTIVE'] == 'Y'): ?>
<div class="mb-5">
<a href="#modal-1" class="open_modal">
<img src="<?= CFile::GetPath($action['PREVIEW_PICTURE']) ?>" class="d-none d-md-block offer-before" alt="Специальное предложение">
<img src="<?= CFile::GetPath($action['DETAIL_PICTURE']) ?>" class="d-block d-md-none offer-before" alt="Специальное предложение">
</a>
</div>
<? endif ?>
В результате на странице выводится баннер с проверкой активности из базы.
Оставить комментарий