Developing Discourse Plugins - Part 1 - Create a basic plugin

Hmmmm. That’s a tricky one, because the symlink needed to be deleted, otherwise the Docker mount fails (as it cannot overwrite the existing file).

I had a bit of a google around for solutions, and found an interesting solution which would dereference the symlink and copy the symlink’s target into the specified directory, but couldn’t find anything that would create a Docker volume mount, thus preserving the dynamic link and bi-directional synchronisation. Happy to be steered towards a solution as this would be a neat feature to have.

Расскажите, как добавить вашу валидацию в модель app/models/user.rb?

1 лайк

Вы можете использовать обычный код Ruby для этого в вашем plugin.rb:

class ::User < ActiveRecord::Base
  validates_presence_of :your_attribute
end
6 лайков

Только начинаю свой первый маленький плагин :blush: У меня есть несколько вопросов, надеюсь, кто-то сможет помочь…

Первый вопрос: имеет ли значение, используем ли мы то, что указано в этом руководстве, или нам действительно стоит стремиться использовать генератор плагинов?

В этом руководстве это не рассматривалось, но как мы можем сделать данные доступными для наших шаблонов из файла plugin.rb?

Предположим, например, что я хочу отображать случайное приветственное сообщение в плагин-выходе topic-above-posts, когда кто-то посещает тему, причём сообщение выбирается случайно из массива в plugin.rb… как мне передать эти данные в шаблон? Который, как я также предполагаю, должен находиться здесь:

plugins/my_new_plugin/assets/javascripts/discourse/templates/connectors/topic-above-posts/my_new_plugin.hbs (Правильно ли я понимаю?)

Любые советы будут очень полезны :blush:

2 лайка

Использование генератора плагинов — это, как правило, отличный способ начать работу и понять, как должен быть структурирован плагин. Я рекомендую его.

Теперь о том, как добавить код Ruby во фронтенд: это два разных приложения. Фронтенд-приложение (Ember) должно каким-то образом запрашивать данные у сервера (Rails). Обычно мы делаем это через AJAX-запрос, но можно также добавить данные в SiteSerializer, чтобы они автоматически отправлялись вместе с данными форума.

В противном случае вам нужно будет изучить, как добавить маршрут и контроллер в Rails и отправлять сообщения в формате JSON.

8 лайков

Спасибо, Робин!

Не знаешь, есть ли какие-нибудь руководства по этой теме? Или, может быть, есть простой плагин (или даже тестовый плагин), который мог бы направить нас в правильном направлении? (Если нет, не мог бы ты быстро разместить это где-нибудь для нас? Думаю, это поможет многим людям :blush:)

Кстати, у тебя есть какие-то новые мысли насчёт написания книги? Если хочешь, я могу познакомить тебя с нужным человеком :smiley:

1 лайк

Спасибо за комплимент, но я определённо слишком занят, чтобы думать о написании книги. К тому же технические книги имеют ОЧЕНЬ ограниченную аудиторию. Те, кого я знаю и кто их писал, говорят, что делают это ради себя, а не ради денег :slight_smile:

Не могу придумать простого плагина для возврата чего-либо с серверной стороны. discourse-tooltips добавляет маршрут и затем использует его для получения предпросмотров тем при наведении курсора, так что это может быть полезно.

8 лайков

Скоро я начну разработку плагинов…

Вопрос:

Есть ли список hooks, в которые мы можем встроить plugin?

Например, если мы хотим написать плагин для обработки cooked данных в post перед их отображением, мы ожидаем, что будет хотя бы один hook в начале и один в конце, например:

  • display_post_start

  • display_post_complex

Тогда наш plugin сможет hook в код в hook location, выбранном нами выше.

Есть ли список этих plugin hooks и как они называются в DiscourseWorld?

Обновление: Нашел это:

git grep "plugin-outlet" -- "*.hbs"

Но я не вижу outlet для изменения cooked содержимого поста.

Существует ли руководство по созданию собственных outlet-ов, например, outlet для изменения cooked части постов?

2 лайка

Вы ищете это руководство, раздел decorateCooked():

5 лайков

Я использую этот шаблон для кастомного плагина. Нужно ли что-то изменить в связи с предстоящим переходом на Ember 5?

Думаю, нет? Хотя это просто линтер?

1 лайк

Скелет совместим с Ember 5. Однако, если вы добавили какой-либо JavaScript-код или HBS-шаблоны, вам необходимо проверить наличие устареваний, как описано в объявлении.

Да, содержимое package.json относится только к линтингу и не влияет на функциональность или совместимость плагина.

3 лайка

Пожалуйста, добавьте к этому:

rake plugin:create[plugin-name]

Я провёл сегодня слишком много времени, пытаясь найти Automating Discourse Plugin Setup with `create-discourse-plugin` gem (не уверен, как я мог забыть, что это название задачи rake?! :person_shrugging:)

5 лайков

Также стоит добавить примечание при использовании настройки Docker, так как приведённые выше инструкции могут завершиться ошибкой, похожей на:

ambientimpact:~/.../Discourse/discourse$ d/rake plugin:create[neurocracy-date-rewrite]
Cloning 'https://github.com/discourse/discourse-plugin-skeleton' to '/src/plugins/neurocracy-date-rewrite'...
Initializing git repository...
Initialized empty Git repository in /src/plugins/neurocracy-date-rewrite/.git/
Author identity unknown

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident name (for <discourse@localhost>) not allowed
rake aborted!
Command failed with exit 128: git
/src/lib/tasks/plugin.rake:354:in `system'
/src/lib/tasks/plugin.rake:354:in `block (2 levels) in <main>'
/src/lib/tasks/plugin.rake:344:in `chdir'
/src/lib/tasks/plugin.rake:344:in `block in <main>'
Tasks: TOP => plugin:create
(See full trace by running task with --trace)

Перед созданием плагина необходимо сначала настроить .gitconfig внутри контейнера (при необходимости измените адрес электронной почты и имя):

d/exec git config --global user.email "you@example.com"
d/exec git config --global user.name "Your Name"
d/rake plugin:create[plugin-name]
1 лайк