wp-discourse 帖子中多行 HTML 注释未隐藏

你好,

我不确定这是 wp-discourse 特有的问题,还是 Discourse 本身的 HTML 解析器的问题,但看起来由 wp-discourse 生成的帖子中,多行 HTML 注释并未被隐藏。

我刚刚完成了 chinwag.pluralistic.net 的设置,该站点基于 Cory Doctorow 在 pluralistic.net 上发布的文章。他的文章开头包含一些以 HTML 注释形式呈现的元数据。最近,这种格式从单行改为了多行。

你可以在以下帖子中看到这种情况:

原文中的单行注释已被移除:

然而,稍后文章中的多行注释却直接显示了出来:

我不认为问题是由 WordPress 插件引起的。以下是 Discourse 未将其解析为注释的示例标记:

<p><!--
Tags:


Summary:
New podcast; Europe's interop coalition; Scarfolk beermats; Miami cop owns illegal mansion nightclub; Video and transcript of my OII talk; Shower temperature vs handle position

URL:
https://pluralistic.net/2020/07/06/polbathic/

Title:
Pluralistic: 06 Jul 2020 polbathic

Bullet:
🧔🏿

Separator:
_,.-'~'-.,__,.-'~'-.,__,.-'~'-.,__,.-'~'-.,__,.-'~'-.,_

Top Sources:
Today's top sources: Fipi Lele, Naked Capitalism (https://www.nakedcapitalism.com/).

--><br></p>

渲染结果为:

问题在于,注释内的空行被 Discourse 解析为段落。一旦如此,HTML 注释就不再是有效的标记。如果从注释中移除空行,Discourse 就能正确解析它:

<p><!--
Tags:
Summary:
New podcast; Europe's interop coalition; Scarfolk beermats; Miami cop owns illegal mansion nightclub; Video and transcript of my OII talk; Shower temperature vs handle position
URL:
https://pluralistic.net/2020/07/06/polbathic/
Title:
Pluralistic: 06 Jul 2020 polbathic
Bullet:
🧔🏿
Separator:
_,.-'~'-.,__,.-'~'-.,__,.-'~'-.,__,.-'~'-.,__,.-'~'-.,_
Top Sources:
Today's top sources: Fipi Lele, Naked Capitalism (https://www.nakedcapitalism.com/).
--><br></p>

除了在发布帖子到 Discourse 之前编辑帖子内容外,我不确定处理此问题的最佳方法是什么。

处理这个问题最好的方法可能是在将帖子发布到 Discourse 之前,先移除帖子中的评论。也许该插件默认就应该这样做,但这是我第一次遇到这个问题。

WP Discourse 插件提供了一个过滤器,可以在帖子发布到 Discourse 之前挂钩以解析帖子内容。该过滤器名为 wp_discourse_excerpt。帖子内容作为变量传递给该过滤器。以下是如何使用该过滤器在帖子发布到 Discourse 之前移除 WordPress 帖子中的所有评论。这种模式也可以用于以其他方式修改帖子:

add_filter( 'wp_discourse_excerpt', 'wpdc_custom_discourse_excerpt' );
function wpdc_custom_discourse_excerpt( $html ) {
	if ( ! extension_loaded( 'libxml' ) ) {

		return $html;
	}

	$use_internal_errors   = libxml_use_internal_errors( true );
	$disable_entity_loader = libxml_disable_entity_loader( true );
	$html_doc              = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/></head><body>' . $html . '</body></html>';
	$doc                   = new \DOMDocument( '1.0', 'utf-8' );
	$doc->loadHTML( $html_doc );
	$finder   = new \DOMXPath( $doc );
	$comments = $finder->query( '//comment()' );
	if ( $comments->length ) {
		foreach ( $comments as $comment ) {
			$comment->parentNode->removeChild( $comment );
		}

		$parsed = $doc->saveHTML( $doc->documentElement );
		libxml_clear_errors();
		libxml_use_internal_errors( $use_internal_errors );
		libxml_disable_entity_loader( $disable_entity_loader );

		return preg_replace( '~<(?:!DOCTYPE|/?(?:html|head|meta|body))[^>]*>\s*~i', '', $parsed );
	}

	libxml_clear_errors();
	libxml_use_internal_errors( $use_internal_errors );
	libxml_disable_entity_loader( $disable_entity_loader );

	return $html;
}

将上述代码添加到您的 WordPress 主题的 functions.php 文件中应该可以解决问题。如果不起作用,请检查确保您的 WordPress 站点服务器上已启用 libxml 扩展。

我确实会尝试一下,但如果评论中的 HTML 实体导致 Discourse 判定该评论为无效 HTML,这听起来似乎是个更大的问题,不是吗?

我不确定 Discourse 应如何处理这种情况。我认为,对于直接在 Discourse 上创建的帖子,说明仅支持有限的 HTML 子集是合理的;但对于通过 API 创建的帖子,或通过拉取 RSS 源导入的帖子,Discourse 应在多大程度上支持 HTML,目前还不太清楚。

我认为将我在上面发布的代码直接添加到 WP Discourse 插件中是合理的。该插件已经使用类似的功能来清理从 Discourse 同步到 WordPress 的评论。这一功能已使用了一段时间,至今未收到任何问题的报告。我会在接下来的几天内再向您反馈此事。

该内容已在 WP Discourse 版本 2.0.6 中添加。当从 WordPress 向 Discourse 发布完整帖子内容时,帖子中的任何注释块都会在发送到 Discourse 之前被移除。

谢谢,Simon!一旦可用,我会立即安装并反馈。

更新:效果非常好。谢谢!