Custom Excerpt Length not working for me

I’m trying to reduce the number of words that show up in “Discours” when I publish an article in WordPress. But instead I don’t see a single word :slight_smile:


2 Likes

Are you using the Block editor, or the old Classic editor to publish the post?

Are you able to share a link to the post? That might give some clues about what is going wrong.

What happens if you try manually adding an excerpt to the post:

Thank you for your response. We’re still using the classic editor.
It’s happening to us currently for all articles, but here are the links:

I don’t know if I fully understand how to add an excerpt manually.

We haven’t used “Excerpt” for posts in WordPress for a few years now, I didn’t get it right away.

But it seems that when I fill in “manually” in WordPress everything works fine.

Is there any solution to get the first X words to be sent to Discourse without having to manually fill in “Excerpt”?

1 Like

That makes sense. The logic that is used to create the excerpt is different when the excerpt is manually created than it is when the WP Discourse plugin parses the excerpt from the post’s content.

It should work now, but there may be a conflict on your site between the Discourse plugin and another plugin that you have installed on the site. Another possibility is that you are using shortcodes in the post that are not being parsed correctly when the Discourse plugin attempts to create the excerpt.

Are you using shortcodes in your posts?

For my own reference, the issue seems to be here: https://github.com/discourse/wp-discourse/blob/main/lib/discourse-publish.php#L297-L299. I’m assuming something is going wrong related to the call to $excerpt = apply_filters( 'the_content', $raw );

3 Likes

Yes, we use shortcodes. I’ll try temporarily disabling them and see what happens. Thanks for the directions. I’ll let you know what we find.

1 Like

If I disable most of the plugins on the site, everything seems to work correctly. Thanks for the directions. I’m going to look for the problematic plugin :slight_smile:

2 Likes

A few hours later :). I’ve already found the culprit, does the plugin Lnk.Bio – Plugin WordPressu | WordPress.org Česko do it any ideas how to fix it?

1 Like

The LnkBio plugin has a function that hooks into the 'wp_insert_post' action. That function calls unset($post->post_content) on the WordPress $post object. Theoretically, this shouldn’t unset the post’s post_content attribute outside of the LnkBio function, but when I test this locally (mocking the LnkBio plugin’s API calls), the call to unset($post->post_content) is unsetting the post content for the WP Discourse plugin here: https://github.com/discourse/wp-discourse/blob/main/lib/discourse-publish.php#L106.

This only happens when posts are published with the Classic Editor. If posts are published with the Block Editor, the post content is available to the WP Discourse plugin. I’m assuming this is because posts published with the Block editor are published via a REST request.

Note that I’m running into the issue of no content being published to Discourse both when I set a custom excerpt length and when I select the WP Discourse “Use Full Post Content” option.

The easiest fix would be to switch over to using the Block editor.

Another option would be to contact LnkBio and tell them about the issue. They could fix this by finding a safer way of parsing the post content for their API request:

function lnkbio_api_sync($post_id, $post, $update) {
	unset($post->post_content);
	if ($post->post_status === 'publish') {
		if (!get_option('lnkbio_id') || !get_option('lnkbio_secret')) {
			return;
		}
		// url set to `example.com` for testing without a lnkbio account
		wp_remote_post(
			'http://example.com',
			[
				'blocking' => false,
				'body' => [
					'ACTION' 	=> 'WP_sync',
					'post_id' 	=> $post_id,
					'post'    	=> json_encode($post),
					'id'		=> get_option('lnkbio_id'),
					'secret' 	=> get_option('lnkbio_secret'),
					'permalink' => get_permalink($post),
					'is_pub'	=> true,
					'image'		=> get_the_post_thumbnail_url($post_id, 'full'),
					'group_id' 	=> get_option('lnkbio_group'),
				]
			]
		);
	}
}

Edit: you could also just edit the LnkBio plugin’s code to remove the call to unset($post->post_content); and then finding a way of setting the appropriate values for the $post object that’s used here:

'post' => json_encode($post)

Generally editing plugins in this way is a bad idea, but it would work if you are very careful. Probably only do this if you have a way of testing your changes on a non-production site.

1 Like

Hi there,

This is the maintainer of the Lnk.Bio Wordpress plugin.

The function lnkbio_api_sync is only using the unset function on the local variable $post and it should not affect any code outside the function.

The $post variable is not passed via reference either, so it’s definitely only local to that function, otherwise it’d impact the post/excerpt everywhere in the WP code.

Any change we make to the $post is local to that function only, unless maybe Discourse code somehow uses global variables?

Do you have a sandbox Discourse installation for which you can share the API credentials so we can test the Discourse plugin locally and how it interacts with our code?

Thanks in advance

2 Likes

Yeah, that’s what I thought.

The WP Discourse plugin uses global $post in three places:

I’m not sure if this could have any impact on what’s going on. I’m also not seeing a good way of avoiding the use of global $post in those files.

This is interesting: Global Variables « WordPress Codex

Developers are advised to consider this a Reserved Name List, and not to create local variables with the same names in Plugins or Themes. Under some circumstances, the global variable value will be replaced by the local variable value, causing errors in the WordPress Core that are difficult to diagnose.

I think we might have found an edge case.

I don’t. I’m just providing free support here. I know you can signup for a free trial at Discourse pricing | Discourse - Civilized Discussion. Pick either the Standard or the Business plan. It only takes a few minutes to get a site up and running.

2 Likes

Thanks, appreciated the feedback.

We’ve signed up for the trial as you suggested and were able to reproduce the issue.

We found out that even renaming $post to $local_post or similar doesn’t solve the issue. The only workaround we found is to json_encode and then json_decode the content, as to create a completely separate object. Very ugly.

Nevertheless, we published an update to solve this incompatibility, even if the previous design was 100% correct from a code standpoint.

Here’s the patch that has already been published

-       unset($post->post_content);
+       $json = json_encode($post);
+       $local_post = json_decode($json);
+       unset($local_post->post_content);
        if ($post->post_status === 'publish') {
                if (!get_option('lnkbio_id') || !get_option('lnkbio_secret')) {
                        return;
@@ -138,7 +140,7 @@ function lnkbio_api_sync($post_id, $post, $update) {
                                'body' => [
                                        'ACTION'        => 'WP_sync',
                                        'post_id'       => $post_id,
-                                       'post'          => json_encode($post),
+                                       'post'          => json_encode($local_post),
                                        'id'            => get_option('lnkbio_id'),
                                        'secret'        => get_option('lnkbio_secret'),
                                        'permalink' => get_permalink($post),
1 Like

Thanks for doing that!

It looked correct to me. I was surprised by what was going on. I’m sorry if I came off a bit harsh in my initial post about the issue. I’d been puzzling over it for a few hours by then.

4 Likes

You didn’t come harsh at all, you had great insights.

After working on it a bit more, we found a better, more elegant solution using the clone function.

This has already been published to the updated Lnk.Bio plugin and the patch is simply

diff --git a/lnk.bio.php b/lnk.bio.php
index 65759fc..cc0c0d2 100644
--- a/lnk.bio.php
+++ b/lnk.bio.php
@@ -126,8 +126,7 @@ function lnkbio_api_post(string $url, array $data) {
 }

 function lnkbio_api_sync($post_id, $post, $update) {
-       $json = json_encode($post);
-       $local_post = json_decode($json);
+       $local_post = clone($post);
        unset($local_post->post_content);
        if ($post->post_status === 'publish') {
                if (!get_option('lnkbio_id') || !get_option('lnkbio_secret')) {
4 Likes

Thank you both so much, you have my admiration and respect for how quickly you were able to detect and solve the problem. Do you plan to officially incorporate this improvement into the Link.Bio plugin update? If so, when approximately?

1 Like

Looks like the update of the Lnk.Bio plugin is already done and working fine (I was a bit confused that the plugin version remained unchanged). Thanks

1 Like