Несколько мыслей по этому поводу.
Разработка платных курсов по Discourse
Идея курсов, связанных с разработкой под Discourse на таких платформах, как Udemy или Coursera, интересна. Я предполагаю, что основные проблемы заключаются в том, что вне команды Discourse не так много людей, которые были бы квалифицированы для создания курса по разработке под Discourse, и что потенциальное количество студентов для такого курса довольно невелико. Тем не менее, я уверен, что хороший курс по разработке тем или плагинов для Discourse со временем сможет привлечь достаточно студентов, чтобы оправдать усилия по его созданию.
Также существует возможная проблема: платные курсы по Discourse могут противоречить духу этого форума. Но я лишь строю догадки на этот счет.
Уроки по разработке под Discourse
Я считаю, что наблюдение о том, что реализация многих плагинов, тем и компонентов тем Discourse довольно проста, верно. Как и при разработке для других платформ, проблема заключается в том, чтобы преодолеть первоначальный барьер непонимания того, как части системы работают вместе. Команда Discourse (или другие квалифицированные разработчики) могла бы помочь в этом, написав несколько уроков, которые шаг за шагом проведут вас через весь процесс создания функциональных тем, компонентов тем и плагинов. Например, пошаговое руководство по созданию чего-то вроде компонента темы Discourse Placeholder.
Я понимаю, что это потребует значительных затрат времени, поэтому такая инициатива должна соответствовать бизнес-целям Discourse.
Доступные ресурсы
При небольшом поиске в этом форуме можно найти множество полезной информации о разработке под Discourse. Изучение примеров кода в репозитории Discourse на GitHub — также отличный способ научиться.
Не стоит игнорировать и недавний инструмент — GitHub Copilot. Если правильно настроить среду разработки, он может помочь понять, как разрабатывать темы и плагины для Discourse. Для разработки тем Discourse лучший подход, который я нашел, — это разработка темы (с помощью Discourse Theme CLI) в корневом каталоге локальной установки Discourse. Такая структура дает Copilot легкий доступ к кодовой базе Discourse. (Обратите внимание, что при разработке плагинов папка plugins уже находится в корневом каталоге /discourse.) (Также отмечу, что я могу ошибаться насчет того, действительно ли Copilot имеет доступ к кодовой базе Discourse, которую я загрузил в свою IDE. В любом случае, полезно иметь основной код Discourse под рукой для собственных справок.)
Чтобы избежать отвлекающих факторов и сосредоточиться на использовании Copilot как инструмента для обучения, я отключаю завершение кода Copilot в своей IDE (VS Code) и взаимодействую с ним только через чат. Вот пример того вида помощи, которую он может предоставить. (shopify.js — это файл, созданный Theme CLI в директории /javascripts/discourse/api-initializers/ моей темы.)
Разговор с Copilot
scossar: Можешь объяснить, что делает экспорт по умолчанию в shopify.js? По сути, это шаблонный код, который предоставляется Discourse при создании темы с помощью discourse_theme gem. Я изменил шаблонный код так, чтобы он фиксировал каждое изменение страницы. Я понимаю вызов api.onPageChange, но у меня нет четкого понимания того, как объект api внедряется в мой код.
GitHub Copilot: Объект api внедряется в ваш код через функцию withPluginApi, которая вызывается в методе initialize объекта, возвращаемого apiInitializer.
Вот упрощенная версия того, что происходит:
-
При запуске Discourse выполняет все инициализаторы.
-
Функция apiInitializer создает инициализатор, который запускается после инициализатора "inject-objects".
-
Когда этот инициализатор выполняется, он вызывает функцию withPluginApi, передавая параметры version, cb и opts.
-
Функция withPluginApi проверяет, совместима ли текущая версия Discourse с указанной версией. Если да, она вызывает обратную функцию (cb) и передает экземпляр PluginApi в качестве аргумента. Этот экземпляр PluginApi — это объект api, который вы видите в своем коде.
Таким образом, объект api является экземпляром PluginApi, и он передается вашему коду функцией withPluginApi. Этот объект предоставляет множество методов для взаимодействия с Discourse, таких как onPageChange, который вы уже используете.
scossar: Значит, функция, которая является вторым аргументом экспорта по умолчанию в shopify.js, — это обратная функция, принимаемая apiInitializer?
GitHub Copilot: Да, всё верно. Вторым аргументом для apiInitializer является обратная функция. Эта функция вызывается с экземпляром PluginApi в качестве аргумента при запуске инициализатора (при условии, что текущая версия Discourse совместима с указанной версией). Именно так объект api становится доступным в вашем файле shopify.js.
После того как я разобрался с этим…
scossar: …Еще одна мысль: можно ли использовать api.decorateCooked для внедрения iframe с рейтингами, размещенного на внешнем приложении (например, на приложении Shopify, которое я разрабатываю)?
GitHub Copilot: Да, вы можете использовать api.decorateCooked для внедрения iframe в сообщение. Вот грубый пример того, как это можно сделать:
api.decorateCooked($elem => {
const postId = $elem.data('post-id');
const iframe = document.createElement('iframe');
iframe.src = `https://your-app.com/ratings?post_id=${postId}`;
iframe.width = '100%';
iframe.height = '200'; // при необходимости измените
$elem.append(iframe);
}, { id: 'rating-iframe' });
В этом примере api.decorateCooked используется для добавления iframe к каждому сообщению. Источник iframe устанавливается на URL вашего внешнего приложения, с включенным идентификатором сообщения в качестве параметра запроса. Вам нужно заменить 'https://your-app.com/ratings' на фактический URL вашей страницы рейтингов.
Обратите внимание, что это упрощенный пример. Возможно, вам придется адаптировать его под свои нужды, и вы обязательно должны добавить обработку ошибок и другие необходимые меры предосторожности, чтобы обеспечить корректную и безопасную работу.
В настоящее время нереально ожидать, что Copilot напишет весь ваш код, но это отличный инструмент для обучения написанию кода для Discourse.