Pages, Articles & News
Tools & Plugins
Example / Placeholder Title


Description as an example placeholder. Sample text content for further customization of the "Index36" template.

You are free to edit and customize the template however you like. If you don’t have time or enough knowledge — you can always order template adaptation by contacting me via GitHub or private messages on the digital goods marketplace.

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

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

2 Published Filed under: Cotonti Siena CMF Cotonti - reading materials. Documentation.

ПОДРОБНОЕ РУКОВОДСТВО: Как регулировать диапазон лет в датах при редактировании страниц в 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>

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

 

2025-11-21 17:54

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

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

2025-11-16 01:26

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

Only registered users can post new comments
Account