Joomla 4: классы JText и Text. Из неопубликованного

от автора

Попытаюсь рассказать здесь о некоей коллизии, с которой столкнулся, переписывая старый свой модуль Joomla 3 под Joomla 4. Материал, хочу надеяться, будет интересен профессиональным разработчикам расширений Joomla, несмотря на то обстоятельство, что автор данного текста таковым не является, давно отойдя не только от программирования под Joomla, но и вообще от кодинга на PHP. Но остались старые какие-то проекты, к которым изредка возвращаюсь, больше из ностальгических воспоминаний: что-то уже подзабыл, признаться, многое стало казаться скучным. И в этой связи хочу выразить искреннюю признательность Toivo Talikka, Global Moderator-у форума Joomla.org, чей неподдельный интерес и живое участие в обсуждении и тестировании проблемы сделали возможным написание этой статьи, вскрыв ряд недокументированных особенностей архитектуры четвертой ветки Joomla.

Сходу короткое лирическое отступление. Предпринята, как видите, попытка разбавить сухой технический материал рисунками замечательного петербургского художника Петра Изосимова, с которым автор немного знаком и чья изумительная всегда ирония вполне коррелирует в данном случае с вектором, скажем так, отношения автора к «наличию отсутствия» (в контексте ряда искомых кейсов только, разумеется) документации одного из самых популярных на сегодняшний день CMS-фреймворков. Хм, может статься, мы попросту не нашли; если так, буду благодарен за соответствующие ремарки в комментах. Но не думаю.

Описанный далее экзерсис основан, в частности, на анализе загрузочных файлов Joomla и вполне себе способен содержать gaps and inaccuracies, пробелы и неточности. И — тем не менее — я приступаю к рассказу: примеров и туториалов, доходчиво объясняющих простым смертным критичные подробности кодинга расширений долгожданной Joomla 4 на сегодняшний день в Сети немного, буквально считанные единицы. Уверен, пригодится и вообще в тему.

Итак. Дебажа модуль (это несложный виджет, представляющий собой удобный пользовательский интерфейс клиента ряда погодных API и сервисов определения геотаргетинга), отметил странный казус: в новой версии модуля я не мог так же запросто, как делал это ранее, использовать класс JText в хелпере модуля, объявляя, скажем, массив:

// Helper/FooHelper.php namespace FooNamespace\Module\Foo\Site\Helper; defined('_JEXEC') or die; use Joomla\CMS\Factory;  class FooHelper {     public static function getNames($params)     {             $main = array(                 JText::_('STRING_ONE'),                 JText::_('STRING_TWO')                 );                 return $main;         } }

А вот в HTML-е модуля — мог. Например, так:

// tmpl/default.php  foreach (array_combine($names, $source) as $names => $source):     $html .= '<tr>';         $html .= '<td>' . JText::_($names) . '</td>';         $html .= '<td>' . $source . '</td>';     $html .= '</tr>';     $i++; endforeach;

Не отвлекаясь в тот момент на увлекательные рассуждения о том, как именно в парадигме MVC будет более правильно, автор задался сугубо русским вопросом: а почему нельзя-то, что мешает? — вот раньше было можно а щас нет, как так? — бага?? ниче, ща мы набьем мике баки… и попер с этим разбираться.

Результатом усилий, как ни странно, явилась вполне себе полезная информация. Правда, не сразу.

Второе лирическое отступление. Кодовую базу, послужившую иллюстрацией к материалу — в любой момент возможно увидеть целиком (а не фрагментарно, как продиктовано форматом статьи) в этом репо.

Идем дальше. Спервоначалу пришло в голову, что элементарно не хватает алиаса:

use Joomla\CMS\Language\Text;

, примерно так, собственно, и выходит по актуальной доке и примерам кода базового модуля под Joomla 4. Но увы, здесь снова ждал афронт:

Class 'FooNamespace\Module\Foo\Site\Helper\JText' not found

Как вариант, в хелпере можно было попробовать использовать класс Text вместо JText, и это вполне должно работать, см. в качесте аргумента libraries/src/helper/ContentHelper.php.

Но почему же так странно, почему в хелпере модуля возможен, по-видимому, только Text, а для шаблона модуля сгодится и JText, причем нигде в файлах модуля Joomla 4 я не указывал этого импорта:

$ grep -Fri "use Joomla\CMS\Language\Text;" $

Как это? Возможно, отработало наследование шаблоном модуля? — вряд ли, правила импорта построены так, что включенные файлы не наследуют импорт файла родительского (Importing rules are per file basis, meaning included files will NOT inherit the parent file’s importing rules, Using namespaces: Aliasing/Importing). Объяснение, по-видимому, заключено в

require ModuleHelper::getLayoutPath('mod_foo', $params->get('layout', 'default'));

, именно эту строчку содержит foo.php, точка входа модуля. Операторы require и include, в отличие от use, позволяют включенному файлу наследовать область видимости, вот оно где собака порылась.

Резюме. Разница между классами JText и Text в том, что Text способен быть объявлен только лишь внутри пространства имен. Иными словами, для того, чтобы ссылаться непосредственно на Text вместо JText, необходимо определение неймспейса. К слову, последовательность загрузки в libraries/classmap.php — содержит сопоставление JText, обеспечивая совместимость с новым классом Text, предназначенным, видимо, в Прекрасной Джумла Будущего полностью заменить JText:

JLoader::registerAlias('JText', '\\Joomla\\CMS\\Language\\Text', '5.0');

Данное сопоставление концептуально связывает JText с файлом libraries/src/Language/Text.php, который начинается со следующего объявления пространства имен, общего для файлов в папке libraries/src/Language:

namespace Joomla\CMS\Language;

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


ссылка на оригинал статьи https://habr.com/ru/post/657009/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *