使用新的自定义主页功能

正在试用新的自定义主页功能:https://github.com/discourse/discourse/pull/26291 :tada:
@pmusaraj 我想知道添加组件的最佳方法是什么?

  1. 添加自定义主页修饰符会启用 discovery.custom 路由并显示默认信息警报,该警报在 custom-homepage outlet 上渲染:

  2. 我将一个组件添加到 outlet,它会渲染出来:

  3. 但是,当我添加多个组件时,我会收到一个错误:

  4. 不过,我可以将更多组件添加到其他 outlet。这是显示插件 outlet 的视图:

所以我想知道新的 outlet 应该如何工作:

  • 在某种程度上,我不需要 outlet。我可以使用其他可用的 outlet,并将组件限制在 discovery.custom 路由上
  • 不过,似乎我至少需要将一个组件放在 outlet 上,否则会渲染默认警报?将一个空模板放在那里不起作用。
  • 另一方面,如果我可以将多个组件添加到 outlet,我就不需要路由逻辑了。组件只会显示在主页上,因为 outlet 在其他路由上不可用?
4 个赞

这并不奇怪?

在此处放置单个模板文件,并使用它来引用“Components”文件夹中的组件(您可以拥有许多组件)

<MyFirstComponent />
<MySecondComponent />
<MyThirdComponent />

或者您想要的任何内容……只需在此文件夹中保留一个模板?

1 个赞

我以为是因为它与其他出口一起工作?如上截图所示。

哦,抱歉,你说得对,在一个主题组件中发布多个模板文件(通常情况下)似乎是合法的(我之前知道它会处理主题组件和插件之间的冲突,所以它们都能渲染)。真奇怪。

不过我想:你为什么要这样做呢?你会失去对布局的控制权吗?

一个模板会迫使你一次性组合整个布局,并包含你想要的任意数量的子组件?

不过,这种行为确实显得不一致……

如果我构建一个自定义主页,我希望能够在其上渲染多个现有组件。如前所述,在使用其他可用出口并将组件限制在自定义主页路由时,这已经可以正常工作了。

如果我只能将一个组件添加到特定的自定义主页出口,并且还需要添加一个来禁用默认的 yield,那么这实际上会限制我的布局控制。

但是为什么不能在一个模板中引用所有这些组件?

哦,因为它们来自不同的主题组件?

我认为我们在这里沟通有误。

当我说把所有的(Ember)组件都放在组件文件夹里时,我的意思正是如此,但要放在一个_主题_组件里。

我认为这里的关键是:“为什么这个出口的行为不同?” 我明白你想组合不同的主题组件。

[quote=“Robert, post:7, topic:302496, username:merefield”]
哦,因为它们来自不同的主题组件?
[/quote] 是的,就是这个想法。我只是使用了上面纯文本模板作为说明。例如,我使用 精选列表。并且我可以用这些设置在出口处渲染它:

但是当我想要以同样的方式渲染另一个时,我遇到了多个连接器错误。

:+1:t4:

2 个赞

感谢您测试此功能,@manuel,也感谢您的提问。

我也不知道答案,但我查了一下,大致弄明白了原因。我们最近在去年的这个 PR 中引入了经典插件出口和包装器插件出口之间的区别:DEV: Allow PluginOutlets to 'wrap' a core implementation by davidtaylorhq · Pull Request #23110 · discourse/discourse · GitHub

包装器插件出口只允许一个连接器,其余的允许多个。为了说明这一点,当前的插件核心出口代码是:

<PluginOutlet @name="custom-homepage">
  {{#if this.currentUser.admin}}
    <p class="alert alert-info">
      {{i18n "custom_homepage.admin_message"}}
    </p>
  {{/if}}
</PluginOutlet>

它只允许一个连接器。但如果我将核心出口代码更改为:

<PluginOutlet @name="custom-homepage" />

它将可以很好地允许多个连接器模板。我们 可以 在核心中对这个特定的出口进行此更改,但这种差异更普遍。不过,我明白您的观点,这对开发人员来说确实有点晦涩难懂。

另请注意,多个连接器存在排序问题,据我所知,我们没有决定排序的机制。

我认为无论如何最好的方法是 @merefield 建议的:使用一个模板,然后从其中引用 Ember 组件。

顺便说一句,默认警报仅显示给管理员。

6 个赞

谢谢你的解释!

再多玩了一下……它真的很新,用起来很愉快!

我使用了三个现有的组件来构建该布局,我认为这是构建自定义主页的常用方法。我只能将其中一个添加到 wrapper outlet,这就是为什么我认为在这里使用一个普通的 outlet 会更有帮助。

6 个赞

另一个观察:我使用 /custom URL 在侧边栏上添加了一个链接:

当处于自定义路由时,它没有被高亮显示。

如果我正确理解侧边栏高亮的逻辑,当处于根 URL / 时,它也应该被高亮显示。

3 个赞

在快速浏览了 Featured Lists 组件后,我更清楚地看到了您的问题。一个选项是重构该组件,让它输出所有列表到一个 Ember 组件。然后,您可以将该组件添加到插件包装器出口。

另一个选项是在自定义主页模板中添加第二个插件出口,例如 \u003cPluginOutlet @name=\"below-custom-homepage\"/\u003e

说实话,我可能没有太多理由坚持使用这个带有管理员消息的 custom-homepage 出口。那个警告并非特别有用……

是的,这可能很棘手。在我刚才的本地测试中,/custom 无法正常工作。最好使用 /,它可以正确路由。但它仍然没有高亮显示。

2 个赞

这似乎是一个常见问题。如果我使用 /,它也不会高亮显示设置为着陆页的其他路由。

是的,我也能想象警告只是显示方式不同。包装器 outlet 的主要优点似乎是,我可以有条件地输出核心代码或渲染自定义代码。但这可能永远不会是该信息消息的情况。

肯定有什么误会。该组件已经将所有列表包装在一个包装组件中,并在任何给定的 outlet 上进行渲染:

image

因此,我可以毫无问题地将该组件添加到自定义主页上的当前包装器 outlet 中。
我无法做的是使用该 outlet 在自定义主页上渲染多个独立的组件。我将安装为主题组件的组件,例如这三个:

我的假设是,使用多个独立的 theme 组件来构建自定义主页将是常见的方法。而不是在一个主题中从头开始构建所有内容。

如果您考虑添加另一个 outlet 或更改 outlet 设置,我可以根据迄今为止的使用情况提供更多反馈。不过,我会将那个兔子洞藏在 details 中 :smile:

\u003cdetails\u003e

所以我意识到 outlet 是在 main-outlet 元素内渲染的。这些元素的整体结构是:

  • main-outlet 包装器
    • sidebar-wrapper
    • main-outlet
      • custom-homepage outlet

作为一个设计师,我在使用这个 outlet 安排自定义主页上的项目时并不那么灵活。对于上面共享的设计,我更倾向于使用 before-main-outlet outlet,不仅因为我可以放置多个组件,还因为它不会将组件嵌套在 main-outlet 元素内。
上面截图中的结构如下:

  • main-outlet 包装器
    • sidebar-wrapper
    • 组件:搜索横幅
    • 组件:精选主题
    • 组件:精选列表
    • main-outlet

优点是,我可以将元素安排在整个 main-outlet 包装器的宽度上,而不仅仅是在 main-outlet 元素内。为了说明这一点,如果我在当前的 custom-homepage outlet 上渲染其中一个组件,它将嵌套在 main-outlet 元素内,如下所示:

在我看来,为自定义设计提供最大灵活性的插件 outlet 将放置在

  • 作为 main-outlet 包装器的直接子项(类似于 before-main-outlet outlet)
  • 在一个包装 div 内

该包装 div 将捆绑添加到其中的所有组件,并允许轻松排序。这样的结构将如下所示:

  • main-outlet 包装器
    • sidebar-wrapper
    • custom-homepage-wrapper
      • 组件:搜索横幅
      • 组件:精选主题
      • 组件:精选列表
    • main-outlet

所以这是我作为设计师的反馈。我想这取决于您如何决定它与您认为自定义主页功能的常见用法有多大程度的吻合。
\u003c/details\u003e

3 个赞

这个页面“表面上”是用户可见但“Googlebot”不可见,因此不会被索引吗?

是的,没错,对于爬虫视图,我选择了只输出顶部菜单。我无法从 Rails 应用程序中得知某个主题在此路由上会输出什么。

我正在考虑 @manuel 在这里的建议,很快就会抽出时间来测试一些更改。请 :bear: 谅解。

6 个赞

我已将此功能添加到 Discourse Bars 🍻 🍸 (a sidebar framework) - #43 by merefield

4 个赞

我遇到的一个问题:我想在自定义主页上显示 Homepage Feature component。但是在这个路由上,主题没有被过滤。该组件只显示任何带有图片的最新主题。

组件上的代码是:

    const topicList = await this.store.findFiltered("topicList", {
      filter: "latest",
      params: {
        tags: [`${settings.featured_tag}`],
        order: sortOrder,
      }

似乎 params 没有在自定义主页上应用。否则它工作正常。不确定为什么会这样?

编辑:我在 Featured Lists component 上使用了相同的方法。当在自定义主页上使用此组件时,过滤器也没有应用。但只在第一个列表中…当有更多列表时,接下来的列表都经过了正确的过滤。

3 个赞

有趣的是,我不确定这是为什么,也许 topicList 存储中存在与发现路由相关联的逻辑?自定义主页不是发现路由。

我很想知道,带有参数的相同组件在管理路由或用户个人资料路由中是否也能正常工作?您能否检查一下?

@tynaut 遇到了类似的问题,所以这里很可能需要解决一些问题。

1 个赞

我尝试使用了“精选列表”组件,它已经有一个设置可以显示该组件在任何地方。这不包括管理员路由,但我尝试了所有其他路由(静态页面、用户个人资料等),除了自定义主页之外,它似乎在所有地方都有效。

另一件奇怪的事情是,如前所述,它只过滤第一个列表。例如,在这里我过滤了两个列表,一个用于“特色”标签,一个用于“通用”类别,在所有其他路由上列表显示如下:

仅在自定义主页路由上,它们显示如下:

因此,第一个列表不再按标签过滤,但第二个列表按类别过滤。当我切换列表的顺序时,第一个列表不按类别过滤,但第二个列表按标签过滤:

2 个赞

我发现用“精选主页”组件正确重现这一点有点棘手,它混合了太多其他条件。

但我可以轻松地用一个简化的组件重现它。我已将其推送到此处的示例仓库:GitHub - pmusaraj/discourse-sample-custom-homepage

那里的 sample-list 组件应该只拉取带有 featured 标签的主题,但它没有(对我来说,它拉取了前 3 个主题)。如果我从该主题的 about.json 文件中删除 custom_homepage 修饰符,那么就会拉取正确的主题。

我会找一个更熟悉 store 服务的人来看看。谢谢!

1 个赞

您好

请问如何将组件(搜索横幅或论坛上已安装的自定义组件)添加到 home.hbs 文件中,使其显示在新的自定义主页上?

谢谢