Channel: Joomla для разработчиков
[J4] Поля будут поддерживать data атрибуты
Казалось бы, такая простая вещь как data атрибут уже давно должна была быть составляющей частью стандартных полей. Но появится это только в Joomla 4, что не может не радовать. Ещё одна маленькая мелочь в копилку J4.👌
https://github.com/joomla/joomla-cms/pull/27212
Казалось бы, такая простая вещь как data атрибут уже давно должна была быть составляющей частью стандартных полей. Но появится это только в Joomla 4, что не может не радовать. Ещё одна маленькая мелочь в копилку J4.👌
https://github.com/joomla/joomla-cms/pull/27212
GitHub
[4.0] Allow jForm to support data attribute by twsvaishali · Pull Request #27212 · joomla/joomla-cms
#16141
Как называются специальные позиции (плейсхолдеры) в шаблоне для вывода содержимого?
Anonymous Quiz
13%
jtpl
8%
jmod
63%
jdoc
17%
jpos
Web Assets в Joomla 4 - это?
Anonymous Quiz
24%
Менеджер JS и CSS
3%
Удобное добавление инлайн JS и CSS
7%
Возможность указания зависимостей JS и CSS
17%
Возможность переопределения JS и CSS
48%
Все варианты правильные
Подготовь своё расширение к Joomla 4
Вчера вышла пятая бета Joomla 4. Разработчикам сторонних расширений уже сейчас стоит позаботиться о том, чтобы их расширения продолжали успешно работать и на Joomla 4.
Ниже вы найдете полный список изменений, описывающий потенциальную потерю обратной совместимости при переходе на Joomla 4.
https://docs.joomla.org/Potential_backward_compatibility_issues_in_Joomla_4
Вчера вышла пятая бета Joomla 4. Разработчикам сторонних расширений уже сейчас стоит позаботиться о том, чтобы их расширения продолжали успешно работать и на Joomla 4.
Ниже вы найдете полный список изменений, описывающий потенциальную потерю обратной совместимости при переходе на Joomla 4.
https://docs.joomla.org/Potential_backward_compatibility_issues_in_Joomla_4
Использование Bootstrap в Joomla 4
Joomla 4 уже находится в стадии RC, не за горами выход стабильной версии. Поэтому начинаем потихоньку знакомиться с J4.
В этом материале рассмотрим, как правильно подключать Bootstrap в Joomla 4. Хотелось бы напомнить, что в Joomla 4 по умолчанию используется Bootstrap 5.
https://jpath.ru/docs/output/js-css/ispolzovanie-bootstrap-v-joomla-4
Joomla 4 уже находится в стадии RC, не за горами выход стабильной версии. Поэтому начинаем потихоньку знакомиться с J4.
В этом материале рассмотрим, как правильно подключать Bootstrap в Joomla 4. Хотелось бы напомнить, что в Joomla 4 по умолчанию используется Bootstrap 5.
https://jpath.ru/docs/output/js-css/ispolzovanie-bootstrap-v-joomla-4
jpath.ru
Использование Bootstrap в Joomla 4 - CMS Joomla для разработчиков
Как правильно подключать и использовать Bootstrap в Joomla 4.
Как правильно подключать JavaScript и CSS в Joomla 4
В Joomla 4 появилась концепция Web Assets, которая упорядочила работу с JavaScript и CSS в Joomla. По сути каждый отдельный JS или CSS файл представляет собой ассет (ресурс).
В этом материале расскажем:
- о реестре скриптов и стилей
- как правильно подключать скрипты и стили
- как определять их зависимости
- как их переопределять и отключать
- как создавать пресеты скриптов и стилей
- как создавать пользовательский класс ассета
https://jpath.ru/docs/output/js-css/kak-pravilno-podklyuchat-javascript-i-css-v-joomla-4
В Joomla 4 появилась концепция Web Assets, которая упорядочила работу с JavaScript и CSS в Joomla. По сути каждый отдельный JS или CSS файл представляет собой ассет (ресурс).
В этом материале расскажем:
- о реестре скриптов и стилей
- как правильно подключать скрипты и стили
- как определять их зависимости
- как их переопределять и отключать
- как создавать пресеты скриптов и стилей
- как создавать пользовательский класс ассета
https://jpath.ru/docs/output/js-css/kak-pravilno-podklyuchat-javascript-i-css-v-joomla-4
jpath.ru
Как правильно подключать JavaScript и CSS в Joomla 4 - CMS Joomla для разработчиков
Правильное подключение скриптов и стилей в Joomla
Подготовка расширения к переходу на Joomla 4
Joomla 4 уже здесь, но обновление не всегда проходит гладко. Чаще всего из-за сторонних расширений.
Это попытка собрать в одном месте решения наиболее часто встречающихся проблем при переходе на Joomla 4.
Есть повод задуматься, а стоит ли так спешить с переходом? Joomla 3 будет с нами как минимум до середины августа 2023 года.
https://jpath.ru/practice/podgotovka-rasshireniya-k-perekhodu-na-joomla-4
Joomla 4 уже здесь, но обновление не всегда проходит гладко. Чаще всего из-за сторонних расширений.
Это попытка собрать в одном месте решения наиболее часто встречающихся проблем при переходе на Joomla 4.
Есть повод задуматься, а стоит ли так спешить с переходом? Joomla 3 будет с нами как минимум до середины августа 2023 года.
https://jpath.ru/practice/podgotovka-rasshireniya-k-perekhodu-na-joomla-4
jpath.ru
Подготовка расширения к переходу на Joomla 4 - CMS Joomla для разработчиков
Пытаемся разобраться, какие изменения требуется внести в расширение Joomla, чтобы обеспечить совместимость с Joomla 4.
Подключение и размещение CSS стилей, JavaScript и изображений в Joomla
Разбираемся, как правильно размещать и подключать CSS, JavaScript и изображения в Joomla. В этом нам поможет класс HTMLHelper.
https://jpath.ru/docs/output/html-helpers/podklyuchenie-i-razmeshchenie-fajlov-css-javascript-i-izobrazhenij-v-joomla
Разбираемся, как правильно размещать и подключать CSS, JavaScript и изображения в Joomla. В этом нам поможет класс HTMLHelper.
https://jpath.ru/docs/output/html-helpers/podklyuchenie-i-razmeshchenie-fajlov-css-javascript-i-izobrazhenij-v-joomla
jpath.ru
CSS JS Image - подключение и размещение файлов - CMS Joomla для разработчиков
Использование класса HTMLHelper гарантирует, что подключение CSS, JavaScript и изображений в Joomla будет происходит одинаковым образом.
Как и для чего использовать Dependency Injection Containers в Joomla
Потихоньку перетаскиваем материалы с Хабра к себе 😊
Спасибо С.Толкачёву за первоначальную публикацию 🤝
https://jpath.ru/docs/basics/dependency-injection-containers
Потихоньку перетаскиваем материалы с Хабра к себе 😊
Спасибо С.Толкачёву за первоначальную публикацию 🤝
https://jpath.ru/docs/basics/dependency-injection-containers
jpath.ru
Dependency Injection Containers - CMS Joomla для разработчиков
Как и для чего стоит использовать Dependency Injection Containers в Joomla.
Forwarded from WebTolkRu (Sergey Tolkachyov)
Layouts и subLayouts в Joomla
В Joomla есть понятие layout. Это кусочек вёрстки, который можно многажды использовать в любом месте сайта: как в панели администратора, так и во фронтенде. Можно рассматривать лейауты как оторванные от контекста элементы дизайна. Находятся они в папке
1-й аргумент - это dot-separated (разделенный точками) путь к файлу лейаута. Название папки
"layouts" в данном случае пропускается как само собой разумеющееся. На скриншоте путь отмечен цифрами 1-4. Внутрь файла приходит массив
Либо же, если макет можно раздробить на более мелкие примитивы - тулбар с иконками разбить на отдельные иконки - то можно использовать метод
В первом примере кода мы "вошли" в лейаут icons. А в файле icons.php можно вызвать подмакеты. Для этого нужно создать рядом папку с таким же названием - icons. А в нём уже будут лежать файлы подмакетов.
Передавать туда можно как целиком
Также помним, что файлы из
Где это применимо? Да в принципе везде, хотя данный пример относится к разработке компонента.
@webtolkru
#joomla #development #php #разработка
В Joomla есть понятие layout. Это кусочек вёрстки, который можно многажды использовать в любом месте сайта: как в панели администратора, так и во фронтенде. Можно рассматривать лейауты как оторванные от контекста элементы дизайна. Находятся они в папке
layouts
в корне сайта. Как их использовать? Один из вариантов - использование LayoutHelper.use Joomla\CMS\Layout\LayoutHelper;
// $item - ваш объект или массив с данными, которые нужно использовать в верстке
echo LayoutHelper::render('components.swjprojects.project.icons', ['item' => $item]);
1-й аргумент - это dot-separated (разделенный точками) путь к файлу лейаута. Название папки
"layouts" в данном случае пропускается как само собой разумеющееся. На скриншоте путь отмечен цифрами 1-4. Внутрь файла приходит массив
$displayData
, в котором будет лежать наш $item
- $displayData['item']
.extract($displayData);
echo '<button role="button" class="btn btn-primary">'.$item->title.'</button>';
Либо же, если макет можно раздробить на более мелкие примитивы - тулбар с иконками разбить на отдельные иконки - то можно использовать метод
subLayout()
.В первом примере кода мы "вошли" в лейаут icons. А в файле icons.php можно вызвать подмакеты. Для этого нужно создать рядом папку с таким же названием - icons. А в нём уже будут лежать файлы подмакетов.
// icons.php
extract($displayData);
// обращаемся к /icons/downloads.php
echo $this->sublayout('downloads', $displayData);
// обращаемся к /icons/hits.php
echo $this->sublayout('hits', $displayData);
Передавать туда можно как целиком
$displayData
, так и какую-то часть от него. Тут уже как вам удобно. Также помним, что файлы из
layouts
подвержены переопределениями в шаблонах.Где это применимо? Да в принципе везде, хотя данный пример относится к разработке компонента.
@webtolkru
#joomla #development #php #разработка
Forwarded from Joomla Feed (Sergey Tolkachyov)
Как добавить свой таб или поле в интерфейс Joomla с помощью плагина. «Joomla way».
Задачи могут быть самые разные: поле аватара для пользователя в
Читать на Хабре
#joomla #php #разработка
Задачи могут быть самые разные: поле аватара для пользователя в
com_users
, дополнительный таб в форму редактирования материала, поле связи одной сущности с другой и т.д. Сразу оговорюсь, что бывает и "non-Joomla way" - то есть подходы, которые не предполагаются ядром CMS, но при этом и явно не запрещаются. Сейчас речь пойдёт о традиционном пути, который состоит из 2-х простых шагов.Читать на Хабре
#joomla #php #разработка
Используем Promise в Ajax-запросах
Небольшой пост о том, как можно эффективно строить асинхронные цепочки, добавив всего один флаг к вызову
#joomla #javascript #разработка
https://habr.com/ru/posts/858024/
Небольшой пост о том, как можно эффективно строить асинхронные цепочки, добавив всего один флаг к вызову
Joomla.request
, превратив его в Promise
.#joomla #javascript #разработка
https://habr.com/ru/posts/858024/
Хабр
Пост @b2z — Ajax — 12.11 18:46
Совет по Joomla: используем Promise в Ajax-запросах В статье Ajax-запросы нативными средствами Joomla было подробно разобрано, как с помощью Joomla.request можно легко создавать Ajax-запросы в Joomla....
Forwarded from Joomla Feed (Sergey Tolkachyov)
Как добавить свой повторяемый элемент интерфейса в класс HTMLHelper Joomla 4+
В API Joomla есть полезный инструмент - класс HTMLHelper. Он выводит HTML-элементы интерфейса с нужными параметрами: модальные окна, аккордеоны, табы, изображения и т.д. Для рендера мы передаём все нужные данные: заголовки окон, содержимое табов, атрибуты изображений.
Плюс использования HTMLHelper в Joomla - это его универсальность, оторванность от контекста, возможность использования логики при рендере в зависимости от вводных данных, его можно использовать везде. Но что если нам нужно создать свой собственный класс?..
Читать статью на Хабре
#разработка #php #joomla #development
В API Joomla есть полезный инструмент - класс HTMLHelper. Он выводит HTML-элементы интерфейса с нужными параметрами: модальные окна, аккордеоны, табы, изображения и т.д. Для рендера мы передаём все нужные данные: заголовки окон, содержимое табов, атрибуты изображений.
Плюс использования HTMLHelper в Joomla - это его универсальность, оторванность от контекста, возможность использования логики при рендере в зависимости от вводных данных, его можно использовать везде. Но что если нам нужно создать свой собственный класс?..
Читать статью на Хабре
#разработка #php #joomla #development
Forwarded from Joomla Feed (Sergey Tolkachyov)
Подготовка расширений к Joomla 6: CMSObject -> stdClass
В Joomla 6 метод
Устаревший способ
Как будет в Joomla 6
Соответствующий Pull Request уже принят в ветку Joomla 6.
PR на GitHub
#php #joomla #разработка #development #webdev
В Joomla 6 метод
getItem()
в Adminmodel
будет возвращать \stdClass
вместо CMSObject
. Это означает, что все устаревшие функции этого класса будут недоступны. Разработчики в Joomla 6 должны напрямую работать со свойствами объекта item и не использовать устаревшие методы set()
и get()
.Устаревший способ
$article = $app->bootComponent('content')->getMVCFactory()->createModel('Article', 'Administrator')->getItem(1);
echo $article->get('title');
Как будет в Joomla 6
$article = $app->bootComponent('content')->getMVCFactory()->createModel('Article', 'Administrator')->getItem(1);
echo $article->title;
Соответствующий Pull Request уже принят в ветку Joomla 6.
PR на GitHub
#php #joomla #разработка #development #webdev
Forwarded from Joomla Feed (Sergey Tolkachyov)
Триггеры ядра Joomla при CRUD-операциях
CRUD - аббревиатура основных операций с данными: создание (Create), чтение (Read), изменение (Update) и удаление (Delete). Практически все действия на сайте как в админке, так и пользовательской части можно описать этими действиями. Разработчикам при создании функционала часто в какие-то моменты этих действий нужно проделать некие действия с участием данных или без них.
Как найти нужное событие для своего плагина в Joomla подскажет эта статья.
Читать статью на Хабре
@joomlafeed
#разработка #php #development
CRUD - аббревиатура основных операций с данными: создание (Create), чтение (Read), изменение (Update) и удаление (Delete). Практически все действия на сайте как в админке, так и пользовательской части можно описать этими действиями. Разработчикам при создании функционала часто в какие-то моменты этих действий нужно проделать некие действия с участием данных или без них.
Как найти нужное событие для своего плагина в Joomla подскажет эта статья.
Читать статью на Хабре
@joomlafeed
#разработка #php #development
Forwarded from WebTolkRu (Sergey Tolkachyov)
E-mail шаблоны Joomla 5: добавление и просмотр своих переменных
В Joomla 5 появились настраиваемые email-шаблоны, как системные, так и сторонних компонентов. Их нельзя (пока что) добавить самостоятельно, они добавляются расширениями при установке. Но их можно отредактировать в Система - Шаблоны - Шаблоны писем. В настройках шаблонов писем (кнопка настроек компонента в верхнем правом углу) мы выбираем формат писем текст или HTML. Тогда становятся доступны настройки макетов шаблонов писем Joomla. Эти глобальные параметры можно переопределить в каждом конкретном email-шаблоне. Таким образом для каждого из email-шаблонов можно указать свою вёрстку и настройки логотипа.
Это, конечно, требует отдельной подробной статьи...
Для разработчиков: как добавить свои переменные для e-mail шаблонов Joomla?
Полезны окажутся 2 триггера для плагинов:
onMailBeforeRendering - триггер, который позволяет добавлять свои шорт-коды для строковой замены в плагине. Отдать туда надо массив вида
Также полезное свойство класса для передачи данных из плагина в лейаут письма для рендера -
```php
// Получаем текущий мейлер
$mailTemplate = $event->
$data = [
'
];
// с 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. Отдать туда нужно тот же самый массив, который отдавали в предыдущем триггере.
@webtolkru
#joomla #разработка #php #development #webdev
В 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
. Это ассоциативный массив. ```php
// Получаем текущий мейлер
$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. Отдать туда нужно тот же самый массив, который отдавали в предыдущем триггере.
@webtolkru
#joomla #разработка #php #development #webdev
Forwarded from Joomla Feed (Sergey Tolkachyov)
Добавляем свои переменные в шаблоны писем Joomla 5+
Это полноценная статья о создании плагина, который добавляет переменные-шорткоды для обработки в email-шаблонах Joomla. Кроме того, рассказывается и о том, как в качестве значений для шорт кодов использовать данные пользовательских полей
Статья написана участником нашего сообщества Александром Новиковым (@pro_portal).
Читать статью
Это творческий дебют автора, поэтому давайте поддержим его плюсами в карму👩💻 .
Плагин, о котором идёт речь в статье
joomLab MailAuthor: почтовые уведомления авторам материалов об изменении статуса публикации
Этот плагин позволит Вам реализовать функционал отправки почтового (e-mail) уведомления авторам материалов о статусе публикации их статей. При опубликовании материала или снятия с публикации, автор материала получит уведомление на почту.
Страница расширения
Это полноценная статья о создании плагина, который добавляет переменные-шорткоды для обработки в email-шаблонах Joomla. Кроме того, рассказывается и о том, как в качестве значений для шорт кодов использовать данные пользовательских полей
com_users
.Статья написана участником нашего сообщества Александром Новиковым (@pro_portal).
Читать статью
Это творческий дебют автора, поэтому давайте поддержим его плюсами в карму
Плагин, о котором идёт речь в статье
joomLab MailAuthor: почтовые уведомления авторам материалов об изменении статуса публикации
Этот плагин позволит Вам реализовать функционал отправки почтового (e-mail) уведомления авторам материалов о статусе публикации их статей. При опубликовании материала или снятия с публикации, автор материала получит уведомление на почту.
Страница расширения
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Добавляем свои переменные в шаблоны писем Joomla 5+
Шаблоны писем в Joomla. Вступление С недавнего времени (с выходом Joomla 4) в CMS Joomla появился замечательный функционал - шаблоны писем . Эти шаблоны позволяют администратору настроить "под себя"...
Forwarded from Joomla Feed (Sergey Tolkachyov)
Joomla Web Services Collection For Postman
Разработчикам мобильных и WEB-приложений (и не только) весьма и весьма пригодится готовая коллекция для Postman. В коллекцию добавлены endpoint для REST API Joomla, с параметрами и примерами запросов.
Коллекция составлена трудами французского Joomla-разработчика Alexandre J-S William ELISÉ.
Смотреть коллекцию
@jooomlafeed
#joomla #restapi #webdev #разработка
Разработчикам мобильных и WEB-приложений (и не только) весьма и весьма пригодится готовая коллекция для Postman. В коллекцию добавлены endpoint для REST API Joomla, с параметрами и примерами запросов.
Коллекция составлена трудами французского Joomla-разработчика Alexandre J-S William ELISÉ.
Смотреть коллекцию
@jooomlafeed
#joomla #restapi #webdev #разработка
Forwarded from WebTolkRu (Sergey Tolkachyov)
Joomla-разработчикам: обращение к методам модели в HtmlView напрямую
Когда-то, давным-давно в одной далёкой галактике кто-то решил, что что было бы неплохой идеей ввести косвенный доступ к методам модели (MVC) для получения данных, добавив метод
Но такой подход исключает любую возможность подсказки типов, аргументов и т. д. и делает все излишне сложным. Поэтому разработчики ядра Joomla объявили этот метод устаревшим с этим PR 44162.
Новый способ выглядит так:
Старый подход (то есть метод
1️⃣ осенью 2025г выйдет Joomla 6.
2️⃣ 2 года она будет основной веткой. Joomla 5 будет в режиме поддержки
3️⃣ через 2 года, в 2027 выйдет Joomla 7, в которой будет удалён этот метод.
4️⃣ но Joomla 6 будет ещё 2 года в режиме тех.поддержки и в ней (до 2029 года) этот метод останется.
Таким образом у разработчиков есть от 2,5 до 4,5 лет (на момент написания этого поста) на то, чтобы сделать этот рефакторинг.
👩💻👩💻 [5.3] Deprecate AbstractView::get() #44162
@webtolkru
#joomla #разработка #php #webdev
Когда-то, давным-давно в одной далёкой галактике кто-то решил, что что было бы неплохой идеей ввести косвенный доступ к методам модели (MVC) для получения данных, добавив метод
AbstractView::get()
. Этот метод извлекает модель и затем запускает get<Parameter>()
. Простыми словами, когда мы во 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, это означает, что:1️⃣ осенью 2025г выйдет Joomla 6.
2️⃣ 2 года она будет основной веткой. Joomla 5 будет в режиме поддержки
3️⃣ через 2 года, в 2027 выйдет Joomla 7, в которой будет удалён этот метод.
4️⃣ но Joomla 6 будет ещё 2 года в режиме тех.поддержки и в ней (до 2029 года) этот метод останется.
Таким образом у разработчиков есть от 2,5 до 4,5 лет (на момент написания этого поста) на то, чтобы сделать этот рефакторинг.
👩💻👩💻 [5.3] Deprecate AbstractView::get() #44162
@webtolkru
#joomla #разработка #php #webdev
Forwarded from Joomla Feed (Sergey Tolkachyov)
Please open Telegram to view this post
VIEW IN TELEGRAM
HTML Embed Code: