Компания «Карельский разработчик» представляет обновление 0.3.0 «Шуя» для системы управления содержимым «ГИРВАС». Версия сменяет кодовую стадию «Воицы» и получает наименование в честь реки Шуя — одной из крупнейших рек Республики Карелия, берущей начало из озера Суоярви и впадающей в Онежское озеро. Традиция присвоения версиям CMS имён карельских водных объектов подчёркивает региональную принадлежность продукта и его включённость в ландшафт отечественных технологических разработок.
Данный релиз сфокусирован на развитии инструментов навигации по контенту, поисковых возможностей и средств поисковой оптимизации, а также содержит существенные технические усовершенствования ядра системы.
Встроенная поисковая система

Одним из ключевых нововведений версии стала реализация полнотекстовой поисковой системы, функционирующей без использования сторонних сервисов и плагинов.
Поиск выполняется по заголовкам, описаниям, основному содержимому и ключевым словам записей. Реализована логика AND-поиска с автоматическим разбиением запроса на отдельные слова и исключением знаков препинания, что позволяет находить релевантные материалы даже при неточных формулировках. Ранжирование результатов осуществляется на основе настраиваемых весовых коэффициентов: совпадения в заголовках имеют приоритет над совпадениями в теле документа.
В административной панели возможности поиска будут расширены в последующих обновлениях: авторизованные пользователи смогут осуществлять поиск по записям, статическим страницам и пользователям системы.
Архив записей с навигацией по датам
Версия 0.3.0 представляет встроенный архив записей — инструмент для хронологической навигации по контенту.
Функционал автоматически группирует записи по годам и месяцам, отображая количество публикаций для каждого временного интервала. Навигация поддерживает фильтрацию по категориям: пользователь может просматривать как общий архив всех записей сайта, так и архив отдельной категории. Хлебные крошки динамически формируются в зависимости от выбранного периода и категории, обеспечивая удобное перемещение по уровням архива. Страницы архива оптимизированы для поисковых систем — мета-теги формируются автоматически, а URL страниц архива включены в динамическую карту сайта (sitemap).
Иерархия категорий и улучшенная навигация

В обновлении реализована поддержка дочерних категорий с рекурсивным обходом дерева. Страница категории теперь отображает записи с учётом всех вложенных подкатегорий, что обеспечивает более полное представление контента.
Хлебные крошки на страницах категорий и записей отображают полную иерархическую цепочку от корневой категории до текущей позиции. Данное изменение улучшает как пользовательскую навигацию, так и внутреннюю перелинковку сайта для поисковых систем.
Встроенный SEO-анализатор контента

В редактор страниц и записей административной панели интегрирован клиентский SEO-анализатор, работающий без обращения к серверу.
Анализатор выполняет проверку по пяти направлениям: заголовок, мета-описание, ключевые слова, контент и URL. Среди проверяемых параметров — длина и содержание SEO-тегов, вхождение ключевых слов в заголовки, первый абзац и основной текст, корректность иерархии заголовков, наличие alt-текста у изображений, атрибут rel="nofollow" у внешних ссылок, выявление «голых» URL и рекомендации по их оформлению в формате Markdown. Результаты анализа отображаются мгновенно с цветовой индикацией, полосами прогресса и блоком конкретных рекомендаций по улучшению.

Контент-блоки

В административной панели появился новый раздел «Контент-блоки», предназначенный для управления специализированными элементами, встраиваемыми в секции тем оформления без редактирования шаблонов.
Предусмотрена поддержка нескольких типов блоков:
- «Персонализированный» — произвольное содержимое с разметкой Markdown;
- «Кабинет» — мини-профиль пользователя с автоматическим отображением формы авторизации для неавторизованных посетителей;
- «Список категорий» — иерархический перечень всех категорий записей;
- «Пустой» — специализированный тип для интеграции сторонними модулями.
Для каждого блока настраиваются правила отображения через регулярные выражения, применяемые к URL. При совпадении запрошенного адреса с шаблоном блок выводится в соответствующей секции темы.
Технические усовершенствования ядра
Версия 0.3.0 содержит значительные доработки компонента QueryBuilder — внутреннего построителя SQL-запросов:
- Добавлена поддержка JOIN-ов (INNER, LEFT, RIGHT, FULL) с адаптивной генерацией условий для MySQL и PostgreSQL;
- Реализован класс CaseExpression для построения CASE-выражений, включая специализированные методы для JSON-поиска;
- Добавлена полноценная поддержка индексов: создание и удаление с учётом типов
BTREE,HASH,GIST,GIN,SPGIST,BRIN,FULLTEXT, а такжеUNIQUE,CONCURRENTLY,IF NOT EXISTSи частичных индексов с WHERE-условиями.
При установке CMS теперь автоматически создаются оптимизирующие индексы для всех таблиц, включая GIN-индексы для JSONB-полей (PostgreSQL) и частичный индекс для опубликованных записей. Ошибки создания индексов логируются без прерывания процесса установки.
В класс EntryCategory добавлено кеширование инициализированных данных, предотвращающее повторные запросы к базе данных при множественных вызовах метода initData().
Миграция
Обновление файловой системы
Мы настоятельно рекомендуем получать обновление через официальный репозиторий CMS «ГИРВАС». Если Вы его используете по умолчанию, то в корне Вашего проекта выполните консольную команду git pull, предварительно переключившись на ветку production (если ранее использовали другую ветку).
После обновления файловой системы обязательно очистите кэш системы: rm -R ./cache/* (путь может отличаться в зависимости от фактического Вашего расположения в системе).
Миграция базы данных
После успешного обновления файлов CMS необходимо провести миграцию базы данных. Для этого потребуется выполнить несколько SQL-запросов к Вашей базе данных (можно просто скопировать и вставить), в зависимости от вида Вашего СУБД,
Для MySQL
-- Создание таблицы для контент-блоков --
CREATE TABLE IF NOT EXISTS content_blocks (
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
texts JSON,
metadata JSON,
createdUnixTimestamp INTEGER NOT NULL DEFAULT 0,
updatedUnixTimestamp INTEGER NOT NULL DEFAULT 0
);
-- Индексы для таблицы entries
CREATE INDEX idx_entries_category ON entries (categoryID);
CREATE INDEX idx_entries_author ON entries (authorID);
CREATE INDEX idx_entries_created ON entries (createdUnixTimestamp DESC);
CREATE INDEX idx_entries_updated ON entries (updatedUnixTimestamp);
CREATE UNIQUE INDEX idx_entries_name_unique ON entries (name);
-- Индексы для таблицы entries_categories
CREATE INDEX idx_entries_categories_parent ON entries_categories (parentID);
CREATE UNIQUE INDEX idx_entries_categories_name_unique ON entries_categories (name);
-- Индексы для таблицы entries_comments
CREATE INDEX idx_entries_comments_entry ON entries_comments (entryID);
CREATE INDEX idx_entries_comments_author ON entries_comments (authorID);
CREATE INDEX idx_entries_comments_created ON entries_comments (createdUnixTimestamp DESC);
-- Индексы для таблицы pages_static
CREATE UNIQUE INDEX idx_pages_static_name_unique ON pages_static (name);
CREATE INDEX idx_pages_static_author ON pages_static (authorID);
CREATE INDEX idx_pages_static_created ON pages_static (createdUnixTimestamp DESC);
-- Индексы для таблицы users
CREATE UNIQUE INDEX idx_users_login_unique ON users (login);
CREATE UNIQUE INDEX idx_users_email_unique ON users (email);
-- Индексы для таблицы users_sessions
CREATE INDEX idx_users_sessions_user ON users_sessions (userID);
CREATE INDEX idx_users_sessions_token ON users_sessions (token);
-- Индексы для таблицы forms_data
CREATE INDEX idx_forms_data_form ON forms_data (formID);
CREATE INDEX idx_forms_data_created ON forms_data (createdUnixTimestamp DESC);
-- Индексы для таблицы web_channels
CREATE UNIQUE INDEX idx_web_channels_name_unique ON web_channels (name);
-- Индексы для таблицы metrics
CREATE INDEX idx_metrics_date ON metrics (date);
Для PostgreSQL
-- Создание таблицы для контент-блоков --
CREATE TABLE IF NOT EXISTS content_blocks (
"id" SERIAL NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"texts" JSONB,
"metadata" JSONB,
"createdUnixTimestamp" INTEGER NOT NULL DEFAULT 0,
"updatedUnixTimestamp" INTEGER NOT NULL DEFAULT 0
);
-- Индексы для таблицы entries
CREATE INDEX IF NOT EXISTS idx_entries_category ON entries ("categoryID");
CREATE INDEX IF NOT EXISTS idx_entries_author ON entries ("authorID");
CREATE INDEX IF NOT EXISTS idx_entries_created ON entries ("createdUnixTimestamp" DESC);
CREATE INDEX IF NOT EXISTS idx_entries_updated ON entries ("updatedUnixTimestamp");
CREATE UNIQUE INDEX IF NOT EXISTS idx_entries_name_unique ON entries ("name");
CREATE INDEX IF NOT EXISTS idx_entries_texts_gin ON entries USING GIN (texts);
CREATE INDEX IF NOT EXISTS idx_entries_metadata_gin ON entries USING GIN (metadata);
CREATE INDEX IF NOT EXISTS idx_entries_published ON entries ("createdUnixTimestamp" DESC) WHERE (metadata::jsonb->>"isPublished")::boolean = true;
-- Индексы для таблицы entries_categories
CREATE INDEX IF NOT EXISTS idx_entries_categories_parent ON entries_categories ("parentID");
CREATE UNIQUE INDEX IF NOT EXISTS idx_entries_categories_name_unique ON entries_categories ("name");
-- Индексы для таблицы entries_comments
CREATE INDEX IF NOT EXISTS idx_entries_comments_entry ON entries_comments ("entryID");
CREATE INDEX IF NOT EXISTS idx_entries_comments_author ON entries_comments ("authorID");
CREATE INDEX IF NOT EXISTS idx_entries_comments_created ON entries_comments ("createdUnixTimestamp" DESC);
-- Индексы для таблицы pages_static
CREATE UNIQUE INDEX IF NOT EXISTS idx_pages_static_name_unique ON pages_static ("name");
CREATE INDEX IF NOT EXISTS idx_pages_static_author ON pages_static ("authorID");
CREATE INDEX IF NOT EXISTS idx_pages_static_created ON pages_static ("createdUnixTimestamp" DESC);
CREATE INDEX IF NOT EXISTS idx_pages_static_texts_gin ON pages_static USING GIN (texts);
-- Индексы для таблицы users
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_login_unique ON users ("login");
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email_unique ON users ("email");
-- Индексы для таблицы users_sessions
CREATE INDEX IF NOT EXISTS idx_users_sessions_user ON users_sessions ("userID");
CREATE INDEX IF NOT EXISTS idx_users_sessions_token ON users_sessions ("token");
-- Индексы для таблицы forms_data
CREATE INDEX IF NOT EXISTS idx_forms_data_form ON forms_data ("formID");
CREATE INDEX IF NOT EXISTS idx_forms_data_created ON forms_data ("createdUnixTimestamp" DESC);
-- Индексы для таблицы web_channels
CREATE UNIQUE INDEX IF NOT EXISTS idx_web_channels_name_unique ON web_channels ("name");
-- Индексы для таблицы metrics
CREATE INDEX IF NOT EXISTS idx_metrics_date ON metrics ("date");
Заключение
Обновление 0.3.0 «Шуя» для CMS «ГИРВАС» объединяет развитие пользовательских инструментов навигации и поиска с глубокой технической модернизацией ядра. Мы рекомендуем всем пользователям выполнить обновление, чтобы оценить возросшие возможности поиска, удобство архивации контента и новые инструменты поисковой оптимизации.
Комментарии