Discourse включает в себя сотни Plugin Outlets, которые можно использовать для вставки нового контента или замены существующего контента в интерфейсе Discourse. Аргументы аутлета (Outlet arguments) доступны для того, чтобы контент мог быть настроен в зависимости от контекста.
Выбор аутлета
Чтобы найти имя плагин-аутлета, выполните поиск по ядру Discourse на строку “<PluginOutlet” или используйте компонент темы plugin outlet locations. (например, topic-above-posts).
Обёрточные аутлеты (Wrapper outlets)
Некоторые аутлеты в ядре выглядят как <PluginOutlet @name="foo" />. Они позволяют вставлять новый контент. Другие аутлеты «обёртывают» существующую реализацию в ядре, как показано ниже:
<PluginOutlet @name="foo">
реализация в ядре
</PluginOutlet>
Определение коннектора для такого «обёрточного» аутлета заменит реализацию в ядре. Только одна активная тема или плагин может предоставлять коннектор для обёрточного плагин-аутлета.
Для обёрточных плагин-аутлетов вы можете отобразить исходную реализацию в ядре, используя ключевое слово {{yield}}. Это может быть полезно, если вы хотите заменить реализацию в ядре только при определённых условиях или если вы хотите обернуть её в что-то другое.
Определение коннектора
После того как вы выбрали аутлет, придумайте имя для вашего коннектора. Оно должно быть уникальным среди всех тем и плагинов, установленных в данном сообществе. Например: brand-official-topics
В вашей теме или плагине определите новый коннектор .gjs с путём, оформленным следующим образом:
![]()
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
![]()
{plugin}/assets/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
Содержимое этих файлов будет отображаться как компонент Ember. Для общей информации об Ember и формате .gjs, ознакомьтесь с руководствами по Ember.
Для нашего гипотетического коннектора «brand official topics» файл может выглядеть так:
<template>
<div class="alert alert-info">
Эта тема была создана членом
<a href="https://discourse.org/team">команды Discourse</a>
</div>
</template>
Использование аргументов аутлета
Plugin Outlets предоставляют информацию об окружающем контексте через @outletArgs. Аргументы, передаваемые каждому аутлету, различаются. Простой способ просмотреть аргументы — добавить это в ваш шаблон:
{{log @outletArgs}}
Это запишет аргументы в консоль разработчика вашего браузера. Они появятся как объект Proxy — чтобы изучить список аргументов, разверните [[Target]] прокси.
В нашем примере topic-above-posts отображаемая тема доступна по @outletArgs.model. Таким образом, мы можем добавить имя пользователя члена команды следующим образом:
<template>
<div class="alert alert-info">
Эта тема была создана
{{@outletArgs.model.details.created_by.username}}
(членом
<a href="https://discourse.org/team">команды Discourse</a>)
</div>
</template>
Добавление более сложной логики
Иногда простого шаблона недостаточно. Чтобы добавить логику JavaScript в ваш коннектор, обновите ваш файл .gjs, чтобы он экспортировал компонент на основе класса. Это работает так же, как и любое другое определение компонента, и может включать инъекции сервисов.
В нашем примере topic-above-posts мы можем захотеть отображать пользователя по-разному в зависимости от настройки сайта «prioritize username in ux». Файл .gjs может выглядеть примерно так:
.../connectors/topic-above-posts/brand-official-topic.gjs:
import Component from "@glimmer/component";
import { service } from "@ember/service";
export default class BrandOfficialTopics extends Component {
@service siteSettings;
get displayName() {
const user = this.args.outletArgs.model.details.created_by;
if (this.siteSettings.prioritize_username_in_ux) {
return user.username;
} else {
return user.name;
}
}
<template>
<div class="alert alert-info">
Эта тема была создана
{{this.displayName}}
(членом
<a href="https://discourse.org/team">команды Discourse</a>)
</div>
</template>
}
Условное отображение
Если вы хотите, чтобы ваш контент отображался только при определённых условиях, часто достаточно обернуть ваш шаблон в блок {{#if}} handlebars. Если этого недостаточно, вы можете использовать хук shouldRender, чтобы контролировать, будет ли отображаться шаблон вашего коннектора вообще.
Сначала убедитесь, что у вас есть коннектор .gjs на основе класса, описанный выше. Затем добавьте функцию static shouldRender(). Расширяя наш пример:
import Component from "@glimmer/component";
export default class BrandOfficialTopics extends Component {
static shouldRender(outletArgs, helper) {
const firstPost = outletArgs.model.postStream.posts[0];
return firstPost.primary_group_name === "team";
}
// ... (любая другая логика)
<template>
{{! ... }}
</template>
}
Теперь коннектор будет отображаться только тогда, когда первый пост в теме был создан членом команды.
shouldRender оценивается в контексте автотрекинга Glimmer. Будущие изменения любого из упомянутых свойств (например, outletArgs) вызовут повторную оценку функции.
Введение новых аутлетов
Если вам нужен аутлет, который ещё не существует, пожалуйста, не стесняйтесь создавать pull request или открыть тему в Development.
Этот документ находится под контролем версий — предложите изменения на github.