我的“组件”模板坏了。我该如何修复?

在我维护的一个 Discourse 实例中,我有一个组件(继承自该实例的前维护者)用于在页脚中显示该实例赞助商的标志。该组件以前运行良好,但最近却被错误地渲染,以字面形式显示模板控制指令(并将模板值占位符以字面形式放入 HTML 中,因此图像路径没有被解析):

该组件未在 git 仓库中维护,而是直接在“管理”→“外观”→“主题和组件”→“组件”选项卡下配置:

自定义代码

自定义部分:

  • 通用:CSS、页脚、JS

上传

额外文件

导出主题以查看这些文件。
  • javascripts/discourse/api-initializers/theme-initializer.gjs

这些“部分”的内容

点击“编辑代码”时看到的内容;括号中是导出文件中相应文件的路径

CSS (common/common.scss)
.sponsors {
    .inner {
        display: flex;
        align-items: center;
        justify-content: space-around;
        margin-bottom: 10px;
    }

    .heading {
        font-size: 1.75em;
    }

    .sponsor-image {
        max-height: 55px;
    }

    .geoaargau {
        max-height: 45px;
    }
}
页脚 (common/footer.html)
  {{#if displaySponsors}}
    <div class="sponsors-wrapper wrap">
      <div class="inner">
        <h3 class="heading">Sponsoren</h3>
        <a href="http://www.asseco-berit.ch/"><img src="{{theme-setting "theme_uploads.asseco_berit"}}" alt="Asseco Berit" class="sponsor-image asseco-berit"></a>
        <a href="http://www.geoaargau.ch/"><img src="{{theme-setting "theme_uploads.geoaargau"}}" alt="GEOAargau" class="sponsor-image geoaargau"></a>
      </div>
    </div>
  {{/if}}
JS (javascripts/discourse/api-initializers/theme-initializer.gjs)
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  // 这是插件插口,后面跟着组件的自定义名称
  api.registerConnectorClass("above-footer", "sponsors", {

    setupComponent(args, component) {
        
     var topMenuRoutes = 
        component.siteSettings.top_menu.split('|')
        .map(function(route) {return '/' + route});
      
     var homeRoute = topMenuRoutes[0];
     
     api.onPageChange((url) => {

        if (url === "/" || url === homeRoute ){ 
          document.querySelector("html").classList.add("sponsors"); 
          component.set("displaySponsors", true); 
        } else {
          document.querySelector("html").classList.remove("sponsors"); 
          component.set("displaySponsors", false); 
        }
      });
    }
    
  });
});

导出内容还包含:
about.json (466 Bytes)
我猜它是在导出时动态生成的,所以我不认为它相关。

出现此故障时,有效 DOM 的相关部分是:

<div class="custom-footer-content">
    {{#if displaySponsors}}
    <div class="sponsors-wrapper wrap">
      <div class="inner">
        <h3 class="heading">Sponsoren</h3>
        <a href="http://www.asseco-berit.ch/"><img src="{{theme-setting " theme_uploads.asseco_berit"}}" alt="Asseco Berit" class="sponsor-image asseco-berit"></a>
        <a href="http://www.geoaargau.ch/"><img src="{{theme-setting " theme_uploads.geoaargau"}}" alt="GEOAargau" class="sponsor-image geoaargau"></a>
      </div>
    </div>
  {{/if}}
</div>

因此,我们可以看到控制指令 {{#if ...}}...{{/if}} 和占位符 {{theme-setting "..."}} 被用作字面 HTML,而不是被执行/评估/插值。

这是如何以及为何发生变化的?我该如何修复它?

这是否可能与 Upcoming Header Changes - Preparing Themes and Plugins 有关?(尽管我没有看到其中提到模板语法的更改。)

1 个赞

(我所说的“如何和为什么”是指:根本性的变化是什么,以及我是否错过了任何关于它的通知?我相当确定导致这种行为变化的原因是通过激活的自动 Discourse 更新降临到该实例上的,但我希望知道根本原因是什么。)

控制台中有任何错误或警告可以提供进一步的信息吗?

1 个赞

在浏览器控制台中?也许——我不确定那里的“正常”是什么,以及什么可能暗示着问题。我可以直接把内容粘贴在这里,还是可能会泄露敏感信息?

是的,浏览器控制台——粘贴进去没关系:) 通常,如果某些东西被弃用,控制台会抛出一些有用的信息。

1 个赞
https://www.geowebforum.ch/c/feedback/2 加载时的完整浏览器控制台内容
ℹ️ Discourse v2026.3.0-latest — https://github.com/discourse/discourse/commits/38ad2acd2c — Ember v6.6.0 chunk.f47b6dc1cc59c827db42.d41d8cd9.js:275:35231
[PLUGIN discourse-weekly-newsletter] To prevent errors in tests, add a `pluginId` key to your `modifyClass` call. This will ensure the modification is only applied once. chunk.f47b6dc1cc59c827db42.d41d8cd9.js:209:136918
DEPRECATION NOTICE: Defining connector classes via registerConnectorClass is deprecated. See https://meta.discourse.org/t/32727 for more modern patterns. [deprecation id: discourse.register-connector-class-legacy] chunk.f47b6dc1cc59c827db42.d41d8cd9.js:134:74065
Error in parsing value for ‘-webkit-text-size-adjust’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:1:800
Error in parsing value for ‘-moz-text-size-adjust’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:1:827
Unknown property ‘text-size-adjust’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:1:849
Unknown pseudo-class or pseudo-element ‘-moz-focus-inner’.  Ruleset ignored due to bad selector. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:1:1615
Expected ‘none’, URL, or filter function but found ‘alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:622
Ruleset ignored due to bad selector. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:36117
Error in parsing value for ‘justify-content’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:181379
Error in parsing value for ‘text-wrap’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:205516
Error in parsing value for ‘image-rendering’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:264428
Error in parsing value for ‘-webkit-text-size-adjust’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:268491
Error in parsing value for ‘-moz-text-size-adjust’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:268518
Unknown property ‘text-size-adjust’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:268540
Error in parsing value for ‘font-size’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:298136
Expected ‘none’, URL, or filter function but found ‘alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:447258
Expected ‘none’, URL, or filter function but found ‘alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:4:447681
Expected ‘none’, URL, or filter function but found ‘alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:6:33799
Error in parsing value for ‘text-wrap’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:6:105390
Error in parsing value for ‘text-wrap’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:6:105471
Error in parsing value for ‘padding’.  Declaration dropped. common_6dfc7bba61f3a7b80a86f119f30594abc84aaa6d.css:6:257744

我猜我需要查看 Using Plugin Outlet Connectors from a Theme or Plugin

所以,我认为带有 setupComponentregisterConnectorClass 已被弃用,请看您的错误日志:

DEPRECATION NOTICE: Defining connector classes via registerConnectorClass is deprecated. See https://meta.discourse.org/t/32727 for more modern patterns. [deprecation id: discourse.register-connector-class-legacy] chunk.f47b6dc1cc59c827db42.d41d8cd9.js:134:74065

而且我也不确定我们是否仍然允许使用原始 HTML,就像在您的页脚组件中那样。

因此,这个组件将不得不重构以适应现代模式,我建议将其移动到一个合适的组件中,而不是像现在这样放在“管理”(Admin)下面。

回答您的另一个问题

这是由于持续的使 Discourse 现代化并采用 Glimmer 组件的新现代标准的工作所致。

3 个赞

如果不是原始 HTML(模板),https://www.geowebforum.ch/admin/customize/themes/3/common/footer/edit 处的内容期望是什么?是 Markdown 格式,就像用户提供的内容一样吗?

您能提供一些关于如何做到的指导吗?我感觉有点迷失,因为 Discourse 的文档似乎分散在整个元论坛中。

为此,我可以直接解压“导出”文件并将其检入 Git 仓库吗?

如果我的组件的导出中包含 *.gjs 文件,它难道已经是一个 Glimmer 组件了吗?或者说这实际上是问题的一部分——当前的 Discourse 错误地将我的组件识别为一个 Glimmer 组件(因此以该文件名导出它),尽管在代码层面上它还不是一个?

(请原谅我的无知。我不是 Web 开发人员,对 Ember 和 Glimmer 几乎一无所知。)

1 个赞

我的意思是:最新版本的软件不再正确解析原始 HTML,因此您看到的只是转储的 HTML 而不是渲染后的效果。

是的,.gjs 文件确实表明它是一个 glimmer 组件,但其中使用的 registerConnectorClass 方法(已经)不再有效了。

这完全可以理解。Using Plugin Outlet Connectors from a Theme or Plugin 基本上说明的是,要通过 registerConnectorClass 方法在页面上的某个位置渲染信息,就像您的 footer.html 文件所做的那样,我们现在使用一个特定的元素,称为插件插口(plugin outlet)。对于页脚,above-footer 插口会很好地工作。

最好阅读一下 Beginner's guide to using Discourse Themeshttps://meta.discourse.org/t/developing-discourse-themes-theme-components/93648。

查看一个简单的主题组件(theme component)也有助于理解结构。例如:GitHub - discourse/discourse-minimal-footer · GitHub

最后,Discourse 机器人可以为您提供极大的帮助:它非常了解 Discourse 的模式,所以您可以向它提供您当前的 代码,解释问题,并要求它帮助您重构它。

2 个赞