Универсальное комбинированное свойство

Управление контентом
без дублирования структур
Модуль для проектов, где данные не ограничиваются схемой «одно поле — одно значение». Гибкая настройка набора подполей под бизнес-задачи с единой формой управления.
Единое логическое поле
Объединение связанных данных в одном свойстве с хранением в JSON.
Конструктор структур
Формирование собственных структур из подполей различных типов.
Ускорение работы
Интуитивно понятная форма в административной панели.
Снижение затрат
Изменение структуры через настройки свойства без создания новых сущностей.
Гибкость вёрстки
Данные готовы для произвольного вывода в шаблонах.
Контакты
Филиалы, офисы, шоурумы — единый формат данных.
События
Вебинары, презентации, программы — структурированная карточка.
Коммерческие предложения
Тарифы, пакеты, промо — прозрачное управление.
Готовые фрагменты кода для интеграции в шаблоны
<?php
// Получение данных из свойства (MULTIPLE = N)
$contacts = $arResult['PROPERTIES']['CONTACTS_BLOCK']['VALUE'] ?? [];
if (!is_array($contacts) || empty($contacts)) {
return;
}
// Извлечение подполей
$address = (string)($contacts['ADDRESS'] ?? '');
$phone = (string)($contacts['PHONE'] ?? '');
$email = (string)($contacts['EMAIL'] ?? '');
$map = $contacts['MAP'] ?? '';
?>
<div class="contacts-block">
<?php if ($address !== ''): ?>
<div><?= htmlspecialcharsbx($address) ?></div>
<?php endif; ?>
<?php if ($phone !== ''): ?>
<div><a href="tel:<?= htmlspecialcharsbx($phone) ?>"><?= htmlspecialcharsbx($phone) ?></a></div>
<?php endif; ?>
<?php if ($email !== ''): ?>
<div><a href="mailto:<?= htmlspecialcharsbx($email) ?>"><?= htmlspecialcharsbx($email) ?></a></div>
<?php endif; ?>
</div>
<?php
// Получение данных из свойства (MULTIPLE = Y)
$rows = $arResult['PROPERTIES']['TARIFFS']['VALUE'] ?? [];
if (!is_array($rows) || empty($rows)) {
return;
}
?>
<div class="tariffs">
<?php foreach ($rows as $row): ?>
<?php if (!is_array($row)) { continue; } ?>
<?php
$name = (string)($row['TARIFF_NAME'] ?? '');
$price = $row['PRICE'] ?? '';
$services = (string)($row['SERVICES'] ?? '');
$badge = (string)($row['BADGE'] ?? '');
?>
<div class="tariff-card">
<?php if ($name !== ''): ?>
<h3><?= htmlspecialcharsbx($name) ?></h3>
<?php endif; ?>
<?php if ($price !== '' && $price !== null): ?>
<div class="price">
<?= htmlspecialcharsbx((string)$price) ?> ₽
</div>
<?php endif; ?>
<?php if ($services !== ''): ?>
<div class="services">
<?= nl2br(htmlspecialcharsbx($services)) ?>
</div>
<?php endif; ?>
<?php if ($badge !== ''): ?>
<span class="badge">
<?= htmlspecialcharsbx($badge) ?>
</span>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php
// Получение ID файла из подполя
$fileId = (int)($row['FILE'] ?? 0);
if ($fileId > 0) {
// Получение информации о файле
$file = CFile::GetFileArray($fileId);
if (is_array($file) && !empty($file['SRC'])) {
// Определение имени файла для отображения
$name = $file['ORIGINAL_NAME'] ?: $file['FILE_NAME'];
?>
<a href="<?= htmlspecialcharsbx($file['SRC']) ?>"
target="_blank" rel="noopener"
class="file-link">
<i class="fas fa-download"></i>
<?= htmlspecialcharsbx($name) ?>
</a>
<?php
}
}
?>
<?php
// Получение ID связанного элемента
$elementId = (int)($data['ELEMENT_LINK'] ?? 0);
if ($elementId > 0) {
// Получение данных связанного элемента
$element = CIBlockElement::GetByID($elementId)->Fetch();
if (is_array($element) && !empty($element['NAME'])) {
// Формирование ссылки на элемент
$detailUrl = $element['DETAIL_PAGE_URL'] ?? '';
?>
<div class="linked-element">
<?php if ($detailUrl !== ''): ?>
<a href="<?= htmlspecialcharsbx($detailUrl) ?>">
<?= htmlspecialcharsbx($element['NAME']) ?>
</a>
<?php else: ?>
<?= htmlspecialcharsbx($element['NAME']) ?>
<?php endif; ?>
</div>
<?php
}
}
?>
<?php
// Получение значения из списка
$listValue = (string)($data['LIST_FIELD'] ?? '');
// Маппинг значений (если требуется)
$statusMap = [
'draft' => 'Черновик',
'active' => 'Активно',
'archive' => 'Архив'
];
$displayText = $statusMap[$listValue] ?? $listValue;
?>
<div class="list-field">
<span class="status-<?= htmlspecialcharsbx($listValue) ?>">
<?= htmlspecialcharsbx($displayText) ?>
</span>
</div>
<?php
// Получение даты из подполя
$dateFrom = (string)($event['DATE_FROM'] ?? '');
$dateTo = (string)($event['DATE_TO'] ?? '');
// Форматирование даты (пример)
if ($dateFrom !== '') {
// Преобразование в формат дд.мм.гггг
$formattedDate = date('d.m.Y', strtotime($dateFrom));
?>
<div class="date-field">
<span class="label">Дата начала:</span>
<span class="value">
<?= htmlspecialcharsbx($formattedDate) ?>
</span>
</div>
<?php
}
if ($dateTo !== '') {
$formattedDate = date('d.m.Y', strtotime($dateTo));
?>
<div class="date-field">
<span class="label">Дата окончания:</span>
<span class="value">
<?= htmlspecialcharsbx($formattedDate) ?>
</span>
</div>
<?php
}
?>
<?php
// Получение значения цвета
$color = (string)($data['COLOR'] ?? '#000000');
// Проверка валидности цвета
if (preg_match('/^#[a-f0-9]{6}$/i', $color)) {
?>
<div class="color-display" style="display:flex; align-items:center; gap:10px;">
<span class="color-preview" style="display:inline-block; width:30px; height:30px; border-radius:4px; background:<?= htmlspecialcharsbx($color) ?>;"></span>
<span class="color-code">
<?= htmlspecialcharsbx($color) ?>
</span>
</div>
<?php
}
?>
<?php
// Получение данных из UF-поля раздела
$event = $arResult['UF_EVENT_META'] ?? [];
if (!is_array($event) || empty($event)) {
return;
}
?>
<div class="event-meta">
<?php if (!empty($event['DATE_FROM'])): ?>
<div class="meta-item">
<span class="meta-label">Начало:</span>
<span class="meta-value">
<?= htmlspecialcharsbx((string)$event['DATE_FROM']) ?>
</span>
</div>
<?php endif; ?>
<?php if (!empty($event['DATE_TO'])): ?>
<div class="meta-item">
<span class="meta-label">Окончание:</span>
<span class="meta-value">
<?= htmlspecialcharsbx((string)$event['DATE_TO']) ?>
</span>
</div>
<?php endif; ?>
<?php if (!empty($event['PLACE'])): ?>
<div class="meta-item">
<span class="meta-label">Место:</span>
<span class="meta-value">
<?= htmlspecialcharsbx((string)$event['PLACE']) ?>
</span>
</div>
<?php endif; ?>
<?php if (!empty($event['ORGANIZER'])): ?>
<div class="meta-item">
<span class="meta-label">Организатор:</span>
<span class="meta-value">
<?= (int)$event['ORGANIZER'] ?>
</span>
</div>
<?php endif; ?>
</div>
Рекомендации по использованию
- • Используйте стабильные коды подполей (TITLE, PRICE, DATE_FROM)
- • Всегда экранируйте вывод через htmlspecialcharsbx
- • Для сложных блоков выносите разбор JSON в result_modifier.php
- • Для повторяющихся секций используйте множественные свойства
Для бизнеса
- Ускоренный запуск новых страниц и направлений
- Снижение затрат на разработку и сопровождение
- Единый подход к контенту в разных разделах сайта
- Снижение вероятности ошибок редакторов благодаря структуре
- Упрощённое масштабирование проекта
Для разработчика
- Структурированные данные в одном свойстве
- Простая интеграция в шаблоны компонентов
- Отсутствие множества инфоблоков и технического долга
- Гибкая эволюция проекта без тяжёлых миграций
Готовое решение для контентных проектов
Структура страницы адаптируется под любой раздел. Контент остаётся управляемым, данные — предсказуемыми.



