WP Discourse Plugin Tips and Tricks

wordpress

(Simon Cossar) #1

Adjusting the comments_number sync period for WordPress archive pages

To get the correct number of Discourse comments for a post, the plugin needs to periodically make an HTTP request to Discourse to get the current comments number. On single pages this period is set to be no more often than every 10 minutes. For archive pages the period is set to no more than once every 24 hours. The reason for this is to avoid making multiple request to Discourse every time an archive page is accessed.

If you still find that the plugin is making too many request to Discourse when displaying your site’s archive pages, you can adjust the archive_page_sync_period by hooking into the 'discourse_archive_page_sync_period' filter. You do that by adding something like this to your theme’s functions.php file:

add_filter( 'discourse_archive_page_sync_period', 'my_namespace_archive_page_sync_period' );
function my_namespace_archive_page_sync_period( $sync_period ) {
    // This will change to sync_period for archived posts to once a week.
    return WEEK_IN_SECONDS;
}

If you find that the plugin is not making enough requests to Discourse to retrieve the current comment numbers for archive pages, you can add something like this to your theme’s functions.php file. This will set the archive_page_sync_period to 10 minutes.
Note: on a busy site this could place a heavy load on your server.

add_filter( 'discourse_archive_page_sync_period', 'my_namespace_archive_page_sync_period' );
function my_namespace_archive_page_sync_period( $sync_period ) {
    // This will change to sync_period for archived posts to once a week.
    return 10 * MINUTE_IN_SECONDS;
}

Dealing with comment number issues when displaying both Discourse and WordPress comments for a post.

The wp-discourse plugin uses the WordPress get_comments_number filter hook so that the number of Discourse comments that have been created for a post can be displayed throughout your theme. This creates a conflict when both Discourse and WordPress comments are being displayed for a post. The plugin is able to resolve that conflict in most places. One place where it can’t be resolved is in the comment title that WordPress themes often display at the head of the comment section. This is the section that begins with something like “2 thoughts on…”

The easiest way to do this is to add a rule to your theme’s css file.

.discourse-comments-area ~ .comments-area .comments-title  {
	display: none;
}

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.

Dealing with WordPress shortcodes

The WP Discourse plugin does not process shortcodes before the content is published to Discourse. If your WordPress posts must include shortcodes in the content that is published to Discourse, those shortcode will be published as [shortcode_name] . Here are three different approaches for dealing with shortcodes that may be in your posts. The first two functions remove the shortcodes, the last function ‘does’ the shortcodes. Note: ‘doing’ the shortcodes will generally result in the output being processed by Discourse as code. This is because of whitespace that gets added to the output.

// Removes anything that looks like a shortcode. This will remove anything in the post that
// occurs inside of brackets `[...]`.
add_filter( 'wp_discourse_excerpt', 'testeleven_remove_shortcodes' );
function testeleven_remove_shortcodes( $excerpt ) {
    $excerpt = preg_replace( '/\[.*\]/', '', $excerpt );

    return $excerpt;
}

// Strips any shortcodes from the post content. If  theme is wrapping content between
// opening and closing shortcodes, that content will be removed as well.
add_filter( 'wp_discourse_excerpt', 'testeleven_strip_shortcodes' );
function testeleven_strip_shortcodes( $excerpt ) {
    $excerpt = strip_shortcodes( $excerpt );

    return $excerpt;
}

// Searches the content for shortcodes and filter shortcodes through their hooks.
add_filter( 'wp_discourse_excerpt', 'testeleven_do_shortcodes' );
function testeleven_do_shortcodes( $excerpt ) {
    $excerpt = do_shortcode( $excerpt );

    return $excerpt;
}

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 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 ‘bikes’ and ‘tents’ 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' ),
            'has_archive' => 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 ( 'tents' === $category['name'] || 'bikes' === $category['name'] ) {
                $output[] = $category;
            }
        }
        return $output;
    }

    return $categories;
}

remove the require_activation flag

If you’re sure that WordPress is authenticating email addresses, you can tell Discourse that it doesn’t need to. To completely remove the require_activation flag, add something like this to your theme’s functions.php file:

// Replace 'my_prefix' with your site prefix.

add_filter( 'discourse_email_verification', 'my_prefix_discourse_email_verification' );
function my_prefix_discourse_email_verification( $require_activation, $user_id ) {
    return false;
}

To remove the require_activation flag for specific users, use something like this:

// Replace 'my_prefix' with your site prefix.

add_filter( 'discourse_email_verification', 'my_prefix_discourse_email_verification', 10, 2 );
function my_prefix_discourse_email_verification( $require_activation, $user_id ) {
    $user = get_userdata( $user_id );
    if ( /* some condition tested against $user */ ) {

        return true;
    }

    return false;
}

Displaying the comments template with the Timber theme

The Timber WordPress theme uses the Twig template engine. This creates a problem for including the WP Discourse comments template, which is written in PHP. To include the comments template, modify the comments section of the single.twig file to something like this. The important part is calling the wpdc_comments_template function with post.id as it’s argument.

    <section class="comment-box">

    <!-- comments -->

    {% if post.publish_to_discourse == 1 %}
        <div class="comments">
            {{ function ('wpdc_comments_template', post.id) }}
        </div>
    {% else %}
        <div class="comments">
            {% if post.comments %}
                <h3> comments </h3>
                {% for cmt in post.comments %}
                    {% include "comment.twig" with {comment:cmt} %}
                {% endfor %}
            {% endif %}
        </div>

        {% if post.comment_status == "closed" %}
            <p> comments for this post are closed </p>
        {% else %}
            <!-- comment form -->
            {% include "comment-form.twig" %}
        {% endif %}
    {% endif %}

</section>

Then add the wpdc_comments_template function to your theme’s functions.php file.

function wpdc_comments_template( $post_id ) {
    do_action( 'wpdc_sync_discourse_comments', $post_id );
    $comments_template = WPDISCOURSE_PATH . 'templates/comments.php';

    ob_start();
    include $comments_template;
    $template = ob_get_clean();

    return $template;
}

Creating an SSO Login Link

If you have the SSO Provider option enabled, you can add an SSO login link to your WordPress site by creating a link with the following structure:

<a href="https://discourse.example.com/session/sso?return_path=/">Community</a>

Set the value of return_path to the page on your forum you would like the user to end up on. You can add an SSO login link to a WordPress menu by adding a URL with this structure as a Custom Link in the Menus section of the WordPress dashboard.


WP Discourse template customization
WP Discourse plugin installation and setup
WP Discourse 1.0.0 release
Clearing the text from the shortcode
WP Discourse 1.4.0 Release
Filtering Pages and Posts for shortcode
WP Discourse 1.0.0 release
WP-discourse: how to deal with shortcodes in post
WP Discourse 1.5 Release
Link custom user field to external website
Editing linked Discourse posts/topics without changes being overridden by Wordpress?
(Simon Cossar) #7

2 posts were split to a new topic: What does selecting Update Discourse Topic do?


(François Douville) #8

For comments, is it possible to add a button like this reply instead of a text “join discussion at [link]”?


WP Discourse plugin installation and setup
(Simon Cossar) #9

On the plugin’s Text Content tab, set the Discourse Link text to ‘Reply’. Remove the text from the Start Discussion, Continue Discussion, and Join Discussion settings. This will give you a link with the text ‘Reply’. You can style the link however you like. Unfortunately, the link doesn’t have a CSS class yet, so you have to use .comment-reply-title a to target the link.

This CSS is from an online button generator. It could be improved.

.comment-reply-title a {
  background:    #0088cc;
  border-radius: 0px;
  padding:       8px 20px;
  color:         #ffffff;
  display:       inline-block;
  font:          normal 700 24px/1 sans-serif;
  text-align:    center;
  text-shadow:   none;
}

The reply icon isn’t included with the plugin. To add a reply icon you will need to include the icon in your theme. I’m using Fontello icons here.

.comment-reply-title a:before {
  font-family: "fontello";
  content: '\f112';
  font-style: normal;
  font-weight: normal;
  speak: none; 
  display: inline-block;
  text-decoration: inherit;
  width: 1em;
  margin-right: .2em;
  text-align: center;
}

This could be improved, but it’s getting close:

23%20AM