使用 WP Discourse 将 WordPress 文章发布到 Discourse

您可以使用 WP Discourse 插件将 WordPress 帖子发布到您的 Discourse 论坛,以便您的社区可以讨论您的 WordPress 内容。在设置发布功能之前,您必须先在 WordPress 上安装 WP Discourse 插件,并将其连接到您的 Discourse。如果您已准备好开始,请先观看这段简短的视频,或按照以下说明操作。

下一步

设置发布功能后,您可能想查看以下主题:


操作说明

发布设置

:warning: 更改设置后,请务必保存。请点击页面底部的「保存选项」按钮。

这些设置应该相对直观易懂。如果您在理解任何设置时遇到问题,请回复此主题以获取进一步说明。

默认 Discourse 分类

设置帖子在 Discourse 上发布时的默认分类。此设置可在 WordPress 的「新建帖子」屏幕上针对单个帖子进行覆盖。

显示子分类

指示是否希望论坛的子分类可作为从 WordPress 发布帖子的可用分类。您需要先保存此设置,子分类才会出现在「默认 Discourse 分类」选项输入框中。

强制更新分类

当您向论坛添加了新分类并希望它们在 WordPress 站点上可用时使用。启用此设置并保存选项页面后,系统将向 Discourse 发起一次 API 调用以获取分类列表。启用后,下次您返回「评论」标签页时,会发现该设置已自动禁用。

允许标签

如果您希望通过 WordPress 为创建的 Discourse 主题添加标签,请启用此项。

以未列出主题发布

将使从 WordPress 发布的帖子在 Discourse 上处于未列出状态。如果您启用了 Sync Comment Data Webhook 设置,这些未列出的帖子将在首次收到 Discourse 回复时变为可见。

使用完整帖子内容

允许您将完整的 WordPress 帖子而非摘要发布到 Discourse 论坛。若要避免在 Discourse 帖子下方显示「显示完整帖子」按钮,您必须在 Discourse 上取消选中 embed truncate 站点设置(位于 yourforum.com/admin/site_settings/category/posting)。

自定义摘要长度

如果您未选择 Use Full Post Content 设置,此设置将生成指定长度的摘要并发布到 Discourse。您也可以在创建 WordPress 帖子时,通过在 Excerpt 元数据框中添加内容来手动创建摘要。

自动发布

此设置会自动勾选「发布到 Discourse」复选框,该复选框出现在针对需发布到 Discourse 的帖子类型的「新建帖子」屏幕上。创建帖子时仍可取消勾选该复选框。

自动追踪已发布主题

此设置默认启用。启用后,从 WordPress 发布到 Discourse 的帖子作者将自动「关注」该主题(他们将收到关于每条新回复的 Discourse 通知)。

要发布的帖子类型

必须设置此项。默认值为 post,但也可以选择页面和自定义帖子类型。

按标签排除帖子

如果在此设置中添加 WordPress 标签,则带有这些标签的任何 WordPress 帖子都不会发布到 Discourse。

不显示 Discourse 用户名字段

这将隐藏用户个人资料中的「Discourse 用户名」字段。Discourse 用户名用于在发布帖子到 Discourse 时设置主题作者。

Discourse 用户名可编辑

此设置决定非管理员用户是否能在其个人资料中编辑自己的 Discourse 用户名。Discourse 用户名用于在发布帖子到 Discourse 时设置主题作者。

直接数据库发布标志

此设置用于某些具有特殊 WordPress 环境的配置。除非您清楚其作用,否则请勿使用此设置。

详细发布日志

启用此设置后,所有发布到 Discourse 的帖子(即使成功)都将记录在 WP Discourse 日志中。通常仅记录错误。

通过 XML-RPC 启用发帖

XML-RPC 是一种远程过程调用,通常由博客软件用于向 WordPress 发送帖子。使用此过程的 App 包括 wordpress.com博客应用

默认情况下,WP Discourse 不会将通过 XML-RPC 创建的帖子发布到 Discourse。原因是目前没有很好的方法来判断通过博客软件发布的帖子是否意在发布到 Discourse。

如果您希望使用博客软件创建直接发布到 Discourse 的帖子,需要在主题的 functions.php 文件中添加一些代码,以挂钩到 wp_discourse_before_xmlrpc_publish 过滤器。wp_discourse_before_xmlrpc_publish 过滤器会将两个参数传递给挂钩到它的函数。第一个参数 $publish_to_discourse 是一个布尔值,默认为 false,用于禁用通过 XML-RPC 发布。第二个参数是 post 对象。

若要使所有通过 XML-RPC 发布的帖子自动发布到 Discourse,您需要编写一个始终返回 true 的函数。可以使用如下代码:

警告:这将导致所有通过 XML-RPC 发布的帖子(包括在博客软件上编辑的旧帖子)都被发布到 Discourse。

add_filter('wp_discourse_before_xmlrpc_publish', 'my_namespace_xmlrpc_publish', 10, 2 );
function my_namespace_xmlrpc_publish( $publish_to_discourse, $post ) {
  return true;
}

按帖子标签过滤 XML-RPC 帖子

wordpress.com 博客应用允许您为帖子添加标签。您可以利用标签控制是否将帖子发布到 Discourse。若只发布带有 ‘discourse’ 标签的帖子,可以使用如下代码:

add_filter('wp_discourse_before_xmlrpc_publish', 'my_namespace_xmlrpc_publish_by_tag', 10, 2 );
function my_namespace_xmlrpc_publish_by_tag( $publish_to_discourse, $post ) {
  if ( has_tag( 'discourse', $post ) ) {
    return true;
  }
  return false;
}

如果您想使用此方法,但不希望 ‘discourse’ 标签出现在已发布的帖子中,可以使用如下代码将其移除:

add_filter( 'term_links-post_tag', 'my_prefix_remove_discourse_tag' );
function my_prefix_remove_discourse_tag( $tags ) {
    foreach( $tags as $key => $value ) {
        if ( strpos( $value, 'discourse' ) ) {
            unset( $tags[ $key ] );
        }
    }

    return $tags;
}

按帖子日期过滤 XML-RPC 帖子

若只允许在特定日期之后发布的帖子通过 XML-RPC 发布到 Discourse,请在 functions.php 文件中添加如下代码。此代码将允许所有在 2016 年 1 月 1 日之后发布的帖子发布到 Discourse。

add_filter('wp_discourse_before_xmlrpc_publish', 'my_namespace_xmlrpc_publish_by_date', 10, 2 );
function my_namespace_xmlrpc_publish_by_date( $publish_to_discourse, $post ) {
  if ( strtotime( $post->post_date ) > strtotime( '2016-01-01') ) {
    return true;
  }
  return false;
}

待办:为 wp-discourse 插件添加过滤器,以仅允许通过 XML-RPC 发布新帖子(而非编辑过的帖子)。

为自定义帖子类型过滤可用分类

在 Discourse 分类显示于 WordPress admin/post-new 页面上的「发布到 Discourse」元数据框之前,会应用 WordPress 过滤器 'wp_discourse_publish_categories'。该过滤器接收 Discourse 分类数组和当前帖子作为参数。您可以在主题的 functions.php 文件中使用它来限制特定帖子类型可用的分类。

以下示例创建了一个名为 'acme_product' 的帖子类型,然后返回 Discourse 分类 ‘fun’ 和 ‘scratch’,以便在该类型的帖子「发布到 Discourse」元数据框中显示。

// 创建帖子类型。
add_action(  'init', 'my_namespace_create_post_type' );
function my_namespace_create_post_type() {
  register_post_type( 'acme_product',
    array(
      'labels' => array(
      'name' => __( 'Products' ),
      'singular_name' => __( 'Product' )
    ),
    'public' => true,
    'supports' => array( 'title', 'editor', 'comments', 'custom-fields' ),
    'has_archive' => true,
    'show_in_rest' => true,
    )
  );
}

// 为 'acme_product' 帖子类型过滤可用分类。
add_filter( 'wp_discourse_publish_categories', 'my_namespace_filter_categories', 10, 2 );
function my_namespace_filter_categories( $categories, $post ) {
   if ( 'acme_product' === get_post_type( $post ) ) {
     $output = [];
     foreach ( $categories as $category ) {
        if ( 'fun' === $category['name'] || 'scratch' === $category['name'] ) {
          $output[] = $category;
        }
     }
     return $output;
   }
   return $categories;
}

如果您想为特定帖子类型严格应用特定分类(即 1:1 对应),则应使用 wpdc_publish_post_category

function wpdc_change_post_category( $category, $post_id ) {
  if ( 'acme_product' === get_post_type( $post ) ) {
       $categories = WPDiscourse\Utilities\Utilities::get_discourse_categories();
       $fun_category = array_search( 'fun' , array_column( $categories, 'name' ));
       return $fun_category;
  } else {
       return $category;
  }
}
add_filter( 'wpdc_publish_post_category', 'wpdc_change_post_category' );

显示已连接 Discourse 主题的元数据

设置好发布功能后,您可以使用 模板自定义 来显示 Discourse 主题的元数据。

首先,您需要决定要修改哪个模板。例如,如果您只想显示主题元数据而不显示回复作为评论,则应修改 no_replies 模板。

选择模板后,您可以修改它以添加 Discourse 主题元数据。以下是一个示例代码片段,其中包含解释代码功能的注释:

// 确保 wp-discourse 插件已安装(使用您喜欢的方法)
// 例如:https://wordpress.stackexchange.com/questions/127818/how-to-make-a-plugin-require-another-plugin

// 引入 wp-discourse 插件中的 plugin-utilities
require_once ABSPATH . 'wp-content/plugins/wp-discourse/lib/plugin-utilities.php';
use WPDiscourse\Shared\PluginUtilities;

// 将您的主题元数据模板封装在一个类中,以便轻松包含插件工具

class DiscourseTopicMetadata {
  
  // 在类中包含 wp 插件工具
  use PluginUtilities;
  
  public function __construct() {

    // 在类初始化时添加模板过滤器
    add_filter( 'discourse_no_replies_html', array( $this, 'topic_metadata_html' ) );
  }

  function topic_metadata_html( $input ) {
    // 从帖子元数据中获取 Discourse 永久链接
    $discourse_permalink = get_post_meta( get_the_ID(), 'discourse_permalink', true );

    // 使用插件工具中的辅助方法,通过 Discourse 永久链接获取主题 JSON(该方法会自动处理授权)
    $topic = $this->get_discourse_topic($discourse_permalink);
   
    // 输出您的 HTML 标记,包括您希望显示的主题元数据
    ob_start();
    ?>
    
    <div id="discourse-topic-meta">
        <div class="views">
          浏览量
          <?php echo $topic->views; ?>
        </div>
        <div class="replies">
          回复数
          <?php echo $topic->reply_count; ?>
        </div>
    </div>
    <?php
    
    return ob_get_clean();
  }
}

// 实例化类以添加过滤器
new DiscourseTopicMetadata();

有关 get_discourse_topic 响应中可用的主题元数据的详细信息,请参阅 Discourse API Docs

10 个赞

是否可以导入先前发布的博客文章?例如,过去 30 天内的博客文章?只是为了稍微填充一下该类别。谢谢。

2 个赞

目前没有批量导入选项。您仍然可以通过编辑每个旧帖子并将其发布到 Discourse 来实现此目的。

2 个赞

我将我的站点设置为只有少数人(作者)可以登录 WordPress,但 Discourse 基本上对任何人开放。Discourse 用于身份验证。

我希望从文章创建的主题显示 Discourse 用户的名字,而不是“System”(或者我设置的发布用户名)。

换句话说,发布用户名设置为“System”。Joe Blow 在 WordPress 中发布了一篇新文章。Joe Blow 存在于 Discourse 中(由于 Discourse 控制身份验证,所有 WordPress 用户也是 Discourse 用户)。我希望该主题显示为 Joe Blow 发布,而不是 System。稍后,在同一个站点上,Jane Doe 发布了一篇文章,我希望 Discourse 中的主题显示为 Jane Doe 发布,而不是 System。

这可以做到吗?

我不知道。但如果你查看“发布”选项卡,然后是最后一个选项“单用户 API 密钥发布”,我会先尝试那个。

如果你正在使用 DiscourseSSO(或任何连接),那么没有人可以在不通过 WordPress 的情况下注册到你的论坛。所以,如果 WordPress 控制 Discourse 上编辑器的账户,你如何在不首先要求每个人在 WordPress 上注册的情况下做到这一点?我很好奇,因为我可以使用类似的东西。

(而且……我又离题了🤦‍♂️)

我使用了 DiscourseConnect 客户端设置。它使用 Discourse 作为身份验证系统,并在 WordPress 中创建用户(如果用户不存在)。根据插件的说明:

启用您的站点作为 DiscourseConnect 客户端,允许通过您的 Discourse 论坛或您的 WordPress 站点处理 WordPress 用户身份验证。如果 Discourse 用户通过 DiscourseConnect 链接登录 WordPress,他们将根据其 Discourse 凭据进行身份验证。如果该用户尚不存在于您的 WordPress 站点上,将创建一个新用户。

用户最初将在 WordPress 中被设置为订阅者,我将根据需要手动将其设置为作者。我计划将该站点设置为允许未注册用户查看所有内容,只有当他们想发布文章时才需要在 WP 中注册。

WordPress 中的所有用户都必须先在 Discourse 中注册,然后连接器将自动将他们登录到 WP,或者创建账户然后将他们登录。

是的,但它会覆盖所有其他身份验证方式,然后论坛的普通用户必须在 WordPress 上注册才能访问 Discourse。

或者是我有什么误解?

据我所见,普通 Discourse 用户永远不必访问 WP 网站。如果他们决定从 Discourse 网站点击链接,他们会自动在 WP 网站上注册。

欢迎您查看这两个网站,看看我指的是什么。请记住,它们尚未完成,但那部分现在可以正常工作。
Https://forum.oursail.boats 是 Discourse
Https://www.oursail.boats 是 WP 网站。

在 WP 网站上创建一个帐户。您将能够在此处查看和回复消息。

然后转到 WP 网站,然后选择“登录”菜单项。它将绕过 WP 登录,而是连接到 Discourse 登录(取决于您的设置)。如果您选择了“保持登录”选项,它甚至不会提示您。登录后,它将立即返回到 WP 网站。

您只需确保在 WordPress 上发布文章的用户在其个人资料中填入了 Discourse 用户名。如果用户有 Discourse 用户名,他们在 WordPress 中发布的内容将使用他们的用户名发布到 Discourse。

您可以手动更新此信息,或使用“更新用户数据”Webhook(请参阅 WP Discourse 的“Webhooks”设置)自动更新。

3 个赞

在我手动编辑完我 393 篇已发布的 WP 帖子之前,我想再次确认一下情况是否仍然如此?也就是说,是否仍然没有批量导入选项?谢谢!

没有批量导入选项。请注意,如果您向 Discourse 发布 393 篇帖子,您将有 393 个主题存根。我建议您考虑更具针对性的策略。您的社区现在实际要讨论什么?

2 个赞

我猜他们不会。Discourse 只是用来取代评论,仅此而已。所以,它不是为 Discourse,而是为 WordPress。

我曾遇到过类似的情况。因为世界上大多数 WordPress 帖子都没有引起任何评论,或者这些评论或多或少只是噪音,我的帖子也不例外。但我没有处理所有内容,而是利用我旧的 WP-content 来激活 Discourse 上的活动。我不是一次性连接所有帖子,而是逐步进行的。就像现在有关于中暑的狗和你在徒步时应该吃多少卡路里的热门话题一样——这些都是旧帖子,在 Discourse 上焕发了新的生命。

如果有一个选项可以批量连接所有内容,我会这样做的——即使不明白这种错失的潜力。我甚至可以说,即使你能编写出来,也要把批量选项埋葬六英尺之下 :wink:

2 个赞

我只是想在将网站从 WordPress 迁移到 Ghost 之前将所有评论导入 Discourse,因为 Ghost 不处理评论(尽管您可以将其连接到 Discourse 进行评论)。

但现在我才想到,如果我先将新的 Ghost 连接到我的 Discourse,然后再导入我所有的 WordPress 帖子,那可能会奏效……也许(/me 去试试……)

它不会将评论从 WP 迁移到 Discourse。它只会在 WordPress 中显示 Discourse 帖子。

如果我理解正确的话……

1 个赞

既然您即将迁移到 Ghost,那么链接 Wordpress 博文和 Discourse 主题就没有意义了。

大家好!

我刚刚完成了 Discourse 社区的配置!目前正在我的暂存网站上测试 WP Discourse 插件。

我担心潜在的 SEO 问题。具体来说,通过将相同的内容从 WP 发布到 Discourse,我担心会出现重复内容(根据 SEO 问题)。Discourse 会将论坛上的内容标记为副本以用于 SEO 目的吗?

你好 Victor :slight_smile:

SEO 方面,默认设置应该没问题(因为它们是不同的域名),但你也可以将 Discourse 主题的规范 URL 设置为 Wordpress 文章的 URL。

启用 Discourse 站点设置 embed set canonical url,然后 WP 文章的永久链接将成为 Discourse 主题的规范 URL(即,它将作为规范链接出现在 Discourse 主题 HTML 的 head 中)。

更多背景信息请参见:

1 个赞

谢谢 @angus。我真的很感激。对我来说,通过 SEO 来控制比听天由命更安全!

1 个赞

我正在尝试为不同的自定义帖子类型设置不同的类别。下面的代码可以在 WordPress 管理员中选择正确的类别。但是,在发布到 Discourse 时,类别并未在那里设置(并默认为“未分类”)。

也许我遗漏了显而易见的东西?

// WP Discourse 为 CPTS 设置 CPT 论坛类别

add_filter( 'wp_discourse_publish_categories', 'radhr_filter_categories_policies', 10, 2 );
function radhr_filter_categories( $categories, $post ) {
	if ( 'policy' === get_post_type( $post ) ) {
		$output = [];
		foreach ( $categories as $category ) {
			if ( 'Policies' === $category['name']) {
				$output[] = $category;
			}
		}
		return $output;
	}

	elseif ( 'guide' === get_post_type( $post ) ) {
		$output = [];
		foreach ( $categories as $category ) {
			if ( 'Guides' === $category['name']) {
				$output[] = $category;
			}
		}
		return $output;
	}

	elseif ( 'post' === get_post_type( $post ) ) {
		$output = [];
		foreach ( $categories as $category ) {
			if ( 'Blogs' === $category['name']) {
				$output[] = $category;
			}
		}
		return $output;
	}

	return $categories;
}

您对如何实现目标做出了合理的假设,但如果您使用古腾堡编辑器过滤到单个类别,wp_discourse_publish_categories 将无法可靠工作。

您应该改用 wpdc_publish_post_category

我将更新 OP 以便注意到这一点。

1 个赞