Года и Даты в Cotonti. Пороги диапазона лет.

Как настроить диапазон годов / лет в выпадающих списках даты при редактировании страниц в Cotonti. Как установить минимальный или максимальный порог года при выборе даты.

Comments on this page: 2

ПОДРОБНОЕ РУКОВОДСТВО: Как регулировать диапазон лет в датах при редактировании страниц в Cotonti

(Без хаков, без правки ядра, с полным объяснением — как, где, почему, и что происходит под капотом)

 

 

Введение: Проблема, которую мы решаем

При редактировании статей -  страницы в Cotonti (модуль Page), у нас есть поля:

  • Дата создания
  • Начало публикации
  • Окончание публикации

В каждом из них — выпадающие списки: День | Месяц | Год | Час | Минута

 

Проблема по умолчанию:

 

$max_year = 2030;
$min_year = 2000;

Жёстко прописано в функции cot_selectbox_date()
Не меняется со временем
Через 5 лет (в 2031) — нельзя будет выбрать будущие даты
Через 10 лет — список устареет полностью

→ Довольно большой диапазон в годах между верхним и нижним порогом при выборе года как компонента даты

 

Цель

Сделать динамический и в тоже время контролируемый диапазон лет, например:

  • 2022 – 2026 (в 2025 году)
  • 2023 – 2027 (в 2026 году)
  • Автоматически обновляется каждый год

Без правки ядра. Без плагинов. Через тему.

 

 

Где и как используется cot_selectbox_date()?

 

Функция лежит в  system/forms.php (можно глянуть здесь):


/**
 * Generates date part dropdown
 *
 * @param int $utime Selected timestamp
 * @param string $mode Display mode: 'short' or complete
 * @param string $name Variable name preffix
 * @param int $max_year Max. year possible
 * @param int $min_year Min. year possible
 * @param bool $usertimezone Use user timezone
 * @param string $custom_rc Custom resource string name
 * @return string
 */
function cot_selectbox_date($utime, $mode = 'long', $name = '', $max_year = 2030, $min_year = 2000, $usertimezone = true, $custom_rc = '')
{
	global $L, $R, $usr;

    if (function_exists('cot_selectbox_date_custom'))
    {
        return cot_selectbox_date_custom($utime, $mode, $name, $max_year, $min_year, $usertimezone, $custom_rc);
    }

    $result = NULL;

    /* === Hook === */
    foreach (cot_getextplugins('form.date') as $pl)
    {
        include $pl;
    }
    /* ===== */

    if($result !== NULL) return $result;

	$rc_name = preg_match('#^(\w+)\[(.*?)\]$#', $name, $mt) ? $mt[1] : $name;

	$utime = ($usertimezone && $utime > 0) ? ($utime + $usr['timezone'] * 3600) : $utime;

	if ($utime == 0) {
		list($s_year, $s_month, $s_day, $s_hour, $s_minute) = [null, null, null, null, null];
		$buffered = cot_import_buffered($name, null);
		if (is_array($buffered)) {
			$s_year   = $buffered['year'];
			$s_month  = $buffered['month'];
			$s_day    = $buffered['day'];
			$s_hour   = ($buffered['hour'] ?? 0) > 0 ? $buffered['hour'] : 1;
			$s_minute = $buffered['minute'] ?? 0;
		}
	} else {
		list($s_year, $s_month, $s_day, $s_hour, $s_minute) = explode('-', @date('Y-m-d-H-i', $utime));
	}
	$months = [];
	$months[1] = $L['January'];
	$months[2] = $L['February'];
	$months[3] = $L['March'];
	$months[4] = $L['April'];
	$months[5] = $L['May'];
	$months[6] = $L['June'];
	$months[7] = $L['July'];
	$months[8] = $L['August'];
	$months[9] = $L['September'];
	$months[10] = $L['October'];
	$months[11] = $L['November'];
	$months[12] = $L['December'];

	$year = cot_selectbox($s_year, $name.'[year]', range($max_year, $min_year, -1));
	$month = cot_selectbox($s_month, $name.'[month]', array_keys($months), array_values($months));
	$day = cot_selectbox($s_day, $name.'[day]', range(1, 31));

	$range = [];
	for ($i = 0; $i < 24; $i++) {
		$range[] = sprintf('%02d', $i);
	}
	$hour = cot_selectbox($s_hour, $name.'[hour]', $range);

	$range = [];
	for ($i = 0; $i < 60; $i++) {
		$range[] = sprintf('%02d', $i);
	}

	$minute = cot_selectbox($s_minute, $name.'[minute]', $range);

	$rc = empty($R["input_date_{$mode}"]) ? 'input_date' : "input_date_{$mode}";
	$rc = empty($R["input_date_{$rc_name}"]) ? $rc : "input_date_{$rc_name}";
	$rc = empty($custom_rc) ? $rc : $custom_rc;

	$result = cot_rc($rc, [
		'day' => $day,
		'month' => $month,
		'year' => $year,
		'hour' => $hour,
		'minute' => $minute
	]);

	return $result;
}

 

ПараметрЧто делаетПо умолчанию
$utimeUnix-время выбранной даты
$mode'long' — полные месяцы, 'short' — без'long'
$nameПрефикс полей (rpagedate, rpagebegin)
$max_yearМаксимальный год в списке2030
$min_yearМинимальный год в списке2000
$usertimezoneУчитывать часовой пояс пользователяtrue
$custom_rcКастомный шаблон вывода

Именно $max_year и $min_year — наши цели.

 

 

Где вызывается в редактировании страниц?

 

В modules/page/page.edit.php (можно глянуть здесь):

'PAGEEDIT_FORM_DATE' => cot_selectbox_date($pag['page_date'], 'long', 'rpagedate').' '.Cot::$usr['timetext'],
'PAGEEDIT_FORM_BEGIN' => cot_selectbox_date($pag['page_begin'], 'long', 'rpagebegin').' '.Cot::$usr['timetext'],
'PAGEEDIT_FORM_EXPIRE' => cot_selectbox_date($pag['page_expire'], 'long', 'rpageexpire').' '.Cot::$usr['timetext'],

→ Эти теги ({PAGEEDIT_FORM_DATE} и т.д.) выводятся в шаблоне page.edit.tpl. (можно посмотреть здесь)

 

 

Решение: Переопределить $max_year и $min_year через шаблон + ресурсы $R

Без правки system/functions.php. Без плагинов. Через тему (например, Carbon).

 

 

ШАГ 1: Задаём динамические пороги в файле темы

Файл: themes/carbon/carbon.php

<?php
defined('COT_CODE') or die('Wrong URL');

// === ДИНАМИЧЕСКИЕ ДИАПАЗОНЫ ГОДОВ ДЛЯ ДАТ РЕДАКТИРОВАНИЯ ===

// Текущий год
$current_year = (int)date('Y');

// Минимальный год: -3 года от текущего
$R['page_years_min_range_threshold'] = $current_year - 3;

// Максимальный год: +1 год от текущего
$R['page_years_max_range_threshold'] = $current_year + 1;

 

Почему так?

  • $Rглобальный массив ресурсов, доступный в шаблонах через {PHP.R.название}
  • date('Y')текущее время, всегда актуально
  • $R задаётся один раз при загрузке темы → работает везде

 

 

ШАГ 2: Переопределяем вывод в шаблоне

 

Файл: themes/carbon/page.edit.tpl

Заменяем стандартные теги:

{PAGEEDIT_FORM_DATE}
{PAGEEDIT_FORM_BEGIN}
{PAGEEDIT_FORM_EXPIRE}

на модификатор с новыми параметрами:

<div class="card mb-4">
    <div class="card-header d-flex align-items-center bg-none fw-bold">
        {PHP.L.Date}
    </div>
    <div class="card-body">
        <div class="row">

            <!-- ДАТА СОЗДАНИЯ -->
            <div class="mb-lg-0 mb-3 col-md-4">
                <label class="form-label">{PHP.L.pageDateCreated}</label>
                {PAGEEDIT_FORM_DATE|cot_selectbox_date(
                    '{PHP.pag.page_date}',
                    'short',
                    'rpagedate',
                    '{PHP.R.page_years_max_range_threshold}',
                    '{PHP.R.page_years_min_range_threshold}',
                    false,
                    'input_date_short'
                )}
            </div>

            <!-- НАЧАЛО ПУБЛИКАЦИИ -->
            <div class="mb-lg-0 mb-3 col-md-4">
                <label class="form-label">{PHP.L.Begin}</label>
                {PAGEEDIT_FORM_BEGIN|cot_selectbox_date(
                    '{PHP.pag.page_begin}',
                    'short',
                    'rpagebegin',
                    '{PHP.R.page_years_max_range_threshold}',
                    '{PHP.R.page_years_min_range_threshold}',
                    false,
                    'input_date_short'
                )}
            </div>

            <!-- ОКОНЧАНИЕ ПУБЛИКАЦИИ -->
            <div class="mb-lg-0 mb-3 col-md-4">
                <label class="form-label">{PHP.L.Expire}</label>
                {PAGEEDIT_FORM_EXPIRE|cot_selectbox_date(
                    '{PHP.pag.page_expire}',
                    'short',
                    'rpageexpire',
                    '{PHP.R.page_years_max_range_threshold}',
                    '{PHP.R.page_years_min_range_threshold}',
                    false,
                    'input_date_short'
                )}
            </div>

        </div>
    </div>
</div>

 

 

Что происходит под капотом?

 

ШагОбъяснение
1При загрузке темы → $R['page_years_...'] заполняются
2В шаблоне {PHP.R.page_years_max_range_threshold} → подставляет 2026
3{PAGEEDIT_FORM_DATE|...}перехватывает вывод и вызывает функцию заново
4Функция получает новые $max_year и $min_year → генерирует правильный список

 

 

Дополнительно: Кастомный вид (без часов/минут)

 

$R['input_date_short'] = '<div class="row g-2">
    <div class="col-4">{$day}</div>
    <div class="col-4">{$month}</div>
    <div class="col-4">{$year}</div>
</div>';

 

→ Это переопределяет шаблон вывода
input_date_short — используется вместо стандартного
→ Убирает часы и минуты → чище

 

Почему работает? cot_rc() ищет $R["input_date_{$mode}"] → если есть — использует его.

 

 

Как задать СВОИ диапазоны?

 

Пример 1: Только будущие даты (для begin и expire)

$R['page_years_min_future'] = (int)date('Y');
$R['page_years_max_future'] = (int)date('Y') + 10;

В шаблоне:

{PAGEEDIT_FORM_BEGIN|cot_selectbox_date(
    '{PHP.pag.page_begin}',
    'short',
    'rpagebegin',
    '{PHP.R.page_years_max_future}',
    '{PHP.R.page_years_min_future}',
    false
)}

 

Пример 2: Разные диапазоны для разных полей

 

// Дата создания: можно назад
$R['page_date_min'] = (int)date('Y') - 10;
$R['page_date_max'] = (int)date('Y') + 1;

// Периоды: только вперёд
$R['page_period_min'] = (int)date('Y');
$R['page_period_max'] = (int)date('Y') + 20;

 

 

Почему этот способ — ЛУЧШИЙ?

 

ПлюсОбъяснение
Без правки ядраОбновления Cotonti не сломают
Работает в любой темеПросто копируем в theme.php
АвтообновлениеКаждый год — новый диапазон
ГибкостьЛюбой диапазон, разные для полей
Чистый кодНикаких Cot::$sys, date() в .tpl
Кастомизация видаЧерез $R['input_date_...']

 

 

Частые ошибки и как их избежать

 

ОшибкаКак исправить
Cot::$sys['now'] в шаблоне→ Нельзя! Используй только {PHP.R....}
Забыл кавычки в '{PHP.pag.page_date}'→ Без кавычек — не сработает
Используем long вместо short→ Появятся часы/минуты → уберираем через $R['input_date_short']
Не переопределил $R→ Проверяем файл инициализации темы сайта carbon.php

 

 

Готово!

Теперь имеем:

  • Динамические списки годов
  • Красивый, чистый интерфейс
  • Без багов, без хаков
  • Работает вечно

закрепим мысль, - файл инициализации темы как пример в themes/carbon/carbon.php:

<?php
/* ====================
[BEGIN_COT_THEME]
Name=Carbon
Version=1.0.2
Schemes=default:Default
[END_COT_THEME]
==================== */

/**
 * Cotonti Model Theme
 *
 * @package Carbon
 * @copyright (c) 2025 webitproff https://github.com/webitproff
 * @license BSD
 */

defined('COT_CODE') or die('Wrong URL');


global $R, $sys;
// нижний и верхний порог выбора года (диапазона лет) при редактировании страниц и статей
// для функции cot_selectbox_date
/*
	{PAGEEDIT_FORM_DATE|cot_selectbox_date(
	'{PHP.pag.page_date}', 
	'short', 
	'rpagedate', 
	'{PHP.R.page_years_max_range_threshold}', 
	'{PHP.R.page_years_min_range_threshold}', 
	false,
	false)} // false - это использовать ли шаблон $R['input_date_long'] или $R['input_date_short'] вашей темы
*/
$R['page_years_min_range_threshold'] = (int) cot_date('Y', Cot::$sys['now']) - 3;
$R['page_years_max_range_threshold'] = (int) cot_date('Y', Cot::$sys['now']) + 1;
$R['input_date_long'] = '<div class="row g-2">
    <div class="col-2">{$day}</div>
    <div class="col-3">{$month}</div>
    <div class="col-2">{$year}</div>
    <div class="col-2">{$hour}</div>
    <div class="col-1 text-center">:</div>
    <div class="col-2">{$minute}</div>
</div>';
$R['input_date_short'] = '<div class="row g-2">
    <div class="col-4">{$day}</div>
    <div class="col-4">{$month}</div>
    <div class="col-4">{$year}</div>
</div>';

Как настроить диапазон лет в выпадающих списках даты для редактирования страниц в Cotonti (на примере темы Carbon)

Цель
Сделать так, чтобы при редактировании страницы (в полях Дата создания, Начало публикации, Окончание)
выпадающий список годов показывал не фиксированный диапазон 2000–2030, а динамический:

Минимальный год: текущий год - 3
Максимальный год: текущий год + 1


Пример на 2025 год:
→ выбор от 2022 до 2026
Как переопределить диапазон выбора элементов даты без правки ядра?
Решение: Используем ресурсы $R + модификатор шаблона

Шаг 1: Откройте файл темы
Путь: themes/carbon/carbon.php

Это главный файл темы, он подключается всегда, когда тема активна.


Шаг 2: Добавить код

// === ДИНАМИЧЕСКИЕ ДИАПАЗОНЫ ГОДОВ ДЛЯ РЕДАКТИРОВАНИЯ СТРАНИЦ ===
// Минимальный год: текущий - 3 года
$R['page_years_min_range_threshold'] = (int)date('Y') - 3;
// Максимальный год: текущий + 1 год
$R['page_years_max_range_threshold'] = (int)date('Y') + 1;

 

Почему date('Y')?
Cot::$sys['now'] — это текущее время в секундах.
date('Y') — проще, быстрее, и работает всегда.


Шаг 3: Измените шаблон редактирования страницы

Файл: themes/carbon/modules/page/page.edit.tpl
Найдите блоки:

<tr>
    <td>{PHP.L.Date}:</td>
    <td>
        {PAGEEDIT_FORM_DATE}
        <p class="small" style="margin-top: 6px">{PAGEEDIT_FORM_DATENOW} {PHP.L.page_date_now}</p>
    </td>
</tr>
<tr>
    <td>{PHP.L.Begin}:</td>
    <td>{PAGEEDIT_FORM_BEGIN}</td>
</tr>
<tr>
    <td>{PHP.L.Expire}:</td>
    <td>{PAGEEDIT_FORM_EXPIRE}</td>
</tr>    


Замените их на:

<div class="mb-lg-0 mb-3">
   <label class="form-label">{PHP.L.pageDateCreated}</label>
   {PAGEEDIT_FORM_DATE|cot_selectbox_date('{PHP.pag.page_date}', 'short', 'rpagedate', '{PHP.R.page_years_max_range_threshold}', '{PHP.R.page_years_min_range_threshold}', false)}
</div>
<div class="mb-lg-0 mb-3">
   <label class="form-label">{PHP.L.Begin}</label>
   {PAGEEDIT_FORM_BEGIN|cot_selectbox_date('{PHP.pag.page_begin}', 'short', 'rpagebegin', '{PHP.R.page_years_max_range_threshold}', '{PHP.R.page_years_min_range_threshold}', false)}
</div>
<div class="mb-lg-0 mb-3">
   <label class="form-label">{PHP.L.Expire}</label>
   {PAGEEDIT_FORM_EXPIRE|cot_selectbox_date('{PHP.pag.page_expire}', 'short', 'rpageexpire', '{PHP.R.page_years_max_range_threshold}', '{PHP.R.page_years_min_range_threshold}', false)}
</div>

Решение универсальное и можно использовать не только со страницами, а везде, где есть выпадающий список селектора выбора элементов даты.

 

7 minutes read Sodium Carbonate

Comments (2)

webitproff

2. Sodium Carbonate

2025-11-21 18:54

конечно можно. просто немного допилить сам модуль товаров потребуется.

добавить импорт данных (дата) в создание и редактирование товара, вывести в шаблон, и затем строковыми ресурсами кастомизировать под себя

taroken

1. Татьяна

2025-11-16 02:26

а к товарам для модуля "маркет" тоже так можно сделать?

Only registered users can post new comments

Content author

webitproff

Offline

Sodium Carbonate

Last logged: 2026-09-01 22:41

About me briefly
Support and development of web projects on the CMF Cotonti: private messengers via the website, open and closed small social networks, trading platforms and marketplaces, freelance and services exchange portal, catalogs of goods from wholesale suppliers, dropshipping platforms, online stores, and much more.
View developments and download
Public portfolio of my works and developments
Telegram for messages
@webitproff
Telegram channel
@s/aBuyFILE
  • Page published: 2025-12-20 07:31
  • Last update: 2025-12-20 07:31

Similar pages

Функция cot_selectbox_date и даты в Cotonti
1 Функция cot_selectbox_date в CMS Cotonti предназначена для генерации выпадающих списков для выбора даты и времени. Эти
Даты в CMF Cotonti. Обзор
2 Даты в CMF Cotonti: Запись, Хранение и Вывод (Представление)Введение в работу с датами в CotontiУважаемые начинающие
Даты в CMF Cotonti. Запись, хранение и вывод (представление)
3 Ниже приведён системный обзор механики работы с датами в CMF Cotonti на основе структуры таблицы cot_pages и набора
Примеры: Вывод даты создания статьи в Cotonti: все способы
4 Все основные модификации вывода даты создания статьи (PAGE_CREATED) В этой статье рассмотрены все основные способы