Bitrix: Assign Properties to Infoblock Sections by Nesting Level
Learn how to assign user properties to Bitrix infoblock sections at specific nesting levels. Restrict section properties by hierarchy depth using DEPTH_LEVEL, UF_* fields, and CIBlockSectionPropertyLink for precise control.
In Bitrix, is it possible to assign specific user properties to infoblock sections at particular nesting levels? How can I restrict section properties based on hierarchy depth for different levels?
Yes — you can attach user properties to Bitrix infoblock sections and restrict which properties apply by nesting level. Use section user fields (UF_*) for data stored on the section itself and use property-to-section links (CIBlockSectionPropertyLink or D7’s SectionPropertyTable) to bind element properties to only the sections at the levels you want; filter sections by DEPTH_LEVEL (via CIBlockSection::GetList) and Add/Delete links programmatically to enforce per-level rules.
Contents
- How Bitrix stores section properties and nesting
- CIBlockSection::GetList and DEPTH_LEVEL — filter by nesting levels
- Option A — UF_* user fields on sections (section-level properties)
- Option B — Link element properties to sections (CIBlockSectionPropertyLink / D7)
- Practical examples: apply/unapply properties by depth (code)
- Admin UI and enforcement: hiding, validation, imports
- Best practices and caveats
- Sources
- Conclusion
How Bitrix stores section properties and nesting
Bitrix stores sections in a tree; each section has system fields like ID, LEFT_MARGIN/RIGHT_MARGIN and DEPTH_LEVEL (DEPTH_LEVEL starts at 1 for root). DEPTH_LEVEL is computed automatically and is the easiest selector when you want to target a specific nesting level. For section queries use the standard API methods (for example CIBlockSection::GetList) which support filtering by DEPTH_LEVEL and ordering by LEFT_MARGIN/RIGHT_MARGIN for subtree operations — see the official GetList docs for details and examples: https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblocksection/getlist.php and practical notes on margins and nesting at https://alexvaleev.ru/margin-sections-bitrix/ and https://vecdev.ru/blog/bitriks/poluchit-spisok-razdelov-api-bitriks-ciblocksection-getlist/.
Two distinct concepts matter in practice:
- Section user fields (UF_*) — data attached to the section object itself. Good when the property is a characteristic of the category (section).
- Element properties linked to sections — a mechanism to enable/disable element properties per section (used, for example, to control which properties appear in the smart filter). This is done via CIBlockSectionPropertyLink (classic API) or the D7 ORM table \Bitrix\Iblock\SectionPropertyTable.
Which one you choose depends on whether the value belongs to the section itself (use UF_*) or you need to control element properties/filtering per section (use property links).
CIBlockSection::GetList and DEPTH_LEVEL — filter by nesting levels
To target sections at a particular nesting level use DEPTH_LEVEL in the filter for CIBlockSection::GetList. Example (read-only retrieval):
$arSelect = ['ID','NAME','DEPTH_LEVEL','UF_MY_FIELD'];
$arFilter = ['IBLOCK_ID' => $iblockId, 'GLOBAL_ACTIVE' => 'Y', 'DEPTH_LEVEL' => 2];
$rs = CIBlockSection::GetList(['LEFT_MARGIN' => 'ASC'], $arFilter, false, $arSelect);
while ($section = $rs->GetNext()) {
// $section['ID'], $section['NAME'], $section['UF_MY_FIELD']
}
See the API docs for CIBlockSection::GetList: https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblocksection/getlist.php. If you need a subtree under a specific parent, you can use LEFT_MARGIN/RIGHT_MARGIN constraints (see examples at https://alexvaleev.ru/margin-sections-bitrix/).
Option A — UF_* user fields on sections (section-level properties)
When the property is an attribute of the section itself (e.g., “promo banner”, “category icon”, “SEO flag”), create a user field for sections (UF_). You can add these fields in the admin UI or programmatically via the user field API (CUserTypeEntity). Once created, UF_ fields are available via CIBlockSection::GetList if you include them in arSelect. Practical guide: https://hmarketing.ru/blog/bitrix/polzovatelskie-svoytva-razdela-infobloka/.
Pros:
- Natural place for section metadata.
- Easy to read/write in templates and components.
Limitations and how to restrict by depth:
- UF fields exist for all sections (there’s no built-in “only show this UF for depth = 2” option in core).
- To enforce per-depth usage you have to implement one (or more) of the following:
- Populate UF fields only for the sections at your target DEPTH_LEVEL and leave them empty elsewhere.
- Enforce rules server-side with event handlers (OnBeforeIBlockSectionAdd / OnBeforeIBlockSectionUpdate) to clear or block fields when the new/updated section isn’t at the allowed depth.
- Apply admin-side JS to hide/show fields on the section edit page depending on the selected parent (requires a small admin UI customization).
- Split sections into separate infoblocks if different depths must have entirely different schemas.
Server-side validation example (sketch):
AddEventHandler("iblock","OnBeforeIBlockSectionAdd","MyOnBeforeSectionAdd");
AddEventHandler("iblock","OnBeforeIBlockSectionUpdate","MyOnBeforeSectionUpdate");
function MyOnBeforeSectionAdd(&$arFields) {
// determine depth (by parent) and strip UF fields if depth != allowed
// (example logic only; keep defensive checks)
$allowedDepth = 2;
$parentId = intval($arFields['IBLOCK_SECTION_ID']);
$depth = 1;
if ($parentId) {
$parent = CIBlockSection::GetByID($parentId)->GetNext();
$depth = ($parent ? intval($parent['DEPTH_LEVEL']) + 1 : 1);
}
if ($depth !== $allowedDepth) {
unset($arFields['UF_MY_FIELD']); // prevent saving this UF on wrong depth
}
}
Server-side enforcement is the reliable way to restrict data — client-side hiding alone can be bypassed.
Option B — Link element properties to sections (CIBlockSectionPropertyLink / D7)
If you want to control element properties (the properties that live on elements of an infoblock) per section — for example, show different smart filter fields for different category depths — use the property-to-section linking API. With the classic API use CIBlockSectionPropertyLink::Add/Delete/GetArray; with D7 use \Bitrix\Iblock\SectionPropertyTable.
Examples and details:
- Add a link with CIBlockSectionPropertyLink::Add($SECTION_ID, $PROPERTY_ID, $arLink). You can pass $SECTION_ID = 0 to apply the property to the whole iblock. See practical API notes: https://www.acrit-studio.ru/pantry-programmer/knowledge-base/privyazka-svoytva-k-razdelam/ and community explanation: https://dev.1c-bitrix.ru/community/webdev/user/89826/blog/8493/.
- The link metadata can include flags (for example, to enable property in SMART_FILTER or to define whether it’s inherited). When you query existing links you’ll see data like INHERITED and INHERITED_FROM (use the API/GetArray or D7 to inspect).
Why this is often the better choice for “properties by category level”:
- It lets you enable/disable properties for specific sections (and by extension control which properties appear in filters and in templates).
- You can target many existing properties without creating separate UF fields.
- It’s designed for per-section control of element properties.
D7 snippet (conceptual) for adding a section-property link:
use Bitrix\Iblock\SectionPropertyTable;
SectionPropertyTable::add([
'IBLOCK_ID' => $iblockId,
'SECTION_ID' => $sectionId,
'PROPERTY_ID' => $propertyId,
'SMART_FILTER' => 'Y' // example flag
]);
See a D7 example collection: https://estrin.pw/bitrix-d7-snippets/s/iblock-section-property-settings/ and the classic API notes at https://www.acrit-studio.ru/pantry-programmer/knowledge-base/privyazka-svoytva-k-razdelam/.
Practical examples: apply/unapply properties by depth (code)
- Bind one element property to every section at DEPTH_LEVEL = 2 (classic API):
$iblockId = 16;
$propertyId = 123; // property you want to bind
$rs = CIBlockSection::GetList(
['LEFT_MARGIN' => 'ASC'],
['IBLOCK_ID' => $iblockId, 'DEPTH_LEVEL' => 2],
false,
['ID']
);
while ($sec = $rs->GetNext()) {
\CIBlockSectionPropertyLink::Add($sec['ID'], $propertyId, ['SMART_FILTER' => 'Y']);
}
- Unbind that property from all sections at DEPTH_LEVEL != 2 (sketch):
$rs = CIBlockSection::GetList([], ['IBLOCK_ID' => $iblockId], false, ['ID','DEPTH_LEVEL']);
while ($sec = $rs->GetNext()) {
if ($sec['DEPTH_LEVEL'] != 2) {
\CIBlockSectionPropertyLink::Delete($sec['ID'], $propertyId);
}
}
- D7-style add (useful in modern projects):
use Bitrix\Iblock\SectionPropertyTable;
$res = SectionPropertyTable::add([
'IBLOCK_ID' => $iblockId,
'SECTION_ID' => $sectionId,
'PROPERTY_ID' => $propertyId,
'SMART_FILTER' => 'Y'
]);
- Retrieve links (classic idea): CIBlockSectionPropertyLink::GetArray or D7 getList to examine PROPERTY_ID, INHERITED, INHERITED_FROM and decide what to show.
Note: After mass changes clear relevant component caches (catalog, smart filter, etc.) so front-end components pick up new bindings.
Admin UI and enforcement: hiding, validation, imports
Do you want fields never to appear for editors at the wrong depth? Two practical approaches:
- Server-side enforcement (recommended): use event handlers to validate/strip/unset UF fields or to block a section save when the depth is wrong. This cannot be bypassed and is safe.
- Admin UI tweaks: inject admin-side JS to hide/show specific UF inputs on the section edit page depending on the parent selection (works but can be bypassed and requires maintenance).
For imports, note there are platform settings that limit nesting depth handling in CSV import/export — if you rely on deep trees check import settings or server-side import logic; see related discussion about import depth limits: https://ru.stackoverflow.com/questions/1229672/1С-bitrix-Как-увеличить-глубину-вложенности-разделов-при-импорте-товаров-Тариф.
Also remember many front-end components (catalog, smart filter) expect properties to be linked correctly — test templates (and third-party themes like Origami which may use depth in their UI) after changing links: https://www.sotbit.ru/docs/sotbit.origami/lesson/catalog_subsection/.
Best practices and caveats
- Choose the right model: UF_* for true section attributes; Section → Property links for controlling element-property visibility/filtering.
- Use DEPTH_LEVEL to target levels (
DEPTH_LEVELis reliable and computed by the system) — filter in CIBlockSection::GetList: https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblocksection/getlist.php. - Prefer server-side validation over client-side hiding if you must prevent improper values.
- Keep property count reasonable — too many property links can make filters heavy; test performance.
- Remember inheritance: links can be inherited; inspect INHERITED / INHERITED_FROM when debugging (API returns these metadata fields).
- If your business rules differ dramatically by depth, consider separate infoblocks (simpler schema, but more maintenance).
- After bulk changes clear caches and reindex if necessary.
Sources
- https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblocksection/getlist.php
- https://hmarketing.ru/blog/bitrix/polzovatelskie-svoytva-razdela-infobloka/
- https://www.acrit-studio.ru/pantry-programmer/knowledge-base/privyazka-svoytva-k-razdelam/
- https://dev.1c-bitrix.ru/community/webdev/user/89826/blog/8493/
- https://estrin.pw/bitrix-d7-snippets/s/iblock-section-property-settings/
- https://alexvaleev.ru/margin-sections-bitrix/
- https://vecdev.ru/blog/bitriks/poluchit-spisok-razdelov-api-bitriks-ciblocksection-getlist/
- https://ru.stackoverflow.com/questions/1229672/1С-bitrix-Как-увеличить-глубину-вложенности-разделов-при-импорте-товаров-Тариф
- https://www.sotbit.ru/docs/sotbit.origami/lesson/catalog_subsection/
Conclusion
Yes — Bitrix supports assigning properties to infoblock sections and you can restrict which properties apply by nesting levels. For section-specific metadata use UF_* fields and filter by DEPTH_LEVEL at read/write time; for controlling element properties or smart-filter visibility per section use CIBlockSectionPropertyLink or D7’s SectionPropertyTable and programmatically Add/Delete links for the DEPTH_LEVELs you need. Want strict enforcement? Do it server-side (event handlers) and clear caches after bulk updates.