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

Discourse では、テーマに「設定」を追加する機能が備わっています。テーマ開発者がこれらを設定することで、サイト管理者はコードを1行も変更することなく、UIを通じてテーマをカスタマイズできます。また、将来のテーマ更新時に設定が上書きされて失われる心配もありません。

テーマは、特定のテーマ対応サイト設定を変更することもできます。詳細については、Themeable site settings トピックを参照してください。

: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

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

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

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

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

設定には9つのタイプがあります:

  1. integer
  2. float
  3. string
  4. bool(ブール型)
  5. list
  6. enum
  7. objectsjson_schema の代替)
  8. upload(画像用)
  9. icon(Discourse アイコンセットからの単一のアイコン)

設定に type 属性を追加することで、タイプを指定できます。例:

float_setting:
  type: float
  default: 3.14

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

float_setting:
  default: 3.14

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

List Setting:

whitelisted_fruits:
  default: apples|oranges
  type: list

Enum Setting:

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

list 設定と enum 設定の違いが明確でない場合のために説明します。enum 設定では、テーマユーザーが、あなたが定義した値のセット(choices 属性を参照)から 1つだけ の値を選択できます。

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

list 設定の実用的な使用例は、こちらで確認できます:Auto-Linkify Words.

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

Icon Setting:

banner_icon:
  default: bullhorn
  type: icon

Icon 設定は、サイト管理者に検索可能なアイコンピッカーを提供し、値はアイコン名になります。Discourse は選択されたアイコンをスプライトシートに追加するため、別途登録せずにテーマ内でレンダリングできます。

objects タイプ

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

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

テーマ設定に説明テキストを追加できます。これは設定の直下にラベルとして表示されます。これを行うには、設定に description 属性を以下のように追加します:

whitelisted_fruits:
  default: apples|oranges
  type: list
  description: "This text will be displayed under this setting and it explains what the setting does!"

すると、以下のように表示されます:

多言語サポート

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

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

Languages list
Code Name
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

integerfloatstring タイプの設定に制限を指定できます。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 という float 設定と site_background という string 設定がある場合、テーマの CSS で以下のようなことをできます:

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

グループ所属の解決

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

グループベースの list 設定では、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 などの自動グループでも機能します。オブジェクトテーマ設定では、type: groups プロパティで同じオプションを使用できます。詳細は objects type for theme settings を参照してください。

: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