Developing Custom Parameters for 1C-Bitrix Components
A component that works only with settings hard-coded into the code is not a component — it's a script. Custom parameters (.parameters.php) make a component configurable through the Bitrix visual editor without touching the code. For complex projects with a team of developers and content managers, this is a critical part of the architecture.
Why Custom Parameters Are Needed
Standard component invocation with hard-coded parameters:
$APPLICATION->IncludeComponent('custom:product.slider', '', [
'IBLOCK_ID' => 5,
'COUNT' => 8,
'SHOW_PRICE' => 'Y',
]);
This works, but when requirements change a developer has to dig into the page template. With .parameters.php, a manager can update settings themselves through the "Component Properties" interface.
Parameter Types and When to Use Each
Bitrix supports the following types (TYPE in the parameter array):
| Type | When to Use |
|---|---|
STRING |
Title, CSS class, URL |
LIST |
Selection from a set of values |
CHECKBOX |
Yes/No flags |
NUMBER |
Quantity, limits |
COLORPICKER |
Color selection |
FILE |
File path |
CUSTOM |
Arbitrary HTML widget |
A Complete .parameters.php
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
use Bitrix\Main\Loader;
// Prepare data for LIST-type parameters
$arIblockList = ['' => '-- Select an infoblock --'];
if (Loader::includeModule('iblock')) {
$res = CIBlock::GetList(['SORT' => 'ASC'], ['ACTIVE' => 'Y', 'SITE_ID' => SITE_ID]);
while ($ib = $res->Fetch()) {
$arIblockList[$ib['ID']] = '[' . $ib['ID'] . '] ' . $ib['NAME'];
}
}
$arSortOptions = [
'SORT_ASC' => 'By order (ascending)',
'SORT_DESC' => 'By order (descending)',
'DATE_ACTIVE_FROM_DESC' => 'By date (newest first)',
'NAME_ASC' => 'By name (A–Z)',
'RAND' => 'Random order',
];
$arLayoutOptions = [
'grid' => 'Grid',
'list' => 'List',
'slider' => 'Slider',
];
$arComponentParameters = [
'GROUPS' => [
'DATA' => ['NAME' => 'Data Source', 'SORT' => 10],
'FILTER' => ['NAME' => 'Filtering', 'SORT' => 20],
'DISPLAY' => ['NAME' => 'Display', 'SORT' => 30],
'SEO' => ['NAME' => 'SEO & Headings', 'SORT' => 40],
'CACHE' => ['NAME' => 'Caching', 'SORT' => 50],
],
'PARAMETERS' => [
// === DATA Group ===
'IBLOCK_ID' => [
'PARENT' => 'DATA',
'NAME' => 'Infoblock',
'TYPE' => 'LIST',
'VALUES' => $arIblockList,
'DEFAULT' => '',
'REFRESH' => 'Y', // reloads the form on change — needed for dynamic parameters
],
'SECTION_ID' => [
'PARENT' => 'DATA',
'NAME' => 'Section (leave empty for all)',
'TYPE' => 'SECTION', // special type: infoblock section selector
'IBLOCK_ID_VARIABLE' => 'IBLOCK_ID', // takes infoblock ID from another parameter
'DEFAULT' => '',
],
'ELEMENT_SORT_FIELD' => [
'PARENT' => 'DATA',
'NAME' => 'Sorting',
'TYPE' => 'LIST',
'VALUES' => $arSortOptions,
'DEFAULT' => 'SORT_ASC',
],
// === FILTER Group ===
'SHOW_ACTIVE_ONLY' => [
'PARENT' => 'FILTER',
'NAME' => 'Active elements only',
'TYPE' => 'CHECKBOX',
'DEFAULT' => 'Y',
],
'ACTIVE_DATE_FROM' => [
'PARENT' => 'FILTER',
'NAME' => 'Active from (date)',
'TYPE' => 'STRING',
'DEFAULT' => '',
],
// === DISPLAY Group ===
'LAYOUT' => [
'PARENT' => 'DISPLAY',
'NAME' => 'Display type',
'TYPE' => 'LIST',
'VALUES' => $arLayoutOptions,
'DEFAULT' => 'grid',
],
'COUNT' => [
'PARENT' => 'DISPLAY',
'NAME' => 'Number of elements',
'TYPE' => 'STRING',
'DEFAULT' => '12',
],
'COLUMNS' => [
'PARENT' => 'DISPLAY',
'NAME' => 'Columns per row',
'TYPE' => 'LIST',
'VALUES' => ['2' => '2', '3' => '3', '4' => '4', '6' => '6'],
'DEFAULT' => '4',
],
'SHOW_PICTURE' => [
'PARENT' => 'DISPLAY',
'NAME' => 'Show image',
'TYPE' => 'CHECKBOX',
'DEFAULT' => 'Y',
],
'PICTURE_SIZE_X' => [
'PARENT' => 'DISPLAY',
'NAME' => 'Image width (px)',
'TYPE' => 'STRING',
'DEFAULT' => '300',
],
'PICTURE_SIZE_Y' => [
'PARENT' => 'DISPLAY',
'NAME' => 'Image height (px)',
'TYPE' => 'STRING',
'DEFAULT' => '200',
],
'SHOW_PRICE' => [
'PARENT' => 'DISPLAY',
'NAME' => 'Show price',
'TYPE' => 'CHECKBOX',
'DEFAULT' => 'Y',
],
'CSS_CLASS' => [
'PARENT' => 'DISPLAY',
'NAME' => 'Additional CSS class for the block',
'TYPE' => 'STRING',
'DEFAULT' => '',
],
// === SEO Group ===
'SET_TITLE' => [
'PARENT' => 'SEO',
'NAME' => 'Set page title',
'TYPE' => 'CHECKBOX',
'DEFAULT' => 'N',
],
'BLOCK_HEADING' => [
'PARENT' => 'SEO',
'NAME' => 'Block heading (H2)',
'TYPE' => 'STRING',
'DEFAULT' => '',
],
// === CACHE Group ===
'CACHE_TYPE' => ['DEFAULT' => 'A'], // A = Auto
'CACHE_TIME' => ['DEFAULT' => 3600],
'CACHE_GROUPS' => ['DEFAULT' => 'N'], // Cache separately per user group
],
];
CUSTOM Parameter Type
When standard types are not enough — for example, you need multi-section selection or a color palette — the CUSTOM type is used:
'SELECTED_SECTIONS' => [
'PARENT' => 'DATA',
'NAME' => 'Sections (multiple selection)',
'TYPE' => 'CUSTOM',
'DEFAULT' => '',
'JS_EVENT' => 'onCustomParamRender',
],
The JavaScript handler onCustomParamRender renders an arbitrary HTML widget inside the component settings form. This is an advanced feature, used rarely but sometimes irreplaceable.
Normalizing Parameters in component.php
Parameters coming from .parameters.php arrive in component.php as strings or arrays — they must be normalized before use:
// In component.php or in the onPrepareComponentParams method of the class
$arParams['IBLOCK_ID'] = (int) $arParams['IBLOCK_ID'];
$arParams['COUNT'] = max(1, min(100, (int) $arParams['COUNT']));
$arParams['COLUMNS'] = in_array($arParams['COLUMNS'], ['2','3','4','6']) ? (int)$arParams['COLUMNS'] : 4;
$arParams['SHOW_PICTURE'] = $arParams['SHOW_PICTURE'] === 'Y';
$arParams['SHOW_PRICE'] = $arParams['SHOW_PRICE'] === 'Y';
$arParams['CSS_CLASS'] = htmlspecialchars(trim($arParams['CSS_CLASS'] ?? ''));
Without normalization the developer is protected from typos in component calls and from XSS through parameters.
Using Parameters in the Template
// template.php
$cssClass = 'products-block products-block--' . $arParams['LAYOUT'];
if ($arParams['CSS_CLASS']) $cssClass .= ' ' . $arParams['CSS_CLASS'];
?>
<div class="<?= $cssClass ?>" style="--columns: <?= $arParams['COLUMNS'] ?>">
<?php if ($arParams['BLOCK_HEADING']): ?>
<h2><?= htmlspecialchars($arParams['BLOCK_HEADING']) ?></h2>
<?php endif; ?>
<?php foreach ($arResult['ITEMS'] as $item): ?>
<!-- ... -->
<?php endforeach; ?>
</div>
The CSS variable --columns controls the grid:
.products-block {
display: grid;
grid-template-columns: repeat(var(--columns, 4), 1fr);
gap: 20px;
}
Documenting Parameters
For the team that will use the component — documentation in a README or directly in .description.php:
$arComponentDescription = [
'NAME' => 'Product Slider',
'DESCRIPTION' => 'Displays a list of products from the selected infoblock. The LAYOUT parameter controls the display type: grid = grid view, slider = Swiper carousel.',
// ...
];
Timelines
| Parameter scope | What is included | Timeline |
|---|---|---|
| 5–10 parameters | Standard types, groups, normalization | 1–2 days |
| 15–25 parameters | + SECTION type, REFRESH, dependent parameters | 3–5 days |
| + CUSTOM widgets | + JS handlers, complex UI in the form | 1 week |
Well-designed component parameters are documentation embedded in code. A developer opens .parameters.php and immediately understands what the component can do and what values it expects.

