Add custom content that only appears on your homepage

A very common situation you’ll find yourself in as a theme developer is the need to create content that only shows on the homepage of your community.

You might add some HTML to the “After Header” section of your theme, which will then appear on every page. You can jump through some hoops in CSS to hide this everywhere except the homepage… but instead let’s use a Discourse theme to create a component with content that is only visible on your homepage.

If you’re unfamiliar with Discourse themes check out Beginner's guide to using Discourse Themes and Structure of themes and theme components

In your Discourse theme you’ll need to setup the following directory structure:

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

From here we’re going to create an Ember component. You can find more about Ember components from their documentation: Ember.js Guides - Guides and Tutorials - Ember Guides

But for now this will be a simple component. The component will consist of two files, one containing the logic and another the template.

: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()}`;
  }
}

This creates a isHomepage getter, which checks the router service for the currentRouteName — if the route name matches your homepage (as dictated by site settings) then it will return true

Now we need our template

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

{{#if this.isHomepage}}
  <h1>This is my homepage HTML content</h1>
{{/if}}

The template checks the isHomepage getter, and will display your content if it’s true. You can add any HTML you want between the {{#if}} blocks.

Now that our component is created, we need to add it to Discourse somewhere. For this step you’ll need to decide which plugin outlet to utilize. These are areas throughout Discourse where we’ve added a little code for developers to hook into. You can search Discourse for these on Github, or browse for them using the (deprecated) Plugin outlet locations theme component.

For custom homepages, above-main-container is a common choice, so let’s use that.

We need to create our connector file in the correct directory:

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

<CustomHomepageContent />

:point_up: and that’s all, it just needs a single line calling for your component :tada:


This document is version controlled - suggest changes on 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