Разница между масштабирование и зумом в CSS. Зум работает так же, как и масштабное преобразование, но в отличие от масштабирования, он влияет на макет страницы. Другими словами, макет страницы пересчитывается с учётом нового размера масштабируемого элемента.
Некоторых разработчиков и вебмастеров интересует останется ли плагин обратной совместимости в Joomla 6. Этот плагин был создан для того, чтобы сделать переход от версии к версии более гладким и бесшовным. Подробнее почитать о роли плагина можно в официальной документации на manual.joomla.org: Compatibility Plugin.
Устаревший код МОЖЕТ быть перемещен в плагин совместимости. Плагин обеспечивает более плавное обновление между основными версиями. Он содержит код из предыдущей версии, который может сломать сайт после обновления, поскольку расширение использует устаревший код. Расширение полностью совместимо только тогда, когда оно работает без проблем с отключенным плагином совместимости.
От версии к версии часть кода ядра Joomla помечается как устаревшая, а затем, спустя некоторое время удаляется из основного ядра и МОЖЕТ быть перемещена в плагин обратной совместимости. Эта концепция появилась при переходе от Joomla 4 к Joomla 5.
Важным уточнением является то, что для новой мажорной версии (joomla 3, joomla 4, joomla 5 и т.д.) плагин содержит устаревший код предыдущей версии. То есть для Joomla 5 это код из Joomla 4. Для Joomla 6 - код из Joomla 5.
Таким образом расширения, использующие методы и функции ядра Joomla и всё ещё работающие даже с плагином обратной совместимости на Joomla 5 в Joomla 6 скорее всего работать уже не будут. В Joomla 6 из плагина обратной совместимости будет удален код, поддерживающий обратную совместимость с Joomla 4. Таким образом стабильно работать в Joomla 6 будет то, что сейчас стабильно работает на Joomla 5 с отключённым плагином обратной совместимости.
Joomla-разработчикам: обращение к методам модели в HtmlView напрямую
Когда-то, давным-давно в одной далёкой галактике кто-то решил, что было бы неплохой идеей ввести в Joomla косвенный доступ к методам модели (MVC) для получения данных, добавив метод AbstractView::get(). Этот метод извлекает модель и затем запускает get(). Простыми словами, когда мы во View (файл HtmlView нашего компонента) видим конструкцию $this->item = $this->get('Item') это означает обращение к методу getItem() модели для текущего View.
Но такой подход исключает любую возможность подсказки типов, аргументов и т. д. и делает все излишне сложным. Поэтому разработчики ядра Joomla объявили этот метод устаревшим с этим PR 44162.
Новый способ выглядит так:
// Файл HtmlView компонента
public function display($tpl = null)
{
$model = $this->getModel();
$this->items = $model->getItems();
parent::display($tpl);
}
Старый подход (то есть метод get() во View) будет удалён в Joomla 7. Памятуя о релизном цикле Joomla, это означает, что:
осенью 2025г выйдет Joomla 6.
2 года она будет основной веткой. Joomla 5 будет в режиме поддержки
через 2 года, в 2027 выйдет Joomla 7, в которой будет удалён этот метод.
но Joomla 6 будет ещё 2 года в режиме тех.поддержки и в ней (до 2029 года) этот метод останется.
Таким образом у разработчиков есть от 2,5 до 4,5 лет (на момент написания этого поста) на то, чтобы сделать этот рефакторинг.
Сегодня мы выпускаем функционал расширенных алертов.
Теперь каждый наш пользователь сможет получать уведомления в специальный бот, если:
Проект ушел в ошибку.
Произошло превышение ОЗУ или ЦПУ выше заданного порога
Сработала Liveness или Readiness проба.
Произошла ошибка сборки или запуска проекта.
Встретилась заданная фраза в логе.
Amvera Cloud — это облако для простого деплоя приложений через git push. Встроенный CI/CD, бэкапы и мониторинг позволяют развернуть проект тремя командами в IDE и не думать о настойке инфраструктуры. Amvera проще, чем использование VPS или Kubernetes-кластера.
А ты такой холодный: представим технологии Rust-дебаггеров в виде айсберга
На верхушке айсберга видим технологии DWARF, PTRACE и ELF, а внизу — набор более редких технологий.
Сегодня будем говорить только о верхушке. Хорошая новость: чтобы понять большинство возможностей дебаггера, достаточно иметь представление об этих трех технологиях:
PTRACE — системный вызов, который позволяет одному процессу (tracer) управлять и исследовать другой процесс (tracee).
ELF (Executable and Linkable Format) — формат исполняемых двоичных файлов.
DWARF (Debugging With Arbitrary Record Formats) — стандарт, описывающий формат .debug_xxx секций в ELF.
Что касается «подводных» технологий, упомянутых на картинке: применяя закон Парето, можно смело сказать что 80% знаний необходимы, чтобы реализовать только 20% функционала (и не самого важного). Но если хотите узнать о них больше, напишите в комментариях.
Подробнее о PTRACE, ELF и DWARF, а также о функциях, которые они реализуют в отладчиках на Rust, читайте в статье.
Совет по Joomla: показ уведомлений Joomla.renderMessages.
Пользователь совершает какие-то действия на сайте и получает сообщения об успешном или не успешном их результате, а также просто информационные сообщения. В php коде мы привыкли использовать для этого метод enqueueMessage():
use Joomla\CMS\Factory;
$html = 'Message';
Factory::getApplication()->enqueueMessage($html, 'warning');
Чаще всего в качестве сообщения используются языковые константы, чтобы пользователи могли получать сообщения на своём языке:
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
Factory::getApplication()->enqueueMessage(Text::_('SOME_LANG_CONSTANT'), 'info');
Рендер сообщений Joomla во фронтенде.
Здесь нам потребуется файл подключённые файлы ядра core.js и messages.js. Немного выдержки из кода:
/**
* Рендер сообщений, отправленных через JSON
* Используется некоторыми javascript, в частности validate.js
*
* @param {object} messages JavaScript объект, содержащий сообщения для рендера.
* Пример:
* const messages = {
* "message": ["Это будет зелёное сообщение", "И это тоже"],
* "error": ["Это будет красное сообщение", "И это тоже"],
* "info": ["Это будет синее сообщение", "И это тоже"],
* "notice": ["Какое-то информационное сообщение", "И это тоже"],
* "warning": ["Оранжевое сообщение", "И это тоже"],
* "my_custom_type": ["Такое же как инфо-сообщение", "И это тоже"]
* };
* @param {string} selector CSS-селектор контейнера для рендера сообщений
* @param {bool} keepOld Удалить предыдущие сообщения? Да, если true
* @param {int} timeout Таймаут исчезновения сообщения в миллисекундах
* @return void Метод ничего не возвращает
*/
Теперь мы видим, что в качестве сообщения мы и в Javascript можем использовать языковые константы. Для этого мы используем метод Joomla.Text._() (по аналогии с Text::_() в PHP). Но Javascript откуда-то должен получить значения этих языковых констант. И для этого в php коде нашей страницы мы должны позаботиться о нём и добавить нужные для js языковые константы с помощью метода Text::script().
use Joomla\CMS\Language\Text;
Text::script('SOME_LANG_CONSTANT_SUCCESS');
Text::script('SOME_LANG_CONSTANT_FAIL');
Таким образом я смогу получить в js доступ к значениям языковых констант SOME_LANG_CONSTANT_SUCCESS и SOME_LANG_CONSTANT_FAIL.
Если вы только начинаете (или хотите начать) изучать JavaScript, то для вас есть подборка обучающих материалов. Все они доступны бесплатно. Регистрироваться, оставлять контактные данные или оформлять подписку тоже не нужно.
Если долго использовать какой-то инструмент, мозг вырабатывает паттерны: мы повторяем одни и те же решения, не всегда задумываясь, что появились новые, более удобные способы. Так происходит и с JavaScript.
JS развивается каждый год, но многие продолжают писать код, как привыкли, не используя свежие возможности языка. Я стараюсь бороться с этим и внедрять новшества в свою повседневную работу и недавно пошел посмотреть что там нового подвезли в ECMAScript 2024 (ES15). А там оказалось довольно много интересного.
Например, новые методы массивов. Раньше методы вроде .sort() и .reverse() изменяли исходный массив, что могло привести к неожиданным багам.
Точно так же работают новые методы .toSorted() и .toSpliced(). Они делают код более предсказуемым и чистым.
Также, я с огромным восхищением прочитал про Temporal - новый объект для работы с датами и временем. Например, меня всегда поражало , что в Date месяцы индексируются с 0 (январь – это 0), а вот дни месяца начинаются с 1. Temporal фиксит эти проблемы и теперь можно: ✅ Создавать объекты только с датой или только со временем ✅ Удобно складывать и вычитать даты ✅ Работать с часовыми поясами без боли В общем делать все, для чего мы раньше тащили в проекты всякие moment и day.js.
К огромному сожалению Temporal пока не поддерживается в браузерах, но когда выйдет – работа с датами в JS станет в разы удобнее.
Если вам интересны такие обновления подписывайтесь на мой Telegram-канал!
Событие Pizza, Bugs & Fun приближается - 22 февраля 2025 года
Уже несколько лет в мире Joomla проводятся мероприятия "Pizza, Bugs & Fun" (#PBF), где каждый может посвятить несколько часов своего мозгового времени тому, чтобы наша любимая CMS стала ближе к идеалу.
Видео из этого поста рассказывает об организационных вопросах, которые пригодятся для участия в PBF:
как создать аккаунт в Mattermost (чат международного Joomla-сообщества)
как создать аккаунт в Joomla! Documentation
как написать статью в Joomla! Documentation
как создать аккаунт на GitHub (у разработчиков обычно уже он есть)
как настроить патч тестер
как протестировать патч
как получить вознаграждение
В рамках события PBF все желающие могут собираться в общий онлайн чат, обсудить вопросы Joomla и приложить к их разрешению свою руку. Самый классный вариант, когда эта встреча происходит оффлайн: тогда организовывается пицца, напитки по вкусу и несколько часов совместного творчества.
Каждый помогает тем, что он умеет:
кто-то пишет недостающую документацию,
кто-то пишет код,
кто-то тестирует как исправлены ошибки или сделан новый функционал.
На сайте события есть карта, можно "захостить" свою локацию. Практически все движки в мире развиваются за счёт спонсирующих их компаний. Joomla одна из немногих, где развитие идёт только усилиями международного сообщества энтузиастов.
На момент написания данного поста в репозитории Joomla 752 открытых Issue (как правило это баги) и 223 Pull request (PR, исправление багов и новый функционал). Все PR обязательно тестируются минимум двумя участниками сообщества, дабы в конечный код движка не проскочила ошибка.
Если каждый из участников только нашего сообщества сделает даже одно тестирование, то, боюсь, PR и Issue на всех не хватит 😀
Модули порой удобно использовать в местах, которые в Joomla не всегда предназначены для этого 😀. Например, в переопределениях макета. Из материала делаем посадочную страницу: часть инфы находится в самом материале, часть - в полях, а часть удобно вывести модулем. При этом модуль этот должен находиться между телом материала и данными из пользовательских полей.
Для реализации берём в руки ModuleHelper и приступаем.
<?php
use \Joomla\CMS\Helper\ModuleHelper;
$modules = ModuleHelper::getModules('landing-masonry');
if(!empty($modules))
{
foreach ($modules as $module)
{
// рендерим всё, что нашли в позиции landing-masonry
echo ModuleHelper::renderModule($module);
}
}
А что если посложнее?
В этом случае всё просто. Но здесь в тему будет упомянуть ещё один способ работы с модулями. Контекст: магазин одежды. В карточке товара нужно вывести информацию о размерной сетке, типовые рекомендации по уходу и т.д. Это короткие тексты, которые повторяются из товара в товар и не нужно их копировать многажды. Эти тексты отображались простым аккордеоном Bootstrap.
Вид карточки товара JoomShopping. Все тексты, кроме описания товара - одинаковые во всех товарах. Описание товара уникальное для каждого товара.
Но! В этот же аккордеон нужно было добавить и описание товара JoomShopping. Поэтому я сделал с помощью своего модуля WT Quick links следующее.
Создал модуль типа WT Quick Links, в котором в список элементов занёс все нужные тексты.
Не стал назначать модуль какой-либо позиции. В шаблоне JoomShopping захардкодил id модуля. Хотя лучше было бы назначить модуль в некой уникальной позиции, которая встречалась бы только в нужном нам месте на сайте.
Программным способом в данные модуля добавил нужные данные из JoomShopping так, как мне нужно (в начало списка - описание товара).
Отрендерил модуль с помощью ModuleHelper в product_default.php шаблона JoomShopping.
<?php
use Joomla\CMS\Helper\ModuleHelper;
use Joomla\Registry\Registry;
// Модуль id 136 - Доставка, оплата и гарантии в карточку товара + ОПИСАНИЕ ТОВАРА JoomShopping
$module = ModuleHelper::getModuleById('136');
$module_params = new Registry($module->params);
// Формируем новые параметры модуля перед рендером.
$new_module_params = [];
$i = 1;
// Помещаем описание товара в самое начало
if (!empty($this->product->description)){
$new_module_params['fields']['fields0'] = (object) [
'item_header' => Text::_('JSHOP_DESCRIPTION'),
'item_text' => $this->product->description
];
}
// Переименовываем все остальные ключи массива элементов из модуля
foreach ($module_params->get('fields') as $key => $value)
{
$new_module_params['fields']['fields' . $i] = $value;
$i++;
}
$new_module_params = new Registry($new_module_params);
// Соединяем старые и новые параметры модуля.
$module_params->merge($new_module_params);
$module->params = $module_params->toString();
// Всё готово! Рендерим модуль.
echo ModuleHelper::renderModule($module);
Вот писал я про то, как установил на TV-приставку Linux и подключил к ТВ как к монитору. Ну и "чтобы зря не пропадало" - а дай-ка посмотрю один известный сейчас сериал, на сайте, посвященном этому самому сериалу. (потому что смотреть можно только в браузере, а браузер на Андроиде на этом сайте жутко тормозит)
Но и тут всё начинает сразу же тормозить, процессор под 100%, память забита, всё еле шевелится. Зато можно удобно посмотреть в Инспекторе, что за дела происходят.
А там зоопарк! Во-первых, куча скриптов тянет рекламу с каких-то левых адресов, куча следилок типа webvisor, всё это в фоне работает и грузит систему. И вот такое:
То есть, получается, оно еще и Ютуб смотрит фоном, то ли показатели накручивает, то ли видео копирует. Причем вроде как под моим аккаунтом - я же в Гугле залогинен?
Хорошо, что всё было завернуто через xray, с его настройками: стоило забанить всю эту рекламно-следильную мудрость и даже ютуб - и волшебным образом тормоза исчезли. Сайт превратился в простой одностраничник, а видео стало просто показывать как видео.
Я конечно понимаю что сам смысл этого сайта в том чтобы делать деньги на показах и накрутках, но совесть надо иметь? Не на 100% же процентов грузить, вплоть до невозможности работы?
Есть много языков, которые не компилируется в машинный код, а исполняются на виртуальной машине или интерпритаторе - C#, Python, JavaScript и так далее, но самый быстрый из них Java.
😮 Почему? В начале 2000-х на рынке JVM существовало несколько ключевых игроков:
Sun Microsystems HotSpot
IBM J9
Oracle JRockit
Excelsior JET
Но в декабре 2006 года, с выходом Java 6, HotSpot вырвалась вперед, разгромив конкурентов, благодаря JIT-компиляции.
🤔 Как работает JIT? Just In Time компиляция — это механизм, который компилирует часто исполняющиеся участки кода в машинный код во время выполнения программы, что значительно ее ускоряет.
Рассмотрим метод:
public void exampleMethod(int value) {
if (value > 0) {
// Исполняется часто
System.out.println("Positive value");
} else {
// Исполняется редко
System.out.println("Non-positive value");
}
}
При первом вызове exampleMethod JVM интерпретирует байт-код
Если exampleMethod вызывается многократно с положительными значениями, JIT-компилятор определяет это как "горячую точку"
После достижения порога вызовов этой точки с условием value > 0 компилируется машинный код для метода
Если позже будет вызван метод с отрицательным значением (что не ожидалось), произойдет uncommon trap, и управление передастся интерпретатору для обработки этого случая
☕️ То есть, JVM в рантайме определяет путь, который чаще всего проходит программа, и именно этот путь компилируется нативно и максимально оптимизируется.
⚡Благодаря такой оптимизации джава уничтожает бенчмарки, потому что в них обычно повторяется один и тот же код.
Разработчикам мобильных и WEB-приложений (и не только) весьма и весьма пригодится готовая коллекция для Postman. В коллекцию добавлены endpoint для REST API Joomla, с параметрами и примерами запросов.
Коллекция составлена трудами французского Joomla-разработчика Alexandre J-S William ELISÉ.
Нам нужно больше capacity: как растет вместимость в слайсах на Go
Чтобы выяснить, во сколько раз Go увеличивает внутренний массив элементов в слайсах, проведем небольшой тест. Добавим один элемент к уже заполненным слайсам:
На графике видно, что в районе 200 элементов увеличенный слайс вмещает уже 400 элементов, а в районе 800 — 1200, то есть вместимость выросла сначала в два раза, потом — в полтора.
В коде рантайма можно найти простую формулу: если в слайсе capacity элементов было меньше 256, то вместимость увеличится в два раза. Если больше 256, то на четверть. Таким образом мы пытаемся экономить память.
Существует забавная константа для вычисления вместимости: три четвертых от 256. Разработчики на Go посчитали, что так происходит более плавный переход от фактора 2x к фактору 1.25
Почему на графике образовались «ступеньки» вместо привычной кривой и что еще нужно знать о слайсах Go-разработчику — читайте в статье →
Совет по Joomla: метод debug() для отладки лейаутов
В Joomla есть понятие layout. Это кусочек вёрстки, который можно многажды использовать в любом месте сайта: как в панели администратора, так и во фронтенде. Можно рассматривать лейауты как оторванные от контекста элементы дизайна. Находятся они в папке layouts в корне сайта. Также, в случае с модулями они могут находиться в папке tmpl модуля. А в случае с плагинами - в tmpl плагина.
Их можно переопределять в шаблонах, в чём и заключается одна из главных фишек Joomla. Лейауты чаще всего рендерятся с помощью классов LayoutHelper или напрямую FileLayout. Писал о них ранее тут и тут.
А вот как увидеть какой именно файл переопределения используется? Сколько их вообще есть и по каким путям идёт поиск макетов? Для этого есть метод debug() (и у LayoutHelper и у FileLayout).
<?php
/**
* Method to render a layout with debug info
*
* @param string $layoutFile Dot separated путь к файлу относитеьлно basePath
* @param mixed $displayData Объект с данными для рендера
* @param string $basePath Base path, где будет поиск файлов лейаутов
* @param mixed $options Дополнительные опции для FileLayout
*
* @return string
*
* @since 3.5
*/
public static function debug($layoutFile, $displayData = null, $basePath = '', $options = null)
{
// Так проще показать параметры метода.
}
Как вы знаете, китайская LLM deepseek-R1 работает не хуже chatGPT-o1, но стоит в 20 раз дешевле. А знаете ли вы, что сама модель вообще бесплатная, её можно скачать себе и запустить на своём железе?
Мне стало интересно, как это делать, можно ли как-то запустить прямо на макбуке, и оказалось, что это делается буквально в два клика (конечно, полная модель на ноут не влезет, но дистиллированная - вполне).
Возможно, все уже это умеют, но расскажу для тех, кто, как и я, был в танке, так что держите инструкцию.
Прикол китайской модели еще в том, что там показан процесс думания. Его можно посмотреть прямо в этом веб-интерфейсе.
Понятно, что это скорее побаловаться - на ноуте влезает только дистиллированная модель и то нещадно тормозит (макбук M1 pro). Для полноценной работы нужно нормальное железо или облако.
По-моему, это очень круто: если вложиться в железо, можно очень быстро и просто поднять у себя самый топовый чат и не посылать больше свои секреты ни в OpenAI, ни в Китай.
Что написать на Go, если «вывод суммы на экран» вы уже переросли
You look lonely... I can fix that.
На этот вопрос нашел ответ Игорь Горбунов. Он разрабатывает платформу базовой станции в YADRO и второй год изучает Go. Когда стандартные задачи ему надоели, он придумал челлендж: построить приложение, похожее на утилиту ping в UNIX-подобных системах.
Первым делом разработчик набросал список требования к приложению, чтобы опираться на него в процессе работы:
Возможность запросов Echo-Request по протоколам ICMP и ICMPv6 и поддержка IPv4 и IPv6 со стороны ping.
Возможность указания целевого узла в виде непосредственно адреса либо в виде имени, что требует поддержки разрешения имен.
Возможность менять из командной строки размер отправляемых запросов и их количество.
Подсчет и вывод в консоль статистики отправленных запросов, полученных и неполученных ответов, ошибок, минимального, среднего, максимального времени круговой задержки (rtt), а также стандартного отклонения rtt.
Получилось ли у Игоря реализовать настоящий ping и какую проблему ему так и не удалось решить — читайте в статье.
E-mail шаблоны Joomla 5: добавление и просмотр своих переменных
В Joomla 5 появились настраиваемые email-шаблоны, как системные, так и сторонних компонентов. Их нельзя (пока что) добавить самостоятельно, они добавляются расширениями при установке. Но их можно отредактировать в Система - Шаблоны - Шаблоны писем. В настройках шаблонов писем (кнопка настроек компонента в верхнем правом углу) мы выбираем формат писем текст или HTML. Тогда становятся доступны настройки макетов шаблонов писем Joomla. Эти глобальные параметры можно переопределить в каждом конкретном email-шаблоне. Таким образом для каждого из email-шаблонов можно указать свою вёрстку и настройки логотипа. Это, конечно, требует отдельной подробной статьи...
Для разработчиков: как добавить свои переменные для e-mail шаблонов Joomla?
Полезны окажутся 2 триггера для плагинов: onMailBeforeTagsRendering и onMailBeforeRendering.
onMailBeforeRendering - триггер, который позволяет добавлять свои шорт-коды для строковой замены в плагине. Отдать туда надо массив вида [ variable_name => variable_value ]. Из админки свои переменные нужно добавлять уже с фигурными скобками: {variable_name} заменится на variable_value. Аргументом $event плагина является экземпляр класса BeforeRenderingMailTemplateEvent, в котором есть кроме прочих 2 метода: getTemplate() (получение объекта мейлера, куда можно добавлять свои данные) и getTemplateId() (получение id шаблона письма вида com_users.registration.admin.new_notification), по которому мы определяем нужный ли это для нас email-шаблон или нет. Аналогично контексту в контент-плагинах.
Также полезное свойство класса для передачи данных из плагина в лейаут письма для рендера - $layoutTemplateData. Это ассоциативный массив.
// Получаем текущий мейлер
$mailTemplate = $event->getTemplate();
$data = [
'variable_name' => 'variable_value'
];
// с Joomla 4 для всех типов писем. 2-й аргумент - plain - текстовый формат письма
$mailTemplate->addTemplateData($data, false);
// с Joomla 5.2 - для HTML-писем
$mailTemplate->addLayoutTemplateData($data);
// пример из ядра Joomla
// Add additional data to the layout template
$this->addLayoutTemplateData([
'siteName' => $app->get('sitename'),
'lang' => substr($this->language, 0, 2),
]);
onMailBeforeTagsRendering - триггер, который добавляет ваши переменные в список доступных переменных для замены в окне редактирования email шаблона Joomla. Отдать туда нужно массив с переменными, но без их значений.