Многострочные HTML-комментарии не скрыты в сообщении от wp-discourse

Здравствуйте,

Не уверен, связана ли эта проблема конкретно с wp-discourse или с HTML-парсером в самом Discourse, но похоже, что многострочные HTML-комментарии не скрываются в постах, созданных wp-discourse.

Я только что завершил настройку chinwag.pluralistic.net на основе постов с 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. Содержимое поста передаётся в него в виде переменной. Вот как можно использовать этот фильтр для удаления всех комментариев из поста WordPress перед публикацией в Discourse. Этот шаблон также можно использовать для других изменений поста:

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;
}

Добавление этого кода в файл functions.php вашей темы WordPress должно решить проблему. Если это не работает, убедитесь, что расширение libxml включено на сервере вашего сайта WordPress.

Я, конечно, попробую это сделать, но звучит это как более серьёзная проблема: если HTML-сущности в комментарии приводят к тому, что Discourse считает этот комментарий невалидным HTML, разве нет?

Я не уверен, как именно Discourse должен обрабатывать это. Думаю, что для постов, созданных непосредственно в Discourse, логично утверждать, что поддерживается лишь ограниченное подмножество HTML, но для постов, созданных через API или импортированных из RSS-ленты, мне неясно, насколько далеко должен заходить Discourse в поддержке HTML.

Кажется разумным добавить код, который я привёл выше, непосредственно в плагин WP Discourse. Плагин уже использует аналогичную функциональность для очистки комментариев, импортируемых из Discourse в WordPress. Это используется уже какое-то время, и о проблемах не сообщалось. Я вернусь к вам с ответом в течение нескольких дней.

Это было добавлено в версию плагина WP Discourse 2.0.6. Когда полный контент публикации публикуется из WordPress в Discourse, любые блоки комментариев в публикации удаляются перед отправкой публикации в Discourse.

Спасибо, Саймон! Я установлю, как только это станет доступно, и сообщу об этом.

ETA: Работает как по волшебству. Спасибо!