Бывает, что на странице товара отображается текст, который никак не находится ни в файлах шаблона, ни в языковых константах. Например, слово «отсутствует» в таблице остатков по складам. Вы обшарили все php-файлы, grep молчит, а на странице оно есть.
Почему так происходит
Текст может рендериться внутри компонента, который вы не контролируете напрямую — например, dresscode:catalog.store.amount. Битрикс-компонент собирает HTML внутри себя, и вы не можете просто найти строку в своём шаблоне, потому что её там нет.
Решение: захват буфера и замена
Метод простой: перехватываем вывод компонента через ob_start(), заменяем нужный текст через str_replace(), и выводим результат.
Шаг 1. Определяем, какой компонент выводит текст
Ищем в шаблоне вызов $APPLICATION->IncludeComponent, внутри которого появляется нежелательный текст. В нашем случае это был:
<?php
$APPLICATION->IncludeComponent(
"dresscode:catalog.store.amount",
".default",
array(...)
);
?>
Шаг 2. Оборачиваем вызов в буферизацию
<?
ob_start();
$APPLICATION->IncludeComponent(
"dresscode:catalog.store.amount",
".default",
array(
"STORES" => $arParams['STORES'],
"ELEMENT_ID" => $arResult["ID"],
"STORE_PATH" => $arParams['STORE_PATH'],
"CACHE_TYPE" => "A",
"CACHE_TIME" => "3600000",
"MAIN_TITLE" => "",
"USE_MIN_AMOUNT" => $arParams["USE_MIN_AMOUNT"],
"MIN_AMOUNT" => $arParams["MIN_AMOUNT"],
"OFFER_ID" => $arParams["OFFER_ID"]
)
);
$storesHtml = ob_get_contents();
ob_end_clean();
$storesHtml = str_replace("отсутствует", "Под заказ от 1 до 5 дней", $storesHtml);
echo $storesHtml;
?>
Что происходит:
ob_start()— включает буферизацию выводаIncludeComponent— отрабатывает, но вывод попадает не на страницу, а в буферob_get_contents()— читает содержимое буфераob_end_clean()— очищает и выключает буферstr_replace()— делает замену текстаecho— выводит изменённый HTML на страницу
А если текст появляется динамически (AJAX)?
Если текст подгружается через AJAX (переключение торговых предложений, всплывающие окна), то серверной замены недостаточно — нужно ловить момент, когда новый HTML вставляется в DOM.
MutationObserver
<script>
(function(){
var observer = new MutationObserver(function(mutations){
mutations.forEach(function(mutation){
if(mutation.addedNodes.length){
document.querySelectorAll(".storeTable .value").forEach(function(el){
if(el.textContent.trim() === "отсутствует"){
el.textContent = "Под заказ от 1 до 5 дней";
}
});
}
});
});
observer.observe(document.body, {childList: true, subtree: true});
})();
</script>
Этот скрипт вешается один раз и автоматически обрабатывает любой контент, добавленный в DOM после AJAX-запроса.
Альтернативы
- Кастомизация шаблона компонента — скопировать .default шаблон catalog.store.amount в пространство имён шаблона сайта и править напрямую. Но если таких замен много, буферизация удобнее.
- Языковые переменные — если текст выводится через GetMessage(), достаточно переопределить константу в файле lang/ шаблона. Но если компонент использует свою локаль, это не сработает.
- jQuery на готовой странице — можно просто найти элементы после загрузки страницы и заменить текст. Недостаток — визуальный «моргание» текста до замены.
Итог
ob_start() / str_replace() — простой и надёжный способ заменить любой текст в выводе Битрикс-компонента, даже если исходный код компонента недоступен для правки. А MutationObserver добавляет поддержку динамической подгрузки контента.