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

You can use the WP Discourse Plugin to Publish Wordpress Posts to your Discourse so your community can talk about your Wordpress content. Before you can set up Publishing you first have to install the WP Discourse plugin on Wordpress and connect it to your Discourse. If you’re ready to get started, start by watching this short video, or follow the instructions below.

Next Step

Once you’ve set up publishing, you may want to check out the following topics


Instructions

Publishing Settings

:warning: Make sure you always save your settings after changing them. Click the ‘Save Options’ button at the bottom of the page.

The settings should be relatively self-explanatory. If you’re having an issue understanding any of them please reply to this topic for a further clarification.

Default Discourse Category

Sets the default category in which your posts will be published on Discourse. This setting can be overridden for individual posts on the WordPress post-new screen.

Display Subcategories

Indicates whether or not you want your forum’s subcategories to be available as categories that you can publish to from WordPress. You will need to save this setting before subcategories become available in the Default Discourse Category option input.

Force Category Update

For when you have added new categories to your forum and would like them to be available on your WordPress site. Enabling this setting and saving the options page makes a single API call to Discourse to retrieve the Discourse categories. After enabling it, the next time you navigate back to the Commenting tab, you will find the setting disabled.

Allow Tags

Enable this if you would like to add tags to Discourse topics that are created via WordPress.

Publish as Unlisted Topics

Will cause posts published from WordPress to be unlisted on Discourse. If you enable the Sync Comment Data webhook setting, unlisted posts will be made visible when they first receive a reply on Discourse.

Use Full Post Content

Let’s you publish full WordPress posts, rather than excerpts, to your Discourse forum. To keep the Show Full Post button from appearing under your post on Discourse, you must un-select the embed truncate site setting on Discourse (found at yourforum.com/admin/site_settings/category/posting.)

Custom Excerpt Length

If you have not selected the Use Full Post Content setting, this setting will create excerpts of that length to be published to Discourse. You can also manually create excerpts when you create a WordPress post by adding the excerpt to the Excerpt meta-box.

Auto Publish

This pre-check’s the Publish to Discourse checkbox that appears on the post-new screen for post-types that are to be published to Discourse. The checkbox can still be un-checked when creating the post.

Auto Track Published Topics

This setting is enabled by default. When enabled, the author of a post published to Discourse from WordPress will automatically be ‘Watching’ the topic (they will receive Discourse notifications about every new reply)

Post Types to Publish

This setting must be set. It defaults to post, but pages and custom post types may also be selected.

Exclude Posts By Tag

If you add Wordpress tags to this setting, any Wordpress post with one of the tags will not be published to Discourse.

Do Not Display Discourse Name Field

This will hide the “Discourse Username” field in user’s profiles. The Discourse Username is used to set the author of the topic when publishing posts to Discourse.

Discourse Username Editable

This determines whether non-admins are able to edit their own Discourse Username in their profile. The Discourse Username is used to set the author of the topic when publishing posts to Discourse.

Direct Database Publication Flags

This setting is used in certain setups that have specialized Wordpress environments. Don’t use this setting unless you know what it does.

Verbose Publication Logs

Enabling this setting will mean that all posts published to Discourse are logged in the WP Discourse logs, even if they succeed. Normally only errors are logged.

Enable posting by XMLRPC

XML-RPC is a remote procedure call that is often used by blogging software for sending posts to WordPress. Apps that use this procedure include the wordpress.com blogging app.

By default, WP Discourse will not publish posts to Discourse that are created through XML-RPC. The reason for this is that there is no great way to indicate whether a post published through blogging software is meant to be published on Discourse.

If you would like to use blogging software for creating posts that are directly published to Discourse, you need to add some code to your theme’s functions.php file that hooks into the wp_discourse_before_xmlrpc_publish filter. The wp_discourse_before_xmlrpc_publish filter passes two arguments to functions that hook into it. The first argument, $publish_to_discourse is a boolean that is set to false to disable publishing by XML-RPC. The second argument is the post object.

To have all XML-RPC posts automatically published by Discourse you need to write a function that will always return true. Use something like the following code:

Warning: this will cause all posts published through XML-RPC to be published to Discourse, this will include old posts that are edited on blogging software.

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

Filtering XML-RPC posts by post tag

The wordpress.com blogging app allows you to add tags to posts. Tags can be used to control whether or not a post is published to Discourse. To only publish posts that have a ‘discourse’ tag, use something like this:

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

If you would like to use this method, but not have the discourse tag appear in your published posts, you can remove it with some code like this:

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

Filtering XML-RPC posts by post date

To only allow posts published after a certain date to be published to Discourse through XML-RPC, add some code like this to your functions.php file. This code will allow all posts published after January 1, 2016 to be published to 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;
}

Todo: add a filter to the wp-discourse plugin to allow for only publishing new posts (as opposed to edited posts) through XML-RPC.

Filtering the available categories for a custom post type

Before the Discourse categories are displayed in the Publish to Discourse meta-box on the Wordpress admin/post-new page, the Wordpress filter 'wp_discourse_publish_categories' is applied to them. It is given the Discourse categories array, and the current post as arguments. This can be used in your theme’s functions.php file to limit which categories are available for a given post type.

Here is an example that creates an 'acme_product' post type and then returns the Discourse categories ‘fun’ and ‘scratch’ to be displayed in the Publish to Discourse meta-box for posts of that type.

// Create the post type.
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,
    )
  );
}

// Filter the available categories for the 'acme_product' post type.
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;
}

If you want to strictly apply a specific category to specific post types (i.e. 1:1) then you should use wpdc_publish_post_category instead.

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' );

Display metadata of a connected Discourse topic

When you have Publishing set up you can display metadata about the Discourse topic by using Template Customisation.

First, you need to decide which template you wish to modify. If, for example, you only wish to show topic metadata, and no replies as comments, then you’ll want to modify the no_replies template.

Once you’ve chosen a template, you can modify it to add Discourse topic metadata. Here’s a snippet that does that, with some comments explaining what the code is doing

// ensure wp-discourse is present using your preferred method,
// e.g. https://wordpress.stackexchange.com/questions/127818/how-to-make-a-plugin-require-another-plugin

// Require the plugin-utilities from the wp-discourse plugin
require_once ABSPATH . 'wp-content/plugins/wp-discourse/lib/plugin-utilities.php';
use WPDiscourse\Shared\PluginUtilities;

// Encapsulate your topic metadata template in a class so you can easily include the plugin utilities
class DiscourseTopicMetadata {
  
  // Include the wp plugin utilities in your class
  use PluginUtilities;
  
  public function __construct() {

    // Add the template filter on the initialization of the class
    add_filter( 'discourse_no_replies_html', array( $this, 'topic_metadata_html' ) );
  }

  function topic_metadata_html( $input ) {
    // Get the discourse permalink from the post metadata
    $discourse_permalink = get_post_meta( get_the_ID(), 'discourse_permalink', true );

    // Use the discourse permanlink to get the topic JSON from Discourse, using the helper method from the plugin utilities which handles authorization for you
    $topic = $this->get_discourse_topic($discourse_permalink);
   
    // Output your markup, including which topic metadata you wish to display
    ob_start();
    ?>
    <div id="discourse-topic-meta">
        <div class="views">
          Views
          <?php echo $topic->views; ?>
        </div>
        <div class="replies">
          Replies
          <?php echo $topic->reply_count; ?>
        </div>
    </div>
    <?php
    
    return ob_get_clean();
  }
}

// Instantiate the class to add the filter
new DiscourseTopicMetadata();

For more details on what topic metadata is available in the response from get_discourse_topic see 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 个赞