Насколько «сложно» модифицировать или расширять Discourse для backend-разработчика

Привет,

Я MLE с опытом бэкенд-разработки. Мои навыки фронтенда отсутствуют или очень слабы.

Меня интересует размещение небольшого форума, который должен включать следующие функции:

  • Удобная фильтрация постов по нескольким тегам
  • Скрытие определённых категорий до входа пользователя в систему
  • Необходимость одобрения регистраций администратором
  • Возможная установка фото-карусели в верхней части сайта

Сложно ли реализовать подобные вещи? Я изучал код некоторых плагинов, и хотя сама реализация выглядит короткой и понятной, писать её, кажется, непросто.

Я в том же положении, что и вы. У меня есть опыт работы с бэкендом на Node.js. Я немного занимался фронтендом (HTML/CSS/JavaScript), но гораздо больше — бэкендом. Здесь много кода, который, кажется, специфичен для Discourse, Ruby или написан в очень специфичном стиле. Даже зная JavaScript, я нахожу код Discourse пугающе сложным. Я серьёзно думаю о запуске локальной ИИ-модели, чтобы загрузить в неё весь код и задавать вопросы о том, что мне нужно сделать. Кроме этого, я могу только читать существующий код, плагины и т. д., пытаясь как можно лучше в них разобраться. Если вы заинтересованы в обмене знаниями или совместном обучении, я открыт к этому :slight_smile:

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

встроены в ядро Discourse, а

можно реализовать с помощью существующих компонентов темы.

Я бы всё отдал за видеокурсы по развитию дискурса на Udemy. Просто скажи, кому кинуть деньги. :dollar_banknote::dollar_banknote::dollar_banknote:

Нет необходимости что-то настраивать вручную — это уже поддерживается API. И вы можете делать это прямо из интерфейса! Я создал «виджет» (компонент Glimmer!) специально для этого:

Этот компонент работает в блоках правой боковой панели и макетах.

Можно ли использовать это для создания вложенной иерархии?

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

Было бы здорово, если бы они всё ещё могли ориентироваться во вложенных структурах, как в традиционных форумах.

Для вложенности используйте категории.

Многие экземпляры Discourse используют эту функцию, например:

Не по теме, но это было очень удобно здесь. Мне нравится наша функция «Объяснить с помощью ИИ».

В данном контексте «MLE» означает инженера по машинному обучению (Machine Learning Engineer). Это специалист, который занимается использованием данных и алгоритмов для создания моделей, позволяющих машинам выполнять задачи без явного программирования под эти конкретные задачи. Обычно у них прочная база в области информатики, статистики и программирования, и их экспертиза чаще сосредоточена на бэкенд-аспектах технологий, таких как разработка и развёртывание предиктивных моделей и других продуктов машинного обучения. Когда автор оригинального сообщения упоминает «MLE», он указывает, что является инженером по машинному обучению, знакомым с бэкенд-разработкой, но не имеющим опыта во фронтенд-разработке.

Несколько мыслей по этому поводу.

Разработка платных курсов по 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.

Вот упрощенная версия того, что происходит:

  1. При запуске Discourse выполняет все инициализаторы.

  2. Функция apiInitializer создает инициализатор, который запускается после инициализатора "inject-objects".

  3. Когда этот инициализатор выполняется, он вызывает функцию withPluginApi, передавая параметры version, cb и opts.

  4. Функция 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.

Я бы подумал, что для пожилых людей будет проще, если категорий будет меньше и иерархия не такая сложная.

Если у вас нет большого трафика, интересного лишь узкому кругу людей, то, скорее всего, вам не нужно множество категорий.