添加仅显示在您的主页的自定义内容

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 本地实例中,添加这些文件的正确路径是什么?我想在 discourse 的本地实例中添加一个新的主题组件。

1 个赞

您将创建自己的主题组件并通过 ux 进行安装。

安装主题或主题组件

安装 Discourse 主题 CLI 控制台应用程序以帮助您构建主题

4 个赞

如果我在分类视图之上构建我的主页,即使我转到/categories(而不是主页URL),我仍然会得到我的自定义内容。我希望将其限制在根URL/,我相信之前的代码就是这样做的,但我想知道defaultHomepage()是否应该这样做。

3 个赞

discovery.${defaultHomepage()} 将匹配由 top-menu 设置设定的着陆路由。它将同时匹配根 URL / 和特定路由,例如 /categories

根据我的经验,在使用 defaultHomepage() 构建自定义主页时,有两个复杂问题:

  • 它所基于的路由不再可用作纯列表视图。
  • 用户可以在其界面设置中设置自己的默认主页。因此,要么需要禁用该功能,要么需要有一个主页概念,该概念适用于任何顶部菜单路由。

要仅在根 URL 上构建自定义主页,可以检查 router.currentURL === '/'。默认情况下,这仅匹配根 URL /,而不匹配顶部菜单设置中设置的着陆路由。但是,侧边栏链接现在具有逻辑,可以尝试将给定的 URL 与路由匹配。因此,默认情况下它在侧边栏链接上不起作用。我刚刚发布了一个关于此的帖子:Can I have sidebar links that don’t resolve an url to a route?

据我所知,目前没有默认方法可以在根 URL 上构建自定义主页,而又不影响顶部菜单的路由或遇到侧边栏问题。如果能提供该选项将是极好的。

4 个赞

是的,/ 和相应的 /route 可以渲染不同内容的这种做法已经存在很长时间了。我们有一个待办事项:

  1. 允许主页独立于 top_menu 设置进行设置
  2. 添加一个新的独立主页模板,无需接管现有路由即可进行自定义

自定义主页目前是一个非常常见的请求,因此我们肯定需要在这里提供更多灵活性。

6 个赞