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

作为主题开发者,您经常会遇到一种情况:需要创建仅在社区首页显示的内容。

您可能在主题的“页眉后”部分添加了一些 HTML,这样它会在每个页面上显示。您可以在 CSS 中费一番周折,将其隐藏,只在首页显示……但更好的方法是使用 Discourse 主题创建一个组件,其中的内容仅在您的首页可见。

如果您不熟悉 Discourse 主题,请查看 Beginner's guide to using Discourse Themeshttps://meta.discourse.org/t/structure-of-themes-and-theme-components/60848。

在您的 Discourse 主题中,您需要设置以下目录结构:

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

接下来,我们将创建一个 Ember 组件。您可以从他们的文档中了解更多关于 Ember 组件的信息:Ember.js Guides - Guides and Tutorials - Ember Guides

但现在,这将是一个简单的组件,写在一个 .gjs 文件中,同时包含逻辑和模板。

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

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

  <template>
    {{#if this.isHomepage}}
      <h1>这是我的首页 HTML 内容</h1>
    {{/if}}
  </template>
}

这会创建一个 isHomepage getter,它会检查路由服务的 currentRouteName —— 如果路由名称与您的首页(由站点设置决定)匹配,则返回 true<template>...</template> 内的模板会检查该 getter,仅当它为 true 时才显示您的内容。您可以在 {{#if}} 块之间添加任何您想要的 HTML。

现在我们的组件已创建,我们需要将其添加到 Discourse 的某个位置。在这一步中,您需要决定使用哪个插件出口(plugin outlet)。这些是 Discourse 中为我们添加了一些代码的区域,供开发者接入。您可以在 Github 上搜索 Discourse 的这些出口,或者通过 (deprecated) Plugin outlet locations theme component 浏览它们。

对于自定义首页,above-main-container 是一个常见的选择,因此我们使用它。

我们需要在正确的目录中创建连接器文件:

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

import CustomHomepageContent from "../../components/custom-homepage-content";

<template><CustomHomepageContent /></template>

: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 个赞