pfaffman
(Jay Pfaffman)
2025 年4 月 15 日 22:22
1
TL;DR:
我想在摘要中添加一些内容。我以前可以覆盖模板,但现在不行了,原因不明。
因为覆盖模板是不好的 ,所以在摘要中有一些地方会被 digest_custom_html 替换,但它会插入文本,所以这些地方需要附加 .html_safe。至少有一个地方放错了(名字里有“above”,但实际上是在下面)。
我认为我有能力为此做一个 PR,除非因为它太简单了,别人做起来会更容易。
更长、更痛苦的故事。
我在这里做过:https://github.com/pfaffman/discourse-add-to-summary,但这似乎已经不起作用了。
我认为我想做的是,在不修改核心代码的情况下,覆盖 digest.html.erb 模板。我以前可以通过将其放在 app/views/user_notifications/digest.html.erb 来实现,并且该文件会被处理而不是核心文件。但这似乎不再起作用了。
现在,我们有一些很棒的 digest_custom_html,如下所示:
<div class="summary-email">
<span class="preheader" style="display:none!important;color:#f3f3f3;font-size:1px;line-height:1px;max-height:0;max-width:0;mso-hide:all!important;opacity:0;overflow:hidden;visibility:hidden">
<%= @preheader_text %>
</span>
<table border="0" cellspacing="0" width="100%">
<tr>
<td>
<%= render_digest_header %>
<table width="100%" class="body digest-content with-dir" style="background:#f3f3f3;padding:0;border-spacing:0;font-family:Arial,sans-serif;font-size:14px;font-weight:200;line-height:1.3;vertical-align:top;">
<tr>
<td class="side-spacer" style="vertical-align:top;padding:0;">
<div class="with-accent-colors">
<table class="spacer with-accent-colors" style="border-spacing:0;padding:0;width:100%">
<tbody>
<tr>
<td height="400px" style="height:400px;border-collapse:collapse!important;margin:0;mso-line-height-rule:exactly;padding:0;"> </td>
</tr>
</tbody>
</table>
</div>
</td>
<td width="650" style="vertical-align:top;padding:0;font-family:Arial,sans-serif;">
<%= render partial: "user_notifications/digest/stats" %>
<%= render partial: "user_notifications/digest/popular_topics" %>
</td>
<td class="side-spacer" style="vertical-align:top;padding:0;">
<!-- Background that goes down part-way behind content -->
<div class="with-accent-colors">
<table class="spacer with-dir with-accent-colors" style="border-spacing:0;padding:0;width:100%">
<tbody>
<tr>
<td height="400px" style="height:400px;border-collapse:collapse!important;margin:0;mso-line-height-rule:exactly;padding:0;"> </td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</table>
<%= render partial: "user_notifications/digest/popular_posts" %>
<%= render partial: "user_notifications/digest/new_topics" %>
<%= render partial: "user_notifications/digest/styles" %>
<%= digest_custom_html("above_footer") %>
<%= render partial: "user_notifications/digest/footer" %>
<%= digest_custom_html("below_footer") %>
</td>
<!-- Empty cells pad either side of the email content -->
<td></td>
</tr>
</table>
</div>
聪明的读者会注意到,热门话题大约在第 78 行开始,远早于第 277 行。我不确定我花了多少时间因为看错了地方而认为什么都没有发生。但这是题外话。
我确实设法在 plugin.rb 的 after_initialize 中做到了这一点。
require_dependency "user_notifications"
module ::UserNotificationsHelperOverride
def digest_custom_html(position_key)
puts "doing improved the digest: #{position_key}"
if position_key == "below_popular_topics"
puts "doing the custom html for above_popular_topics"
# Custom HTML for the popular topics position
"<div>MY COOOOOOOL TEXT</div>"
else
puts "doing the super for #{position_key}"
super
end
end
end
它确实在模板中我期望被更改的地方添加了文本!
可惜的是,它没有被当作 HTML,而是被当作纯文本。所以。。。
我在 all_the_plugins 中查找,没有发现任何人使用这段代码的例子。
如果我将类似这样的行更改为
<%= digest_custom_html("below_popular_topics") %>
并替换为
<%= digest_custom_html("below_popular_topics").html_safe %>
这是否会是一个 PR 欢迎的更改?而且,既然我已经在做了,也许可以确保 position_key 的名称更符合它们的位置?
1 个赞
pfaffman
(Jay Pfaffman)
2025 年4 月 16 日 17:57
3
我认为 digest_custom_html 未生成可解析的 HTML 是一个 bug,因此我将重新归类。
1 个赞
pfaffman
(Jay Pfaffman)
2025 年4 月 18 日 17:21
4
@martin ,抱歉点名你,但你是最后修改 digest.html.erb 的人(两年前)。你介意看看这个 PR 吗?
1 个赞
pfaffman
(Jay Pfaffman)
2025 年4 月 23 日 15:33
5
该插件已部署,我可能很快就会忘记它,所以如果有人想按预期使用这些 digest_custom_html 字段,您可以将类似这样的代码添加到您的 app.yml 中以修补源。我太懒了,无法创建一个替换所有这些的正则表达式,而是只做了我正在使用的那个。请根据您的用例进行修改。
我在插件中创建了一个模板,然后可以将其包含在 app.yml 中。这比处理整个 yaml 块要容易一点。
hooks:
after_code:
- replace:
filename: "/var/www/discourse/app/views/user_notifications/digest.html.erb"
from: 'digest_custom_html("above_footer") '
to: 'digest_custom_html("above_footer").html_safe '
1 个赞
设置一个标签以帮助提醒团队打开 PR(Pull Request)是否有意义?
1 个赞
pfaffman
(Jay Pfaffman)
2025 年4 月 28 日 16:40
7
嘿 @david 。我将再试一次,看看是否有人对这个 PR 感兴趣。如上所述;代码显然没有按预期工作,但没有人关心过。我做了一个变通方法,并部署了代码,在部署时修复了模板,但这并不是一个完美的解决方案。
1 个赞
david
(David Taylor)
2025 年4 月 28 日 17:49
8
您能否为您的方法覆盖结果添加 .html_safe?我认为没有理由将其保留在 erb 模板中?
总的目标,无论是在 Rails 还是 Ember 中,都是将“此字符串是 html 安全的”放在尽可能靠近编写/生成点的位置,这样开发人员就能清楚地知道他们需要确保 HTML 确实是安全的(即任何用户输入都已转义)
您的做法是可以的(只要经过测试),但这并不是这些方法的“预期”用途。如果这是一个故意的插件 api,它应该和其它插件一样在 plugin/instance.rb 中。
此方法的预期用途是将 markdown 放入匹配的翻译键中:
(另请注意那里的 html_safe - 这与您在任何覆盖中需要使用的技术相同)
2 个赞
pfaffman
(Jay Pfaffman)
2025 年4 月 28 日 20:43
9
我的天哪。显然……我可以!!!!我从来没想过我能把它放在那里,而不是放在模板的顶部(至少在我脑子里是这样渲染的)。
我现在看到并理解了 digest_custom 以及它在代码中调用 .html_safe,它很漂亮,就在我查看并试图理解的代码中,但它使用那种奇怪的无括号语法让我感到困惑(对我来说)。(或者我可能永远也看不到它)。
嗯,我确实在 locales 中看到了这些值,但与我之前覆盖模板相比,这是一个风险小得多的解决方案。
非常感谢你指明了正确的方向!
这是我还在做的另一件我觉得很傻的事情。我的 digest_custom_html 需要它被渲染的用户,所以我正在覆盖 digest 来设置 @user,这样我的 digets_custom_html 就可以访问 digest 所属的用户。有没有什么超级简单的方法可以避免这样做?
after_initialize do
# Code which should run after Rails has finished booting
# 在 Rails 完成启动后应运行的代码
# require_relative \"lib/discourse_add_jobs_to_digest/user_notifications_helper_override\"
require_relative \"lib/discourse_add_jobs_to_digest/engine\"
require_relative \"lib/discourse_add_jobs_to_digest/job_api\"
require_dependency \"user_notifications\"
module ::UserNotificationsHelperOverride
def digest_custom_html(position_key)
if position_key == \"above_footer\"
DiscourseAddJobsToDigest::JobApi.get_jobs_html(@user).html_safe
else
super
end
end
end
UserNotificationsHelper.prepend(::UserNotificationsHelperOverride)
module ::UserNotificationsOverride
def digest(user, opts = {})
@user = user
super
end
end
UserNotifications.prepend(::UserNotificationsOverride)
end
2 个赞
david
(David Taylor)
2025 年4 月 29 日 09:10
10
我没有在模板/方法中看到任何其他使用 user 变量的地方,所以是的,你所做的可能是最好的方法。
但即便如此,这类覆盖也不能被“支持”,并且随时可能中断。请确保你有一些测试来捕获它最终发生时的情况。
1 个赞
pfaffman
(Jay Pfaffman)
2025 年4 月 29 日 14:38
11
感谢确认!感谢你的时间。
david:
这类覆盖是无法被‘支持’的,并且随时可能中断。
明白了。这比覆盖整个模板要好得多,而这正是我之前为类似插件提出的解决方案。
而且,是的,应该有测试。
1 个赞
pfaffman
(Jay Pfaffman)
关闭
2025 年5 月 29 日 14:39
12
此主题在最后回复的 30 天后自动关闭。不再允许新的回复。