Discourseテーマに設定を追加する

Discourseでは、テーマ開発者がテーマに「設定」を追加し、サイト管理者がコードの行を変更したり、将来のテーマアップデートで変更が失われるのを心配したりすることなく、UIを通じてテーマをカスタマイズできる機能があります。

テーマはまた、特定のテーマ対応サイト設定を変更することもできます。これに関する詳細については、テーマ対応サイト設定トピックをご覧ください。

:heavy_plus_sign: テーマに設定を追加する

テーマに設定を追加することは、CSSやJSコードを追加することとは少し異なります。UIから行う方法はないためです。

設定を追加するには、テーマ用のリポジトリを作成し、リポジトリのルートフォルダに新しい settings.yaml(または settings.yml)ファイルを作成します。このファイルでは、YAML言語を使用してテーマ設定を定義します。

:loudspeaker: 注意: 開発プロセスを大幅に簡素化するTheme CLIを利用すると役立つかもしれません。

プラグイン開発に慣れている場合、これは新しい概念ではありません。プラグインにサイト設定を追加する方法とほぼ同じように動作します。設定ファイルに有効なYAMLを記述するだけで問題ありません。

有効なテーマ設定には、名前とデフォルト値が必要です。これが最小限の要件であり、以下のように見えます。

simple_setting: true

おそらくお分かりの通り、これにより simple_setting という名前の設定が作成され、デフォルト値として true が設定されます。

同様に、以下のような設定を追加することもできます。

site_name: My Forums
max_avatars: 7

これにより、デフォルト値が “My Forums” の文字列設定である site_name と、デフォルト値が 7 の整数設定である max_avatars の2つの設定が追加されます。

JSコードでは、settings.your_setting_key のようにして設定にアクセスできます。

ここまでは、設定を定義する最も簡単な方法について説明しました。次のセクションでは、さまざまな設定タイプとその使用方法についてもう少し詳しく説明します。

:symbols: サポートされるタイプ

設定には8つのタイプがあります。

  1. integer(整数)
  2. float(浮動小数点数)
  3. string(文字列)
  4. bool(ブール値)
  5. list(リスト)
  6. enum(列挙型)
  7. objectsjson_schemaの代替)
  8. upload(画像用)

以下のように、設定に type 属性を追加してタイプを指定できます。

float_setting:
  type: float
  default: 3.14

必ずしも明示的に type 属性を設定する必要があるわけではありません。Discourseは、設定のデフォルト値から設定タイプを自動的に判断するほど賢いため、上記の例を以下のように簡略化できます。

float_setting:
  default: 3.14

ただし、list および enum 設定を扱う場合は、タイプ属性を設定する必要があります。そうしないと、Discourseがそれらを正しく認識できません。

リスト設定:

whitelisted_fruits:
  default: apples|oranges
  type: list

列挙型設定:

favorite_fruit:
  default: orange
  type: enum
  choices:
    - apple
    - banana

リスト設定と列挙型設定の違いが明確でない場合は、以下を参照してください。列挙型設定では、テーマユーザーがあなたが定義した値のセット(choices 属性を参照)から 1つだけ の値を選択できます。

一方、リスト設定では、ユーザーが独自の値の リスト (つまり、配列)を作成できます。設定のデフォルト値のリストに値を追加したり、削除したりできます。縦棒 | 文字で値を結合して、設定のデフォルト値のリストを設定できます。上記の例のリスト設定を参照してください。

リスト設定の実用例は、Auto-Linkify Words で確認できます。

:loudspeaker: 注意: YAMLではスペースに非常に厳格であり、インデントが正しくない場合は構文エラーを発生させるため、YAMLを扱う際はインデントに注意してください。

objects タイプ

objects 設定タイプは、カスタム構造と検証を使用した高度な設定を実現できる特別なタイプです。このタイプについては別ドキュメントがあります。

:capital_abcd: 設定の説明とローカライズ

テーマ設定に説明文を追加でき、それは設定の直下にラベルとして表示されます。そのためには、以下のように設定に description 属性を追加するだけです。

whitelisted_fruits:
  default: apples|oranges
  type: list
  description: "このテキストはこの設定の下に表示され、設定の機能を説明します!"

そして、以下のような結果になります。

複数言語サポート

複数の言語を知っており、テーマにそれらの言語のサポートを追加したい場合は、Discourseがその言語をサポートしている限り、完全に可能です。

まず、サポートしたい言語が以下のリストに含まれていることを確認してください。

Languages list
コード 名前
ar اللغة العربية
bs_BA bosanski jezik
ca català
cs čeština
da dansk
de Deutsch
el ελληνικά
en English
es Español
et eesti
fa_IR فارسی
fi suomi
fr Français
gl galego
he עברית
id Indonesian
it Italiano
ja 日本語
ko 한국어
lv latviešu valoda
nb_NO Norsk bokmål
nl Nederlands
pl_PL język polski
pt Português
pt_BR Português (BR)
ro limba română
ru Русский
sk slovenčina
sq Shqip
sr српски језик
sv svenska
te తెలुగు
th ไทย
tr_TR Türkçe
uk українська мова
ur اردو
vi Việt Nam
zh_CN 中文
zh_TW 中文 (TW)

(リストに言語がない場合は、How to add a new language を参照してください)

次に、上記のリストから言語コードを見つけ、description 属性の下に言語コードをキーとして、そのキーの値として翻訳を設定します。

whitelisted_fruits:
  default: apples|oranges
  type: list
  description:
    en: English text
    ar: نص باللغة العربية
    fr: Texte français

これで、英語、アラビア語、フランス語の3つの言語をサポートできるようになります。

追加の設定属性とオプション

MinおよびMax属性

場合によっては、ユーザーがテーマやサイト全体を誤って壊さないようにするために、設定値が超えてはいけない制限を指定する必要があるかもしれません。

制限を指定するには、以下のように設定に min または max、または両方の属性を追加するだけです。

integer_setting:
  default: 10
  min: 5
  max: 100

integerfloat、および string タイプの設定に制限を指定できます。integer および float 設定の場合、設定値自体が制限と比較されます。string 設定の場合、値の長さが指定された制限と比較されます。

ユーザーが許可された範囲外の値を入力しようとすると、最小値と最大値を示すエラーが表示されます。

JS/CSS/Handlebarsでの設定へのアクセス

テーマ設定は、テーマのJavaScriptファイルで settings 変数としてグローバルに利用可能です。例えば、以下のようにします。

// {theme}/javascripts/discourse/api-initializers/init-theme.gjs
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  console.log("settings are", settings);
});

この settings オブジェクトは、.gjs <template> タグ内でも通常通り使用できます。

CSS変数の設定

CSSでは、テーマの各設定に対して変数が作成され、各変数はその設定と同じ名前を持ちます。

したがって、global_font_size という浮動小数点数設定と site_background という文字列設定がある場合、テーマのCSSで以下のようにできます。

html {
  font-size: #{$global-font-size}px;
  background: $site-background;
}

グループメンバーシップの解決

テーマコンポーネントは、現在のユーザーが設定されたグループに属しているかどうかに基づいて、機能を表示または非表示にする必要がある場合があります。これのために currentUser.groups をチェックしないでください。これは、ユーザーに見えるグループのみを含み、非表示のグループを見逃す可能性があるためです。

グループベースのリスト設定の場合、resolve_group_membership: true を追加して、サーバー側でチェックを解決します。

copy_button_allowed_groups:
  default: "1|3"
  type: list
  list_type: group
  resolve_group_membership: true

このオプションは、設定が type: list および list_type: group を持つ場合にのみ有効です。有効にすると、フロントエンドの settings オブジェクトには元のグループリストが含まれません。代わりに、Discourseは同じ設定名に user_in_ を接頭辞として付けたブール値を追加します。

// {theme}/javascripts/discourse/api-initializers/init-theme.gjs
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  if (!settings.user_in_copy_button_allowed_groups) {
    return;
  }

  // ユーザーは選択されたグループの少なくとも1つに属しています。
});

生成されたブール値は、logged_in_usersanonymous_users などの自動グループでも機能します。

:link: 関連トピック


このドキュメントはバージョン管理されています。変更を提案するには GitHub をご利用ください。

「いいね!」 54

このセクションを、以下についての内容に置き換えるべきか検討しています: Objects type for theme setting

おそらく、このドキュメントから以下への参照も必要になるでしょう: Migrate Discourse theme settings

「いいね!」 5

はい。新しい改良された方法を知っていたにもかかわらず、json_schemas を機能させようとして 1 時間近く無駄にしました。

@Osama、ご自身で更新できない場合は、できる人に依頼してください。よろしくお願いします。

「いいね!」 4

申し訳ありません。ドキュメントを更新するためのPRはこちらです: Replace references to `json_schema` with `objects` type documentation by OsamaSayegh · Pull Request #26 · discourse/discourse-developer-docs · GitHub

「いいね!」 3

テーマ設定のアップロードフィールドのデフォルト値として、アセットとして定義された画像を使用するにはどうすればよいですか?

残念ながら、以下は機能しません。これ専用のメソッドがあるのか、あるいは実際に可能なのでしょうか?

デフォルト値として使用するために、アセットURLを動的に取得する方法はありますか?

// about.json
{
  "assets": {
    "box_default_image": "assets/box-default-image.png"
  }
}
# settings.yml

box_image:
  type: upload
  default: settings.theme_uploads.box_default_image
「いいね!」 1

about.json からのキーを試しましたか?

# settings.yml

box_image:
  type: upload
  default: "box_default_image"
「いいね!」 1

@moin 完璧に機能します!ありがとうございます!

「いいね!」 1