ホームページにのみ表示されるカスタムコンテンツを追加する

テーマ開発者として非常によく遭遇する状況は、コミュニティのホームページでのみ表示されるコンテンツを作成する必要がある場合です。

テーマの「ヘッダーの後 (After Header)」セクションにHTMLを追加すると、それがすべてのページに表示されます。ホームページ以外ではすべて非表示にするためにCSSでいくつかの工夫をすることもできますが、代わりにDiscourseテーマを使用して、ホームページでのみ表示されるコンテンツを持つコンポーネントを作成しましょう。

Discourseテーマに慣れていない場合は、Beginner's guide to using Discourse Themes および Structure of themes and theme components を参照してください。

Discourseテーマでは、次のディレクトリ構造を設定する必要があります。

:file_folder: javascripts/discourse/components/
:file_folder: javascripts/discourse/connectors/

ここからEmberコンポーネントを作成します。Emberコンポーネントの詳細については、ドキュメント Ember.js Guides - Guides and Tutorials - Ember Guides を参照してください。

しかし、今回はシンプルなコンポーネントを作成します。このコンポーネントは、ロジックを含む1つのファイルと、テンプレートを含むもう1つのファイルの2つのファイルで構成されます。

:page_facing_up: javascripts/discourse/components/custom-homepage-content.js

import Component from "@glimmer/component";
import { service } from "@ember/service";
import { defaultHomepage } from "discourse/lib/utilities";

export default class CustomHomepageContent extends Component {
  @service router;

  get isHomepage() {
    const { currentRouteName } = this.router;
    return currentRouteName === `discovery.${defaultHomepage()}`;
  }
}

これにより isHomepage ゲッターが作成され、ルーターサービスで currentRouteName をチェックします。ルート名がホームページ(サイト設定で指定)と一致する場合、true を返します。

次にテンプレートが必要です。

:page_facing_up: javascripts/discourse/components/custom-homepage-content.hbs

{{#if this.isHomepage}}
  <h1>これは私のホームページのHTMLコンテンツです</h1>
{{/if}}

テンプレートは isHomepage ゲッターをチェックし、true の場合にコンテンツを表示します。{{#if}} ブロックの間に好きなHTMLを追加できます。

コンポーネントが作成されたので、Discourseのどこかに追加する必要があります。このステップでは、どのプラグインアウトレットを利用するかを決定する必要があります。これらはDiscourseのさまざまな領域で、開発者がフックできるように少量のコードが追加されている場所です。GitHubでこれらを検索するか、(deprecated) Plugin outlet locations theme component を使用して閲覧できます。

カスタムホームページの場合、above-main-container は一般的な選択肢なので、それを使用しましょう。

正しいディレクトリにコネクタファイルを作成する必要があります。

:page_facing_up: javascripts/discourse/connectors/above-main-container/custom-homepage-connector.hbs

<CustomHomepageContent />

:point_up: これで完了です。コンポーネントを呼び出すための1行だけが必要です :tada:


このドキュメントはバージョン管理されています - 変更提案はgithubでお願いします。

「いいね!」 47

@awesomerobot様

ご説明ありがとうございます。ご提案いただいた手順を試しましたが、実装した after_header が投稿詳細ページに表示されたままです。これをホームページにのみ表示されるように修正するにはどうすればよいでしょうか?

「いいね!」 1

こんにちは、@Corneliusさん、あなたのコードを見てもよろしいですか?

「いいね!」 2

ヘッダータグにすべてを詰め込むのではなく、ファイルシステムの現代的な使い方に合わせてこれを書き直すと素晴らしいでしょう。

テーマに関するこれらの古いガイドのほとんどは、現在のやり方には時代遅れです。

「いいね!」 7

はい、これはかなり古くなっていました!リモートテーマと最新のEmberコンポーネントの構造を反映するように更新しました。

「いいね!」 6

素晴らしいですね!

そして、そのgetterは、このhttp://ember-cli-page-object.js.org/docs/v1.11.x/api/getter.htmlと同じものですか? 危険なほど少ししか知りません。もし同じであれば、OPを編集してリンクを追加します。

「いいね!」 3

@awesomerobot krisさん、Discourseをローカルにインストールしました。Discourseのローカルインスタンスにこれらのファイルを追加するには、正しいパスは何ですか?ローカルインスタンスに新しいテーマコンポーネントを追加したいと考えています。

「いいね!」 1

テーマコンポーネントを作成し、ux を介してインストールします。

テーマまたはテーマコンポーネントのインストール

テーマの構築に役立つ Discourse Theme CLI コンソール アプリのインストール

「いいね!」 4

ホームページをカテゴリビューの上に構築した場合、ホームページのURLではない「/categories」にアクセスしても、カスタムコンテンツが表示されます。これをルートURL「/」に限定したいと考えています。以前のコードはそうしていたと思いますが、「defaultHomepage()」でそれができるのか疑問です。

「いいね!」 3

discovery.${defaultHomepage()} は、top-menu 設定でランディングルートとして設定されたルートに一致します。ルートURLの / と、/categories のような特定のルートの両方に一致します。

私の経験では、defaultHomepage() に基づいてカスタムホームページを構築する際に、2つの複雑な問題があります。

  • それが構築されるルートは、プレーンなリストビューとしてはもはや利用できません。
  • メンバーはインターフェース設定で独自のデフォルトホームページを設定できます。したがって、その機能を無効にするか、トップメニューのルートのいずれかで機能するホームページの概念を持つ必要があります。

ルートURLのみでカスタムホームページを構築するには、router.currentURL === '/' をチェックできます。デフォルトでは、これはルートURL / にのみ一致し、トップメニュー設定で設定されたランディングルートには一致しません。しかし、現在サイドバーリンクには、指定されたURLをルートに一致させるロジックがあります。そのため、デフォルトではサイドバーリンクでは機能しません。これについてはトピックを投稿しました。URLをルートに解決しないサイドバーリンクはありますか?

私の理解では、現在、トップメニューのルートをターゲットにするか、サイドバーで問題が発生するかのいずれかを除いて、ルートURLでカスタムホームページを構築するデフォルトの方法はありません。そのオプションがあると素晴らしいでしょう。

「いいね!」 4

はい、/ と対応する /route が異なるコンテンツをレンダリングできるというのは、長年のハックのようなものです。以下のようなToDoがあります。

  1. top_menu 設定とは独立してホームページを設定できるようにする
  2. 既存のルートを乗っ取ることなくカスタマイズできる、新しいスタンドアロンのホームページテンプレートを追加する

現時点ではカスタムホームページは非常に一般的なリクエストなので、ここでもっと柔軟性を持たせることは間違いなく可能です。

「いいね!」 6