Обновить
16K+

CMS *

Системы управления сайтом

7,14
Рейтинг
Сначала показывать
Порог рейтинга

Многие знают ныне заброшенный проект CMS Livestreet.

Не знаю какая муха меня укусила, но я его полностью переписываю на Yii 3 Кому интересно, отзовитесь.

Собрал все недочеты и хотелки по данному проекту:

План работ: Переписывание LiveStreet на Yii 3

Цель: Создать современную, безопасную и расширяемую блого-социальную CMS, избегая фатальных ошибок LiveStreet (устаревший стек, дыры в безопасности, платные must-have плагины).

Этап 0: Фундамент и безопасность (P0)

  • Стек: PHP 8.1+, Yii 3 (пакетная архитектура), Cycle ORM, Composer. Весь код приложения строго вне директории public/.

  • Безопасность: Хеширование argon2id, санитизация через HTMLPurifier, строгие CSRF-токены в POST, Rate-limit авторизации. Инсталлятор и миграции выполняются только через CLI.

  • Архитектура: PSR-12, строгая типизация, DI-контейнер (yiisoft/di). Полный отказ от синглтонов, глобального состояния и самописных фреймворков в public.

Этап 1: Ядро и администрирование (P0)

  • Админка: Встроена в ядро (не плагин!). Управление пользователями, RBAC, логами, SEO и запуск миграций в один клик.

  • Контент: Поддержка кастомных типов контента (блоги, топики, страницы) из коробки, без необходимости покупать аддоны.

  • Медиа: Встроенная Media Library с индексом использования файлов, поддержкой S3/CDN и генерацией превью.

  • БД: Официальная поддержка MySQL 8 и PostgreSQL с первого дня разработки.

Этап 2: Социальный функционал и API (P1)

  • API: REST/OpenAPI с версии 1.0 (аутентификация по токенам, автодокументация).

  • Социалка: Встроенные модули (с флагами включения): рейтинги/карма, система жалоб, @mentions, личные сообщения, уведомления (email + in-app), подписки.

  • Производительность: Redis для инкрементальных счетчиков, очереди для тяжелых задач, eager-loading в ORM для полного устранения проблемы N+1 запросов.

Этап 3: Экосистема и миграция (P1)

  • Плагины: Установка через Composer или UI админки. Строгий semver, декларация зависимостей (require/conflict), собственные миграции и фикстуры в пакетах.

  • Миграция данных: Написание CLI-импортера для бесшовного переноса пользователей, топиков, блогов и комментариев из LS 1.0.3 и 2.x.

  • SEO: Генерация единого canonical URL на сущность, встроенный модуль sitemap, Open Graph и JSON-LD из коробки.

Этап 4: Опциональные модули (P2)

  • Real-time обновления (WebSocket/Mercure), PWA, OAuth-авторизация, Markdown-редактор, мультиязычность контента (yiisoft/translator), биллинг-модуль (подписки/донаты как опция, а не обязательная функция).

🚫 Главное правило проекта: Никаких платных must-have функций (админка, ЧПУ, базовый API, типы контента, жалобы). Именно монетизация базового функционала через платные плагины убила экосистему LiveStreet. Ядро должно быть самодостаточным.

Теги:
+4
Комментарии3

Много лет висело без откликов у меня на hh.ru резюме на вакансию «Web-реаниматор старых сайтов» и вдруг прилетела «подработка»…

У небольшой организации занимающейся разработкой очень специфичной техники есть в интернете несколько информационных сайтов на Joomla 3 и уже года 4 без каких-либо изменений, и, соответственно без необходимости иметь сотрудника для их поддержки.
И что примечательно, у этих сайтов в среднем около 1 посещения в неделю..

Но месяц назад на двух сайтах вдруг появились вместо заглавных страниц сообщения «Взломан CoupDeGrace» и «Взломан ANTONKILL».
Так у меня появилась хоть какая-то работа за последние 4 года.
Убрать заставки взломщиков оказалось достаточно просто, сложнее перекрыть дальнейшие возможности для подобных хулиганств – не представляю как удалить из работающего сайта модули Helix и Sppagebuilder, через которые происходит основной вход «хулиганов»… частично их «деактивировал».  Но наверняка есть и другие способы, про которые я тогда не знал.
Обновлять Joomla до актуальной версии занятие долгое и непредсказуемое, а потому один сайт остался жить просто почищенным от заставок «Взломан …», а их там оказалось несколько десятков, а другой достаточно быстро перелопачен в статичные html страницы.
Первый этап «реанимации» закончен и очень постепенно начался второй – поиск нового движка для сайтов. Желательно отечественного производства, с активной поддержкой, чётким MVC, а ещё и бесплатным… в общем – проблематичные условия, но несколько кандидатов нашлось, и даже лидер образовался с самым маленьким количеством проблем на входе.

Но опять возникло «НО»!
Тот сайт, что остался крутиться на Joomla был заселён несколькими бэкдорами и это обнаружилось совершенно случайно только потому, что развили очень активную деятельность и буквально подвесили виртуальный сервер с очень скромными ресурсами.

За прошедшие выходные я понял, что мои возможности уже сильно устарели и резюме на вакансию «Web-реаниматор» надо бы убрать…
Мало того, что «искусство обфусцирования» вышло за уровни моего понимания, но как можно перехватывать пересылаемый по ftp на сайт index.php и класть его в корень с уже вписанным «вирусом» - мне уже видимо не осознать.

В прошлом году на секции «Слабое звено ИБ» один выступающий рассказал о своём эксперименте по «взлому» - всего $10 долларов на оплату токенов и ВСЁ!
Про миллион за взлом «белым хакерам» можно забыть – нейросети обесценили труд этих специалистов на несколько порядков.

Любая известная и популярная CMS со средствами «web-администрирования» и самообновления уже имеет в себе «парадные ворота» для взлома и заселения всем чем захочется.

На мой «устаревший» взгляд, самым эффективным вариантом решения проблемы для подобных информационных сайтов, мне видится CMS с полным функционалом по управлению сайтом на локальном компьютере, а в «публичное пространство» выгружаются только html страницы. И только 555 для папок и 444 для файлов.

А может не всё так грустно?
Может есть уже простые решения, про которые всем кроме меня всё давно известно?

 

Теги:
+7
Комментарии5

Переопределение макета НЕ в шаблоне Joomla.

Мы все знаем, что при работе с сайтом создание своих переопределений стандартных макетов — это типовая, стандартная работа. Она позволяет сделать из материалов, контактов почти всё, что угодно.

И так же мы знаем, что по классике эти переопределения кладутся в папку html активного шаблона Joomla (не важно, для админки или для пользовательской части).
Макет blog.php и blog.xml к нему из JPATH_SITE/components/com_content/tmpl/category/ мы помещаем в templates/<ВАШ_ШАБЛОН>/html/com_content/category и творим там всё, что захотим:

  • любая вёрстка в blog.php и субмакетах

  • любое название для типа пункта меню (гаражи, дачи, самолёты — каталог чего вы делаете на материалах) — в blog.xml (или samolet.php + samolet.xml).

  • любые дополнительные параметры для пункта меню на этот тип — добавьте нужные кнопки и инпуты в blog.xml

Да, это всё классика. Удобно то, что мы создаём нужный нам тип пункта меню таким образом и можем выбрать его в админке: список самолётов, список гаражей.

Если наше переопределение лежит в шаблоне, то URL при создании пункта меню будет вида index.php?option=com_content&view=category&layout=yourtemplate:samolet.

Именно так, через двоеточие: layout=yourtemplate:samolet. Joomla будет знать, что нужно залезть в нужный шаблон и взять нужное переопределение. Если мы НЕ создаём свой тип пункта меню таким образом, а просто переопределяем — то всё ок.

❓ А что будет с сайтом, если мы переключили шаблон на другой?

На старых долгоживущих проектах нередко структура пунктов меню большая и запутанная. Если мы сделали новый шаблон сайта и переключили его в админке — у нас послетают все наши переопределения. И они не будут работать до тех пор, пока мы не прощёлкаем все пункты меню и не пересохраним их. Так, чтобы в их url теперь был new-template:samolet в параметре layout.

И тут мне вспомнился механизм работы с макетами в модулях, где мы можем положить свой макет как в папку с модулем. так и в папку с переопределением. В обоих случаях мы можем его использовать.

Если макет лежит в папке с модулем.

  • Он работает

  • Его можно переопределить в шаблон (хотя зачем, это же наш макет)

  • Он не изменится при смене шаблона

  • ⛔️ Минус — неудобно в работе, когда все макеты разложены по своим модулям и нужно прыгать по папкам в проекте

Макеты лежат в папке html шаблона.

  • всё рядышком

  • типовой подход Joomla (хотя и предыдущий тоже типовой)

  • удобно для типовых шаблонов — сделал комплект переопределений в своём шаблоне и таскаешь из проекта в проект

  • ⛔️ неудобно, когда впереди большая работа по смене шаблона и нельзя, чтобы сразу послетало всё из‑за смены шаблона.

Я решил провести мини‑эксперимент, в целом заранее зная его результат: положить «переопределение» материала не в html/com_content шаблона, а в папку с компонентом. Точь‑в-точь как с модулями.

Оно работает. Мы создаём собственный тип вывода контента, не привязанный к конкретному шаблону. URL нашего пункта меню будет без двоеточия и имени шаблона. Просто index.php?option=com_content&view=category&layout=samolet.

И знаете, это повод задуматься о применении этой возможности, хотя раньше я бы первым закричал: «Вы что‑о-о?!?! Нельзя‑а-а!»

Когда у нас проект, где:

  • не сложная структура

  • переопределения макетов в шаблоне делаются один раз на несколько лет.

  • их (переопределений и новых типов пунктов меню) МАЛО...

..здесь положить всё в шаблон сам Бог велел.

Когда же:

  • сложная структура меню

  • в ней много разных ТИПОВ пунктов меню

  • и все они норовят зависеть от шаблона...

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

Риски есть — когда‑нибудь кто‑нибудь добавит в ядро файл с совпадающим именем. Но это решается брендированным префиксом в именах файлов.

При обновлении эти файлы не затираются — проверил сценарий обновления.

🤔 В общем, это скорее философские вопросы о разграничении ответственности и кто эту ответственность на себя берёт, кто это будет поддерживать, документировать и следить за тем, чтобы практике проекта следовали коллеги.

Теги:
+3
Комментарии0

Совет по Joomla: Как сделать ссылки на списки сущностей Joomla с фильтрацией?

Стандартная форма фильтрации в админке Joomlа
Стандартная форма фильтрации в админке Joomlа

В Joomla в любом списке сущностей есть параметры поиска, которыми мы привыкли пользоваться руками в админке. Но что если вам нужно сделать ссылку на список в админке с заранее заданными параметрами фильтрации?

Например:

  • разработчик хочет дать ссылку на плагин для быстрого перехода к настройкам;

  • разработчик хочет в документации для контент-менеджера дать ссылку на нужные модули, плагины, о которых идёт речь;

Админка Joomla поддерживает фильтры в URL-адресе, а названия GET-параметров для фильтрации можно посмотреть в названиях полей фильтров админки.

Например, в списке плагинов поле фильтра:

  • выбор состояния - filter[enabled]=1 или 0

  • выбор типа (группа плагинов) - filter[folder]={название группы плагина, например content или system}

  • element плагина (уникальное систеное имя) - filter[element]={element}

  • уровень доступа, с которым работает плагин - filter[access]={числовой-код-уровня-доступа}

  • строка поиска - filter[search]={любой%20текст%20для%20поиска}

Таким образом, чтобы дать ссылку на свой плагин в админке можно сделать следующий url:

https://your-joomla-site.ru/administrator/index.php?option=com_plugins&view=plugins&filter[element]=wtotpravkapochtaru&filter[folder]=system

Аналогичным образом работает список модулей, контактов, материалов и т.д. Найти имена параметров можно либо в HTML-коде страницы, либо в XML-форме опций фильтра нужного компонента. Для списка плагинов используется компонент com_plugins, а форма фильтра лежит в administrator/components/com_plugins/forms/filter_plugins.xml. Для списка материалов Joomla - в administrator/components/com_content/forms/filter_articles.xml. Другие компоненты - ищем по анналогии.

Чат русскоязычного Joomla-сообщества в Telegram и в Max.

Теги:
+3
Комментарии0

WT Max v.0.2.0. - библиотека для интеграции с Joomla

Обновление Joomla-библиотеки для API мессенджера MAX с системным плагином для настроек и диагностики подключения. Библиотека предназначена для разработчиков.

Расширение является Joomla-обёрткой над самостоятельным PHP Composer-пакетом Webtolk\Max, у которого так же состоялся релиз 0.2.0. PHP SDK разрабатывалось с учётом стандартов PSR и полностью не зависит от какого-либо фреймворка и/или пакета.

v.0.2.0. Что нового?

  • Подключена новая версия API-хоста: platform-api2.max.ru. Для корректной работы ваших чат-ботов и мини-приложений до 19 июля 2026 необходимо перенаправить HTTP-запросы с домена platform-api.max.ru на platform-api2.max.ru, а также добавить сертификат Минцифры в список доверенных. Как это сделать - ссылка на инструкция внизу поста. ‼️Если этого не сделать - вы получите уведомление об ошибке соединения и неверном сертификате.

  • Расширена публичная API-поверхность. Обновлены и дополнены методы для работы с чатами и сообщениями (включая новые сценарии по ссылкам на чат и выборке по query-id сообщения). Удалены устаревшие методы.

  • Обновлён набор публичных JSON-схем. Добавлены и синхронизированы схемы для новых и изменённых endpoint-ов. Эти схемы - снимки реальных ответов API Max, так как мы прекрасно знаем, что документация и реальное API может отличаться порой очень и очень значительно.

  • Обновление документации. README, стартовые руководства, референсы и описания сущностей/пэйлоадов приведены к текущему API-уровню.

Ссылки:

Теги:
Всего голосов 3: ↑2 и ↓1+3
Комментарии0

Задачка поиска CMS для статического веб сайта.

Для формирования этого отчета я попросил агента opencode (модель qwen3.6-35b-a3b) сначала поискать на github используя api и погуглить (api tavily) проекты под задачу и составить csv файл, затем другим агентом заставил работать с этим файлом построчно (искать строки без пометки ‘принят’, в соответствующей колонке) и для каждого в цикле запускать отдельного агента на исследование github соответствующего проекта, подходит он или нет.

Агент самостоятельно понял что часть проектов по короткому описанию не подходят, так и сказал, это сэкономит токены на исследования (мне пофиг, модель локально запущена но приятно). Задача решилась не сразу (примерно за пол часа с моим участием), так как я провожу эксперименты с агентом со слабой моделью, на которой можно отловить большую часть их проблем, но формально ничто не мешает повторить это самостоятельно. Основная задача при работе с агентами, не доверять им информацию, списки, данные и прочее, пусть хранят в файлах и работают с ними по детерменированным правилам, и даже при подробных инструкциях, норовят схалтурить и работать с данными как человек.

Потом отдельно попросил сформировать этот список.

Проект Stars Forks Last Update

  • decap-cms (decaporg/decap-cms) 19,130 3,119 2026-06-08

  • Grav CMS (getgrav/grav) 15,511 1,411 2026-06-08

  • Front Matter CMS (estruyf/vscode-front-matter) 2,516 104 2026-06-05

  • HTMLy (danpros/htmly) 1,339 301 2026-01-25

  • Automad (marcantondahmen/automad) 901 52 2026-06-07

  • WonderCMS (WonderCMS/wondercms) 727 165 2026-01-01

  • Typemill (typemill/typemill) 597 72 2026-05-27

  • static-cms (StaticJsCMS/static-cms) 593 47 2026-06-05

  • FlatPress (flatpressblog/flatpress) 209 65 2026-06-07

  • Quiqr Desktop (quiqr/quiqr-desktop) 170 11 2026-05-01

  • barnacle (dporkka/barnacle) 1 0 2026-06-04

  • dir2site (EvanRuiz/dir2site) 1 0 2026-05-21

  • beta.vortex.name (0-vortex/beta.vortex.name) 1 0 2025-03-03

  • Editora (MrGKanev/Editora) 1 0 2026-05-26

  • Academic-website (denis-novega/Academic-website) 0 0 2026-05-17

  • primo (irismetric/primo) 0 0 2024-05-01

  • fieldscms (unculturedswine/fieldscms) 0 0 2026-02-16

  • taboola/decap-cms (taboola/decap-cms) 0 0 2024-07-02

Полный отчет

Теги:
Всего голосов 3: ↑2 и ↓1+4
Комментарии2

Стоит ли садиться в 2026 за разработку своей CMS?

Не так давно я писал несколько постов о своем opensource движке, при помощи которого можно вести свой блог. И естественно мне за это навтыкали в комментариях, мол - какая нахрен CMS в 2026 году? Кому она вообще нужна?

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

Главное - чтобы эта CMS имела систему событий и хуков под капотов - чтобы при разработке своего плагина или контроллера можно было легко прицепиться к сущностям движка.

Недавно обратился ко мне старый клиент, которому в далеких лохматых годах делал сайт еще на джумле. Мол - сейчас есть сайт - на Тильде, современный, красивый, но - нефункциональный. Спасай-выручай, надо перенести с Тильды на какую-нибудь крутилку.

Перенес. Написал пару контроллеров. Дизайн сохранил в исконном виде (пришлось правда переписывать весь ужасный инлайн-css от тильды). Но - клиент доволен, что теперь все круто, и не нужно ежемесячно платить за хостинг Тильды (зато нужно платить целых 99 рублей за хостинг для текущего сайта).

Так вот к чему я? Прежде чем переносить сайт с тильды - я перелопатил штук 15 действующих CMS, на которых сейчас клепают сайты - включая всем известный WP и менее известную InstantCms. И ни один двиг не дал того, что мне было нужно.

А задача у меня была тривиально простая - чтобы в админке я создал несколько сущностей (например слайдер, услуги, отзывы) - и разметил все это стандартными шортокдами системы, чтобы вывести на фронт.

Ни один движок этого не дает. (Ну или может я плохо искал).

Тут конечно я должен подвести к своей CMS - а вот моя так умеет! Пользуйтесь!

Сейчас вы подумаете: «Ага, сейчас он начнет впаривать свою CMS!» А вот нет. Не буду.

Потому что вопрос реально открытый: а нужна ли своя CMS в 2026 году? Или проще наваять на php под конкретного клиента мини-админку для управления сайтом-визиткой?

Теги:
Всего голосов 3: ↑2 и ↓1+1
Комментарии21

BloggyCms v1.0.0-rc.4

Наконец-то спустя почти год и два месяца моя CMS-ка для ведения блога получила более менее внятный релиз-кандидат, в котором ошибок осталось не так много, и в принципе система уже легко ставится на хостинг и управляется.

Дашборд системы
Дашборд системы

Впереди - куча оптимизации, например вынесение всех форм шаблона админки в контроллеры, и последующий их рендеринг через render_form(). Данные контроллеров в json и так далее.

Но - текущая версия движка с последующими обновлениями уже не сломается, как это было в первых релизных версиях.

Ну и самое главное - официальный сайт. Как оказалось - это одна из тех задач, которая весьма объемна и кропотлива - это и документация, и каталог дополнений с API для разработчиков и еще много-много чего.

Приглашаю к тестированию: https://github.com/pechoradev/BloggyCms

Также буду рад видеть новых контрибьюторов CMS.

Теги:
Всего голосов 4: ↑3 и ↓1+2
Комментарии24

Мультиязычность. Ад для разработчика.

Сейчас для моего движка понадобилась мультиязычность. Ну как понадобилась - на гитхабе прозрачно намекнули, что негоже одной гордой cms для ведения блога быть сугубо на русском языке.

И понеслась...

Процесс перевода движка
Процесс перевода движка

Это хорошо, что сейчас есть нейросети и они здорово упрощают процесс перевода. Но - по старинке все делаю вручную, каждый файл...Сначала размечаю обыкновенными дефайнами либо класс контроллера, либо шаблона, ну а потом выношу это все в соответствующие языковые папки.

Вайбкодеры меня наверняка закидали бы тапками, мол - все можно автоматизировать и перевести хоть тонну файлов за 20 минут. Но - мне это не в кайф =)

Кто хочет помочь в процессе перевода, а заодно и движок потестить - милости прошу: https://github.com/pechoradev/BloggyCms

Теги:
Всего голосов 3: ↑3 и ↓0+3
Комментарии21

WT CDEK library v.1.3.0 - обновление PHP SDK для Joomla + CDEK.

Небольшая нативная PHP Joomla библиотека для работы с API v.2 службы доставки CDEK. Библиотека представляет собой клиент для авторизации в CDEK API по OAuth, работы с некоторыми методами API: получения ряда данных и расчета стоимости доставки. Поддерживается Joomla 4.2.7 и выше.

В пакет входят:

  • библиотека Webtolk/Cdekapi

  • системный плагин System — WT Cdek для хранения настроек и AJAX‑интеграций

  • task‑плагин Task — Update WT Cdek data для обновления локальных копий справочников CDEK по расписанию

  • web asset с официальным JavaScript‑виджетом СДЭК

👉 v.1.3.0. Что нового?

  • Полный рефакторинг библиотеки. Библиотека переработана в entity‑based API с фасадом Cdek и отдельным слоем запросов. Обратная совместимость не нарушена, поэтому версия библиотеки — 1.3.0.

  • Добавлена поддержка новых разделов API СДЭК. Добавлена поддержка новых разделов API СДЭК: webhooks, prealert, печатные формы, payment, passport, reverse, intakes и других сущностей.

  • Улучшена интеграция с Joomla. Улучшена интеграция с Joomla: installer script для layouts, новые поля Joomla Form для тарифов и обновлённые js виджета CDEK.

  • документация библиотеки. Все методы библиотеки подробно описаны, а так же текст документации собран в отдельной папке в git репозитории.

Пример запроса — запрос информации о городе.

<?php

use Webtolk\Cdekapi\Cdek;

\defined('_JEXEC') or die;

// Вариант 1: брать credentials из настроек плагина
$cdek = new Cdek();

// Вариант 2: передать credentials явно
$cdek = new Cdek(test_mode: true, client_id: 'your_client_id', client_secret: 'your_client_secret');

$result = $cdek->location()->getCities([
    'postal_code' => '410012',
    'city'        => 'Саратов',
    'size'        => 1,
]);

Результат запроса:

Array
(
    [0] => Array
        (
            [code] => 428
            [city_uuid] => 7e54a0b3-76f0-41e2-92e0-f1e600ad84fd
            [city] => Саратов
            [fias_guid] => bf465fda-7834-47d5-986b-ccdb584a85a6
            [country_code] => RU
            [country] => Россия
            [region] => Саратовская область
            [region_code] => 47
            [fias_region_guid] => df594e0e-a935-4664-9d26-0bae13f904fe
            [sub_region] => городской округ Саратов
            [longitude] => 46.034266
            [latitude] => 51.533562
            [time_zone] => Europe/Saratov
            [payment_limit] => -1
        )

)

Библиотека эта нужна для разработчиков, создающих свои расширения для интеграции Joomla и курьерской службы CDEK.

Страница расширения

GitHub расширения

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

Особенность Joomla: json-значения для пользовательских полей и их рендер в subform и вне дочерней формы.

Опять длинное название, но куда уж без этого...

Итак, если вы делаете плагин пользовательского поля - его можно использовать через FieldsHelper. И в процессе ваши данные проходят через различные этапы обработки (недавно была статья на эту тему). И может так оказаться, что ваше поле хранит в rawvalue json (и в базе данных соответственно тоже), а в value вы на его основе рендерите значение. Это стандартный подход Joomla. Так работают, например, поля accessiblemedia. Однако, если вы поместили ваше поле в дочернюю форму (пользовательское поле типа subform и включили "Рендеринг значений = Да", то у вашего замечательного поля может появиться поломанный Json в value вместо нормального значения.

Например:

{&quot;basePath&quot;:&quot;...&quot;,&quot;layout&quot;:&quot;...&quot;}

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

  1. В обычном потоке Joomla сначала вызывает событие onCustomFieldsBeforePrepareField, а потом onCustomFieldsPrepareField.

  2. Внутри subform же для подполей при render_values=1 вызывается только событие - onCustomFieldsPrepareField.

  3. Если преобразование значения (например, json_decode) сделано в вашем плагине только в beforePrepareField, оно не обработает данные для подполя и...

  4. В шаблоне поля строка заэкранируется (htmlentities), кавычки превратятся в тыкву в &quot; и вы получите кривой json, вместо вашего значения.

👉 Собственно полезный совет по Joomla:

Для полей, которые могут жить внутри subform, делайте нормализацию значения и в onCustomFieldsPrepareField тоже, не только в beforePrepareField.

Теги:
Рейтинг0
Комментарии0

Как понять, что ваш интернет-магазин вот-вот сломается: триггеры и решения для сайтов на Magento

Привет! Это Дмитрий Абакумов magento-разработчик в Далее, и Максим Бровко, тимлид в Далее.

Мы собрали 5 типичных симптомов, которые сигнализируют, что система уже нестабильна — на примере Magento, популярной CMS в сфере e-com.

В первую очередь скажем, что на Magento работают крупные бренды по всему миру. Она гибкая, масштабируемая, с богатой экосистемой. Однако без регулярных обновлений, контроля и DevOps-поддержки любой проект начинает замедляться, сбоить, а со временем — ломаться. Сигналы появляются заранее: сначала падает скорость, потом checkout, потом весь сайт.

Сигнал 1: падение скорости при большом трафике — во время акций и распродаж

Что проверить

  • Узкие места в БД: тяжелые SELECT, отсутствие индексов.

  • Дублирующиеся или вложенные вызовы блоков в Magento layout.

  • Как ведет себя cron и очередь задач.

  • Используется ли Varnish для FPC и/или Redis для общего кеша.

Как чинить

  1. Настроить загрузку тяжелых блоков после рендера страницы — через AJAX.

  2. Внедрить нагрузочное тестирование — k6, Siege, JMeter.

  3. Перенастроить кеш Magento, включить компиляцию DI.

  4. Заложить горизонтальное масштабирование или CDN.

Сигнал 2: долгая загрузка интернет-магазина при обычной посещаемости (более 3 секунд)

Что проверить

  • Логи Magento и серверов: timeouts, ошибки, блокировки.

  • Скорость отклика API.

  • Время сборки layout и количество подключаемых блоков.

Как чинить

  1. Проанализировать профилировку — Xdebug, New Relic.

  2. Отключить неиспользуемые плагины и модули.

  3. Настроить мониторинг производительности и ошибок — New Relic, Grafana, Prometheus.

Сигнал 3: Клиенты доходят до оформления, но не покупают — особенно на мобильных устройствах

Что проверить

  • Как работает checkout: отрисовка, JS, блоки, сторонние виджеты доставки/оплаты.

  • Как отрабатывает кнопка «Оформить заказ» — все ли проходит быстро.

  • Нет ли тяжелых или повторяющихся вызовов.

Как чинить

  1. Кешировать доступные блоки внутри checkout.

  2. Упростить форму и ускорить ввод данных — DaData.

  3. Включить асинхронную обработку заказов, если оформление занимает много времени.

  4. Протестировать на реальных устройствах и подключить фронтовый логгер — Sentry.

Сигнал 4: когда починили один баг — появился другой 

Что проверить

  • Архитектуру модулей: tight coupling, перезапись классов, обилие around-плагинов.

  • Есть ли автотесты, CI.

  • Как внедряются хотфиксы.

Как чинить

  1. Минимизировать around-плагины и preference (перезаписей классов), отдавать предпочтение before/after-плагинам и observer.

  2. Покрывать фиксы хотя бы базовыми unit/integration-тестами.

  3. Настроить dev → stage → prod, релизный процесс с changelog.

  4. Ввести code style, практику ревью и договоренности внутри команды.

Сигнал 5: CMS или модули устарели, все «на костылях» и никто не решается трогать

Что проверить

  • Версии ядра Magento и зависимостей.

  • Нет ли deprecated-библиотек, особенно JS.

  • Насколько кастомно переопределены шаблоны и классы.

  • Есть ли onboarding-документация, описание архитектуры, миграций, cron.

Как чинить

  1. Если кастомный код внесен прямо в ядро Magento, то его нужно вынести в отдельные модули.

  2. Сравнить архитектуру с best practices Magento и рекомендациями вендоров.

  3. Написать README и настроить автоматизацию — Docker, Ansible.

  4. Запланировать регулярные апдейты проекта.

Если у вас совпадают 3+ пункта — пора на техаудит

Magento почти всегда подает сигналы заранее: снижается скорость, растет количество багов, страдает checkout. Если таких симптомов становится много — пора остановиться и разобраться, что происходит внутри.

Что делать

  • Использовать метрики: PageSpeed, TTFB, логи ошибок.

  • Провести аудит: кеш, модули, layout, архитектура, DevOps.

  • Найти узкие места и критичные зависимости.

  • Выделить приоритеты по улучшениям и составить roadmap по рефакторингу.

Теги:
Всего голосов 2: ↑1 и ↓1+2
Комментарии0

Спустя почти год работы мой PR приняли в ядро Joomla!

[Тут должна быть победная пляска] Год назад у моих клиентов возникла необходимость во вставке видео в кастомные поля материалов в раздел портфолио. Я начал делать и увидел, что именно стандартное пользовательское поле Media не умеет вставлять в поле ничего, кроме изображений, хотя поле Joomla Form MediaField умеет выбирать и документы (pdf и иже), аудио, видео и даже папки. Я начал работу над тем, чтобы добавить этот функционал  в ядро и очень надеялся успеть к Joomla 5.3, которая выходила в апреле. В целом все сделал, сделал PR 25 февраля 2025 года, но PR не приняли, сказав, что это шибко новый функционал и ему будет хорошо в Joomla 6.0.0. Клиентам пришлось использовать  медиа-менеджер от JCE, а PR отправился ждать релиза 6.0.0, который выходил осенью. К слову сказать, эта пауза была полезна для него, так как летом, уже неспешно я получал советы по улучшению и в июле всё точно было готово.

Релизный цикл Joomla состоит из нескольких этапов: сначала выходят alpha-версии (до 3х штук), где просто фиксируются накопленные изменения, потом beta, где наступает feature freeze - заморозка новых функций, их нельзя уже добавлять. Дальше только отладка и правки  существующих новшеств. У каждого релиза есть 2 релиз-менеджера.

В работе над PR мне помогал все это время Брайан Тиман - ко-фаундер Joomla. К концу июля все было готово, проверено, PR имел 2 необходимых независимых теста. Ждём беты.

Дата беты приходилась на понедельник. Где-то в пятницу днём я отписался в PR и получил совет написать релиз+менеджерам. Как-то удалось найти их в Mattermost, где обитает международное сообщество, но пятница и выходные, а все ж волонтеры и не на зарплате... Моё сообщение прочитали после релиза беты... Сказали, что не были в курсе моего PR (ожидаемо, их около 200-250 все время открытых). И сказали, что поезд ушёл, хоть и so sorry. Зато будет хорошо увидеть PR на тестах в Pizza, Bugz and Fun и вообще welcome в 6.1.

После выхода 6.0.0 меняются релиз-менеджеры. Мы списались: да, все хорошо, но нужно кое-что подправить. Тут конец года и закрытие дедлайнов, потом Новый год и весь январь никто толком не работает. Beta для 6.1 выходит 17 февраля. Последняя alpha  недели за 3 до этого.

Незадолго до выхода альфы я-таки получаю сообщение, что реализуемый функционал сделан не по "Joomla way" и если код в ядре, то этот код является учебным пособием по тому, как ядро использовать. Резонно. А ещё у релиз-менеджера есть собственные наработки и экспертиза в этой теме и свой медиа-менеджер, в котором он тоже прошел огонь, воду и медные трубы. Согласно Joomla way мне нужно было разделить одно мега-крутое поле на 4 отдельных (картинки, аудио, видео и документы). Я подумал, что требуется сделать 4 плагина вместо одного и сказал, что не успею. Мне ответили, что beta is more important for us и время ещё есть, что мне подскажут и 4 плагина делать не нужно.

Пока суть да дело - время идёт. У меня тоже работа, трое детей, карантины, уроки... Но добить этот PR уже стало делом принципа. Я  нашел как нужно было делать, принял несколько правок и пожеланий, потом фиксы code style. Сегодня с утра был последний коммит. Сегодня вечером, 11 февраля 2026 года, PR наконец-то смержен в ядро Joomla.

Эта работа научила меня очень многому. 170 комментариев в conversation на GitHub, несколько отдельных переписок, 1 год на разработку и внедрение простой в целом фичи, "звоночек" в голове: "не забыть, успеть, сделать, найти"...

Сегодня я поднимаю кружку пенного за этот небольшой  в целом PR, за этот прошедший год, за Joomla и за Open Source.

https://github.com/joomla/joomla-cms/pull/45013

#joomla #cms #opensource #community #webdev

P.S. Фото с пивом сюда выставлять не буду, но представьте, что оно тут есть.

Теги:
Всего голосов 9: ↑9 и ↓0+11
Комментарии14

Ближайшие события

Событие Pizza, Bugs & Fun - 29-30 января 2026 года.

Уже несколько лет в мире Joomla проводятся мероприятия "Pizza, Bugs & Fun" (#PBF), где каждый может посвятить несколько часов своего мозгового времени тому, чтобы наша любимая CMS стала ближе к идеалу.

Ссылки на видео и статьи из этого поста рассказывает об организационных вопросах, которые пригодятся для участия в PBF, а так же что и как делать. Координация международного сообщества Joomla происходит в Mattermost (присоединиться).

В рамках события PBF все желающие могут собираться в общий онлайн чат, обсудить вопросы Joomla и приложить к их разрешению свою руку. Самый классный вариант, когда эта встреча происходит оффлайн: тогда организовывается пицца, напитки по вкусу и несколько часов совместного творчества.

Каждый помогает тем, что он умеет:

  • кто-то пишет недостающую документацию,

  • кто-то пишет код,

  • кто-то тестирует как исправлены ошибки или сделан новый функционал.

На сайте события есть карта, можно "захостить" свою локацию. Практически все движки в мире развиваются за счёт спонсирующих их компаний. Joomla одна из немногих, где развитие идёт только усилиями международного сообщества энтузиастов.

На момент написания данного поста в репозитории Joomla 810 открытых Issue (как правило это баги) и 236 Pull request (PR, исправление багов и новый функционал). Все PR обязательно тестируются минимум двумя участниками сообщества, дабы в конечный код движка не проскочила ошибка.

Если каждый из участников только нашего сообщества сделает даже одно тестирование, то, боюсь, PR и Issue на всех не хватит 😀 И ничего не останется нашим коллегам из международных Joomla-чатов.

Чат русскояызчного Joomla-сообщества

Теги:
Рейтинг0
Комментарии0

DDoS-атаки: почему стандартные решения не спасают и как выстроить эффективную защиту. Интервью ispmanager с GreyWeb

Рады вас приветствовать, дорогие читатели!

Тема противодействия DDoS-атакам остается одной из самых острых и актуальных в сфере IT. Атаки постоянно эволюционируют, становятся более сложными и мощными, заставляя специалистов искать новые, более изощренные методы защиты.

В ispmanager мы регулярно сталкиваемся с вопросами наших пользователей о том, как обезопасить свои серверы и проекты. Именно поэтому мы провели глубокое интервью с ведущими экспертами по кибербезопасности из компании GreyWeb, которые специализируются на профессиональной защите от DDoS.

Что мы обсудили и почему это важно для каждого, кто управляет инфраструктурой:

•  Эволюция угроз: Как меняются DDoS-атаки и почему вчерашние методы защиты сегодня уже неэффективны.

•  Ограничения стандартных решений: Разбор типовых ошибок и мифов, связанных с "базовой" защитой.

•  Комплексные стратегии: Какие подходы и технологии позволяют эффективно отражать даже самые мощные и целевые атаки.

•  Взгляд изнутри: Практический опыт GreyWeb по предотвращению и минимизации ущерба от DDoS, кейсы и рекомендации.

•  Подготовка к атаке: Что нужно сделать заранее, чтобы быть готовым к худшему сценарию.

Это интервью — не просто набор теоретических выкладок, а концентрат практического опыта и аналитики от специалистов, которые ежедневно борются с киберугрозами. Если вы системный администратор, DevOps-инженер, разработчик или владелец сервиса, который не понаслышке знает о рисках DDoS, этот материал будет для вас крайне полезен.

Приглашаем к прочтению: ➡️

https://www.ispmanager.ru/news/case-greyweb

Делитесь вашим опытом борьбы с DDoS в комментариях!

Теги:
Всего голосов 1: ↑0 и ↓1-1
Комментарии0

Как тестировать Joomla PHP-разработчику? Компонент Patch tester.

Joomla - open source PHP-фреймворк с готовой админкой. Его основная разработка ведётся на GitHub. Для того, чтобы международному сообществу разработчиков было удобнее тестировать Pull Requests был создан компонент Patch Tester, который позволяет "накатить" на текущую установку Joomla именно те изменения, которые необходимо протестировать.

На стороне инфраструктуры Joomla для каждого PR собираются готовые пакеты, в которых находится ядро + предложенные изменения. В каждом PR обычно находятся инструкции по тестированию: куда зайти, что нажать, ожидаемый результат. Тестировщики могут предположить дополнительные сценарии, исходя из своего опыта и найти баги, о которых сообщить разработчику. Или не найти, и тогда улучшение или исправление ошибки быстрее войдёт в ядро Joomla.

Напомню, что для того, чтобы PR вошёл в ядро Joomla нужны минимум 2 положительных теста от 2 участников сообщества, кроме автора.

Компонент на GitHub

Это видео также на:

Чат русскоязычного Joomla-сообщества

#joomla #php #webdev #community

Теги:
Рейтинг0
Комментарии0

Метод registerListeners() в CMSPlugin в плагинах планируется удалить в Joomla 7.0.

Этот метод регистрирует устаревшие слушатели событий в диспетчере, имитируя работу плагинов Joomla! 3.x и ниже для Joomla 4+. По умолчанию этот метод ищет все общедоступные методы, название которых начинается с on. Он регистрирует лямбда-функции (замыкания), которые пытаются преобразовать аргументы отправленного события в аргументы вызова метода и вызвать ваш метод on<Нечто>. Результат передаётся обратно событию в его аргумент result.

Теперь этот слой совместимости с устаревшей Joomla 3 помечен к удалению в Joomla 7.0, которая должна выйти осенью 2027 года. Это означает, что те уникальные расширения от Joomla 2.5 / Joomla 3, которые ещё работали на Joomla 4-6 скорее всего окончательно перестанут работать на Joomla 7. Предполагается, что активные разработчики планомерно и постепенно избавляются от технического долга и обновляют свои расширения 😎

Чат русскоязычного Joomla-сообщества.

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии0

Совет по Joomla: использовать выключенное состояние для кнопок в списках элементов админки - listCheck().

Мы добавляем в тулбар панели администратора Joomla некую кнопку, которая что-то делает со списком id выделенных элементов и ajax-запросом отсылаем их в свой плагин. Но нам надо предупредить нажатия на кнопку в тех случаях, когда ни один элемент не был выбран. Для этого можно написать свою проверку на js. А можно воспользоваться встроенной в Joomla.

Добавить кнопку в тулбар Joomla 6.

use Joomla\CMS\Toolbar\Button\BasicButton;
use Joomla\CMS\Language\Text;

// ниже по коду, где-нибудь в плагине на onAfterDispatch()
// Предварительно проверяем в каком компоненте мы находимся по option из $app->getInput()
// пример из плагина, поэтому $this->getApplication()
$app = $this->getApplication();
// Берём текущий тулбар
$toolbar = $app->getDocument()->getToolbar('toolbar');

// Создаём кнопку
$button = (new BasicButton('send-to-indexnow'))
    ->text(Text::_('PLG_WTINDEXNOWSWJPROJECTS_BUTTON_LABEL'))
    ->icon('fa-solid fa-arrow-up-right-dots')
    ->onclick("window.wtindexnowswjprojects()");

// Добавляем кнопку в тулбар
$toolbar->appendButton($button);

Заблокировать кнопку тулбара Joomla, если не выбраны элементы списка.

Теперь нам надо проверить находимся ли мы в списке. Делаем это по view из $app->getInput().

if(in_array($app->getApplication()->getInput()->get('view'),
            ['categories','documentation','projects','versions'])
  ) {
        $button->listCheck(true);
}

И если мы в списке - используем метод $button->listCheck(true), который сделает проверку за нас. Если ни один элемент не выбран - кнопка в тулбаре Joomla будет заблокирована и JS-обработчик не будет вызван. Этот метод есть у всех классов кнопок, наследующих класс \Joomla\CMS\Toolbar\ToolbarButton.

Теги:
Рейтинг0
Комментарии0

Человек на GitHub ускорил Joomla в 600 раз на объёме 150к+ материалов в 1700+ категориях.

На старте его сайт на Joomla 3 вообще не смог обновиться на Joomla 5. Пришлось делать экспорт/импорт материалов. Проделав всё это он запустил-таки этот объём данных на Joomla 5. Тестовый скрипт грузил 200 материалов из этого объёма всего за 94 секунды ))) А главная страница с категориями грузилась 20 секунд.

Добавив индекс для таблицы #__content

CREATE INDEX idx_catid_state ON #__content (catid, state);

он сократил время загрузки категорий до 1 секунды. Затем наш герой решил поковырять SQL-запрос в ArticleModel, который отвечает за выборку материалов. И решил заменить тип JOIN на STRAIGHT_JOIN для категорий.

// ->from($db->quoteName('#__content', 'a'))
->from(
    $db->quoteName('#__content', 'a')
    . ' STRAIGHT_JOIN ' . $db->quoteName('#__categories', 'c')
    . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid')
)
// ->join('LEFT', $db->quoteName('#__categories', 'c'), $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid'))

Что сократило загрузку 200 материалов из 150к с 94 секунд до 5. К слову сказать, боевой сайт на Joomla 3 крутится на 12CPU 64GB рамы. А все манипуляции с кодом он делает на базовом 1CPU 1GB сервере и замеры скорости даны именно для базового сервера.

Но это всё в дискуссии, хотя в идеале должно вылиться в Pull Requests. Дальнейшие его изыскания и результаты можно поглядеть в дискуссии на GitHub. Это ещё не конец.

Мы - Open Source сообщество, где никто никому ничего не должен. Джунгли. Но человек ищет пути оптимизации Joomla и предлагает решения. Если оказать поддержку и предложить помощь хотя бы с тестированием самых разнообразных сценариев, то возможно эти улучшения смогут войти в ядро. Пусть не быстро, пусть через несколько лет, пусть не все, но войдут. Достаточно предложить руку помощи и приложить немного усилий.

Дискуссию на GitHub можно почитать здесь.

Теги:
Рейтинг0
Комментарии0

Обработка HTTP ответа в Joomla 6+. Изменения по сравнению с Joomla 3 - Joomla 5.

В Joomla для выполнения внешних запросов из PHP к сторонним API используется класс Joomla\Http\Http напрямую или же Joomla\Http\HttpFactory, который возвращает для работы преднастроенный по умолчанию класс Http. О работе с HTTP-запросами подробно рассказывалось в статье 2021 года Создание внешних запросов с использованием HttpFactory (Joomla) (на Хабре), (на сайте автора). Некоторые изменения касаются работы с ответами на запросы. Например, наш запрос:

use Joomla\Http\HttpFactory;

$http = (new HttpFactory)->getHttp($options, ['curl', 'stream']);
$response = $http->get('https://any-url.ru/api/any/endpoint');

Раньше можно было получить код ответа или тело ответа как свойство $response - $response->code или $response->body. Однако, Joomla, начиная с Joomla 4 во многом переходит на стандарты PSR. В частности для работы с HTTP-ответами - на PSR-7. Также хорошая статья на Хабре о PSR-7: PSR-7 в примерах.

Прямое обращение к свойствам code, headers, body объявлено устаревшим в Joomla 6.0.0 и обещают удалить в Joomla 7.0.0.

Вместо этого нужно работать с HTTP-ответом по стандартам PSR-7.

Код ответа.
Было $response->getContents(). Стало $response->getStatusCode().

Заголовки ответа.

Было $response->headers. Стало $response->getHeaders().

Тело ответа.

Было $response->body. Стало (string)$response->getContents().

В тело ответа теперь приходит не строка, а поток - объект класса Laminas\Diactoros\Stream. Поэтому его нужно привести к строке (если это json, к примеру): (string)$response->getContents(). Чаще всего в коде Joomla встречается именно такой вариант. Однако, есть и вариант с перемещением указателя чтения на начало потока:

// Получили ответ в виде потока
$stream = $response->getBody();
// "перемотали" на начало
$stream->rewind();
// Получили строковый ответ
$json = $stream->getContents();

В итоге результат одинаковый.

Telegram чат русскоязычного Joomla-сообщества.

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии0