Centralized Product Content Management Setup in 1C-Bitrix
When product descriptions are edited in multiple places simultaneously, they inevitably diverge: one title in the catalog, another in the YML feed, another in email newsletter. Centralized content management means descriptions, photos, and attributes are updated in one place and automatically distributed to all channels.
Problem: Duplication Sources
In a typical Bitrix store, content is stored in:
- Catalog infoblock (
b_iblock_element,b_iblock_element_property) - Trade offers (
b_iblock_elementof different infoblock) - Generated XML feeds (Yandex.Market, Google Merchant)
- HL-blocks (additional characteristics)
- Email templates (embedded descriptions)
Manually editing in multiple places leads to divergence.
Single Source Principle
Solution — designate one infoblock as "master" and configure derivative channels to read from it. Data structure doesn't change — the process does.
Master infoblock contains everything: NAME, DETAIL_TEXT, PREVIEW_TEXT, DETAIL_PICTURE, MORE_PHOTO and all properties. Nothing is filled anywhere except this infoblock.
Derivative channels read from master:
- YML feed: generator reads
CIBlockElement::GetListfrom master infoblock - Google Merchant feed: similarly
- Email templates: properties substituted from
b_iblock_elementvia API - Marketplaces: export on schedule via agent
Centralized Source Setup for Trade Offers
Often description is set on parent product, while trade offers (SKUs) have no description. To avoid duplication:
// In product card template — get description from parent if not present
$detailText = $arResult['DETAIL_TEXT'];
if (empty($detailText) && $arResult['IBLOCK_TYPE_ID'] === 'offers') {
$parentId = $arResult['PROPERTIES']['CML2_LINK']['VALUE'] ?? null;
if ($parentId) {
$parent = CIBlockElement::GetList(
[], ['ID' => $parentId],
false, false, ['DETAIL_TEXT']
)->Fetch();
$detailText = $parent['DETAIL_TEXT'] ?? '';
}
}
Content Completeness Control
To prevent products from going live with unfilled fields, add validation before activation:
AddEventHandler('iblock', 'OnBeforeIBlockElementUpdate', function(&$fields) {
if ($fields['IBLOCK_ID'] !== CATALOG_IBLOCK_ID) return;
if ($fields['ACTIVE'] !== 'Y') return;
$required = ['NAME', 'DETAIL_TEXT', 'PREVIEW_PICTURE'];
foreach ($required as $field) {
if (empty($fields[$field])) {
$fields['ACTIVE'] = 'N';
// Log incomplete product
\Bitrix\Main\Diag\Debug::writeToFile(
"Product {$fields['ID']} missing field {$field}",
'',
'/local/logs/content-completeness.log'
);
return;
}
}
// Check required properties
$requiredProps = ['BRAND', 'CML2_ARTICLE'];
foreach ($requiredProps as $propCode) {
if (empty($fields['PROPERTY_VALUES'][$propCode])) {
$fields['ACTIVE'] = 'N';
return;
}
}
});
Bulk Content Update Tool
To update descriptions for hundreds of products — use bulk edit via standard infoblock elements list in admin. Enable columns for editing: Admin section → Infoblocks → Elements list → Configure columns.
For loading descriptions from CSV/XLSX file — custom importer:
// /local/admin/import-content.php
// CSV format: product_id;description;short_description
$file = new SplFileObject($_FILES['csv']['tmp_name'], 'r');
$file->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY);
$file->setCsvControl(';');
$el = new CIBlockElement();
foreach ($file as $row) {
[$productId, $detailText, $previewText] = $row;
if (!(int)$productId) continue;
$el->Update((int)$productId, [
'DETAIL_TEXT' => trim($detailText),
'DETAIL_TEXT_TYPE' => 'html',
'PREVIEW_TEXT' => trim($previewText),
]);
}
Cache Clearing on Content Update
After bulk description update, page caches must be cleared. Cache tag for infoblock is iblock_id_{$iblockId}:
// Clear entire infoblock cache
\Bitrix\Main\Data\TaggedCache::clearByTag('iblock_id_' . CATALOG_IBLOCK_ID);
// Or pinpoint clear per element
\Bitrix\Main\Data\TaggedCache::clearByTag('iblock_element_' . $productId);
If using CDN or external caching (Varnish, nginx proxy_cache) — need separate invalidation mechanism via CDN provider API.
Centralized content management setup is primarily a process agreement and a few technical barriers (event handlers + access rights). Implementation takes 3–7 days depending on number of channels and complexity of completeness checks.







