添加仅在您的主页上显示的内容

作为主题开发者,您会遇到的一个非常常见的情况是需要创建仅在社区主页上显示的内容。

您可能会将一些 HTML 添加到主题的“页眉之后”部分,这样它就会出现在每个页面上。您可以尝试通过 CSS 绕过一些障碍来隐藏它,但只在主页上显示……不如让我们使用 Discourse 主题来创建一个仅在您的主页上可见内容的组件。

如果您不熟悉 Discourse 主题,请查看 Beginner's guide to using Discourse ThemesStructure 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

但目前这将是一个简单的组件。该组件将由两个文件组成,一个包含逻辑,另一个包含模板。

: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 getter,它会检查路由服务(router service)的 currentRouteName——如果路由名称与您的主页(由站点设置决定)匹配,它将返回 true

现在我们需要模板

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

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

模板会检查 isHomepage getter,如果为 true 则会显示您的内容。您可以在 {{#if}} 块之间添加任何您想要的 HTML。

现在我们的组件已创建,我们需要将其添加到 Discourse 的某个位置。对于这一步,您需要决定使用哪个插件插口(plugin outlet)。这些是 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: 就这样,只需要一行代码来调用您的组件 :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 本地实例中,添加这些文件的正确路径是什么?我想在 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 个赞