Это руководство поможет вам настроить красивые URL для разделов, тем и сообщений форума Cotonti. В результате получаются читабельные адреса, которые смело можно отдавать в индексацию поисковым системам, запрещая мусор в виде /*?* или /*&*
Это руководство поможет вам настроить красивые URL для разделов, тем и сообщений форума Cotonti, например:
https://mycotonti.local/forums/cat-some-code-alias (список тем раздела)https://mycotonti.local/forums/cat-some-code-alias/topic123 (тема)https://mycotonti.local/forums/cat-some-code-alias/post456 (сообщение)https://mycotonti.local/forums/cat-some-code-alias/topic123/page2 (пагинация темы)
1. Подготовка
- Включён плагин urleditor (стандартный плагин для ЧПУ).
- Файл
.htaccess в корне сайта настроен на поддержку ЧПУ (есть правила перезаписи). - Вы имеете доступ к файлам сервера (FTP или файловый менеджер).
2. Настройка .htaccess
Файл .htaccess должен содержать базовые правила Cotonti, а также наши дополнительные правила для форума. Убедитесь, что у вас есть что-то похожее на приведённый ниже блок (это стандартные правила, которые уже могут быть в вашем .htaccess). Мы добавим в него кастомные правила для форума.
Расположение: корневая папка сайта (там, где находится index.php).
Содержимое (важные части):
# Rewrite engine options
Options -Indexes
RewriteEngine On
# Принудительное перенаправление на HTTPS и удаление www (опционально)
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
# 301 редиректы (если есть) – оставьте свои
RewriteBase "/"
# Language selector (если используется мультиязычность)
RewriteRule ^(en|ru|de|pl|ua)/(.*) $2?l=$1 [QSA,NC,NE,DPI]
# Sitemap shortcut
RewriteRule ^sitemap\.xml$ index.php?r=sitemap [L]
# Admin area and message
RewriteRule ^admin/([a-z0-9]+) admin.php?m=$1 [QSA,NC,NE,L]
RewriteRule ^(admin|login|message)(/|\?|$) $1.php [QSA,NC,NE,L]
# System category
RewriteRule ^system/?$ index.php?rwr=system [QSA,NC,NE,L]
# ========== НАЧАЛО: ПРАВИЛА ДЛЯ ФОРУМА ==========
# Темы (посты) с пагинацией
RewriteRule ^forums/([a-zA-Z0-9_./%-]+)/topic([0-9]+)/page([0-9]+)?$ index.php?e=forums&m=posts&q=$2&d=$3 [QSA,NC,NE,L]
RewriteRule ^forums/([a-zA-Z0-9_./%-]+)/topic([0-9]+)?$ index.php?e=forums&m=posts&q=$2 [QSA,NC,NE,L]
# Конкретные сообщения (по id)
RewriteRule ^forums/([a-zA-Z0-9_./%-]+)/post([0-9]+)?$ index.php?e=forums&m=posts&id=$2 [QSA,NC,NE,L]
# Список тем раздела с пагинацией (важно: сначала правило с пагинацией, потом без)
RewriteRule ^forums/([a-zA-Z0-9_./%-]+)/([a-zA-Z0-9_%-]+)/page([0-9]+)?$ index.php?e=forums&m=topics&s=$2&d=$3 [QSA,NC,NE,L]
RewriteRule ^forums/([a-zA-Z0-9_./%-]+)/([a-zA-Z0-9_%-]+)/?$ index.php?e=forums&m=topics&s=$2 [QSA,NC,NE,L]
# Отдельный раздел (корневой или вложенный) – здесь важно: используем m=topics&s=...
RewriteRule ^forums/([a-zA-Z0-9_%-]+)/?$ index.php?e=forums&m=topics&s=$1 [QSA,NC,NE,L]
# Главная страница форума
RewriteRule ^forums/?$ index.php?e=forums [QSA,NC,NE,L]
# ========== КОНЕЦ: ПРАВИЛА ДЛЯ ФОРУМА ==========
# All the rest goes through standard rewrite gateway
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]+) index.php?rwr=$1 [QSA,NC,NE,L]
Пояснения:
- Правила расположены в порядке от более специфичных к менее специфичным.
- Паттерн
[a-zA-Z0-9_./%-]+ позволяет использовать точки (для вложенности) и слэши. - Для раздела мы используем
m=topics&s=..., чтобы загружался список тем (файл forums.topics.php), а не список подразделов. - Сохраните изменения и убедитесь, что сервер поддерживает
.htaccess.
3. Создание функции forums_url_structure()
Cotonti позволяет создавать кастомные функции для генерации URL через плагин urleditor. Мы создадим функцию, которая будет возвращать путь к разделу на основе его кода.
Расположение: файл /system/functions.custom.php. Если его нет – создайте.
Содержимое (добавить в конец файла):
<?php
defined('COT_CODE') or die('Wrong URL');
/**
* Генерирует ЧПУ-путь для форума на основе структуры категорий.
* Используется в правилах urleditor.
*
* @param array $args Параметры вызова (например, m=topics, s=...)
* @return string Путь (например, "e-mobility-scooter" или "parent/child")
*/
function forums_url_structure(&$args)
{
global $structure;
$script = 'forums';
$replacement = '';
// Обрабатываем список тем (m=topics)
if (isset($args['m']) && $args['m'] === 'topics') {
if (isset($args['s'])) {
// Получаем путь категории, заменяем точки на слэши
$replacement = str_replace('.', '/', $structure['forums'][$args['s']]['path'] ?? '');
if (isset($args['d'])) {
$replacement .= '/page' . (int)$args['d'];
}
// Удаляем использованные параметры, чтобы они не попали в URL
unset($args['d'], $args['s']);
} else {
$replacement = $script;
}
}
// Обрабатываем просмотр темы (m=posts)
elseif (isset($args['m']) && $args['m'] === 'posts') {
global $db, $db_forum_posts;
if (isset($args['q'])) {
$topicId = (int)$args['q'];
$page = isset($args['d']) ? (int)$args['d'] : 0;
// Получаем категорию темы
$cat = $db->query("SELECT fp_cat FROM $db_forum_posts WHERE fp_topicid = ? LIMIT 1", [$topicId])->fetchColumn();
if ($cat !== false && isset($structure['forums'][$cat])) {
$replacement = str_replace('.', '/', $structure['forums'][$cat]['path']) . '/topic' . $topicId;
if ($page > 0) {
$replacement .= '/page' . $page;
}
} else {
$replacement = $script;
}
unset($args['d'], $args['q']);
} elseif (isset($args['id'])) {
$postId = (int)$args['id'];
// Получаем категорию поста
$cat = $db->query("SELECT fp_cat FROM $db_forum_posts WHERE fp_id = ? LIMIT 1", [$postId])->fetchColumn();
if ($cat !== false && isset($structure['forums'][$cat])) {
$replacement = str_replace('.', '/', $structure['forums'][$cat]['path']) . '/post' . $postId;
} else {
$replacement = $script;
}
unset($args['id']);
} else {
$replacement = $script;
}
unset($args['m']);
}
// Если не подошло, возвращаем просто "forums"
else {
$replacement = $script;
}
return $replacement;
}
Пояснения:
- Функция получает массив параметров
$args и может изменять его (удаляя использованные). - Для списка тем (
m=topics) она возвращает путь раздела, заменяя точки на слэши (например, forums.cat-some-code-alias → cat-some-code-alias). - Для темы (
m=posts&q=...) – путь раздела + /topic{id}. - Для отдельного сообщения (
m=posts&id=...) – путь раздела + /post{id}. - Если параметр
d (страница) задан, добавляет /page{номер}. - Все лишние параметры удаляются из
$args, чтобы они не попали в URL.
Важно: Убедитесь, что глобальная переменная $structure уже загружена (она загружается в functions.php). Если функция вызывается до загрузки структуры, можно вызвать cot_load_structure() в начале функции, но обычно $structure уже доступна.
4. Настройка плагина urleditor
Плагин urleditor использует файлы пресетов (например, marketplace.dat) для определения правил генерации URL. Мы добавим правила для форума.
Расположение:/plugins/urleditor/presets/marketplace.dat (если файла нет – создайте).
Содержимое (добавить или заменить секцию forums):
# ========== ФОРУМ ==========
# Пагинация темы
forums m=posts&q=&d= forums/{forums_url_structure()}/page{$d}
# Ссылка на тему
forums m=posts&q=* forums/{forums_url_structure()}
# Ссылка на конкретное сообщение
forums m=posts&id=* forums/{forums_url_structure()}
# Пагинация списка тем
forums m=topics&s=&d= forums/{forums_url_structure()}/page{$d}{!$m}
# Ссылка на раздел (список тем)
forums m=topics&s=* forums/{forums_url_structure()}{!$m}
# Ссылка на раздел через параметр c (для обратной совместимости, можно удалить)
forums c=* forums/{$c}
# Главная страница форума
forums * forums
Пояснения:
{forums_url_structure()} – вызов нашей кастомной функции.{!$m} – подавляет вывод параметра m (чтобы не было дублирования).- Порядок строк важен: более конкретные правила идут выше.
- Если вы не хотите поддерживать старый формат
c=..., можно удалить строку forums c=* forums/{$c}.
5. Очистка кэша и проверка
После внесения всех изменений выполните следующие шаги:
- Очистите кэш urleditor:
- В админ-панели Cotonti перейдите в Плагины → urleditor.
- Нажмите кнопку Очистить кэш (или выполните SQL запрос:
TRUNCATE cot_urltrans).
- Очистите кэш страниц (если используется):
- В админ-панели: Настройки → Система → Кэш → Очистить кэш.
- Проверьте работу:
- Откройте главную страницу форума:
https://mycotonti.local/forums – должна работать. - Перейдите в любой раздел:
https://mycotonti.local/forums/cat-some-code-alias – должен отобразиться список тем. - Откройте любую тему:
https://mycotonti.local/forums/cat-some-code-alias/topic123 – должны показаться сообщения. - Проверьте пагинацию:
https://mycotonti.local/forums/cat-some-code-alias/topic123/page2. - Убедитесь, что ссылки на сообщения и темы в шаблонах формируются правильно (используют новые URL).
- Если что-то не работает:
- Проверьте права на файлы
.htaccess (должен быть разрешён перезапуск). - Проверьте, что модуль mod_rewrite включён на сервере.
- Убедитесь, что функция
forums_url_structure() не содержит ошибок (проверьте логи PHP). - Убедитесь, что структура форума загружена в глобальной переменной
$structure (должна быть доступна во всех частях системы).
6. Дополнительные советы
- Если у вас мультиязычный сайт и языковой префикс (en, ru и т.д.) обрабатывается в
.htaccess, то правила для форума должны быть расположены после правила RewriteRule ^(en|ru|de|pl|ua)/(.*) $2?l=$1 [QSA,NC,NE,DPI]. Это обеспечит корректную обработку языковых префиксов. Если вы используете вложенные разделы (например, forums.cat-some-code-alias), наша функция заменит точки на слэши, создав URL вида /forums/forums/cat-some-code-alias? Нет, потому что $structure['forums'][$s]['path'] возвращает полный путь с точками, но мы заменяем только точки на слэши. Однако если у вас корневой раздел имеет путь forums, то он не должен попадать в URL. Чтобы избежать дублирования, убедитесь, что в структуре форума первый уровень называется просто forums (или что-то другое), но в URL мы хотим видеть только имя раздела, без forums/. В нашей функции мы возвращаем именно str_replace('.', '/', ...), что для вложенных разделов даст родитель/ребёнок, что правильно. Если же в пути есть префикс forums, он тоже превратится в слэш, что нежелательно. Рекомендуется в структуре форума для корневых разделов использовать имена без префикса forums (например, cat-some-code-alias), тогда путь будет cat-some-code-alias, а не forums/cat-some-code-alias. Если же у вас уже есть точки в путях, то убедитесь, что функция возвращает то, что нужно. В нашем примере мы предполагаем, что путь раздела – это forums.cat-some-code-alias – тогда замена точек даст forums/cat-some-code-alias. Чтобы убрать forums/, можно модифицировать функцию:
$path = $structure['forums'][$args['s']]['path'] ?? '';
$path = str_replace('.', '/', $path);
$path = preg_replace('#^forums/?#', '', $path); // удаляем начальное "forums/"
$replacement = $path;
но делать так не стоит, - это чисто в образовательных целях
Но лучше в админке структуры форума задать пути без лишних префиксов.
- Если после всех настроек ссылки всё ещё генерируются с параметрами
?e=forums&m=topics&s=..., значит, urleditor не срабатывает. Проверьте, включён ли плагин, и очищен ли его кэш.
7. Заключение
Теперь ваш форум использует красивые ЧПУ-ссылки, которые удобны для пользователей и поисковых систем. При необходимости вы можете расширить правила для других модулей аналогичным образом. Удачи!