# WP Discourse: advanced custom filter for discourse\_publish\_format\_html

**URL:** https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059
**Category:** WordPress
**Created:** [January 9, 2019, 2:35pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059 "2019-01-09T14:35:02Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Kayla](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kayla/32/128523_2.png) [@Kayla](https://meta.discourse.org/u/Kayla)
#### Post date: [January 9, 2019, 2:35pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/1 "2019-01-09T14:35:02Z")

</div>

I’m having trouble with a custom filter for posting content to Discourse. My installation is the exact same website mentioned by Marco in the topic below (resolved):

> [@WP Discourse: can't access editor for post types created with Toolset Types plugin](https://meta.discourse.org/t/wp-discourse-cant-access-editor-for-post-types-created-with-toolset-types-plugin/105725):
>
> Hi, I am using the [WP Discourse](https://github.com/discourse/wp-discourse) plugin on a Wordpress 5.0.2 multisite, and have successfully had multiple sites on the network integrated with our Discourse instance. This works for default posts and pages, as well as for custom post types created by podcasting and event plugins. However, on custom post types created with the [Toolset Types](https://wordpress.org/plugins/types/) plugin, I am not able to access the editor when enabling the WP-Disource plugin (v. 1.79 and 1.8). Unselecting [WP Discourse](https://github.com/discourse/wp-discourse) for those content types restores …

Also, because this is a multisite where we want the same [WP Discourse](https://github.com/discourse/wp-discourse) customizations across all, instead of using each individual theme’s functions.php file, I created a single file plugin exclusively for [WP Discourse](https://github.com/discourse/wp-discourse) template customizations inside the /wp-contents/mu-plugins/ folder. This file includes custom output for `discourse_replies_html`, `discourse_no_replies_html`, and `discourse_publish_format_html`, in that order. I don’t think this my issue, but this is where the code l want to talk about lives.

At the moment, I’m attempting to publish 2 different CPTs and WP native posts to discourse. Before incorporating the CPTs into the mix, I was using the following with expected results:

> [@Customize the structure of WP Discourse templates](https://meta.discourse.org/t/customize-the-structure-of-wp-discourse-templates/50754/1):
>
> #### Publish the WordPress post as a onebox on Discourse
> 
> This customization will cause the WordPress post to be published as a onebox on your forum.
> 
> _Before making this customization, check that oneboxes are created on your forum when you add the URL of one of your WordPress posts to Discourse._
> 
> ```plaintext
> function your_namespace_publish_format_html() {
> ob_start();
> the_permalink(); // The post's WordPress permalink
> $output = ob_get_clean();
> 
> return $output;
> }
> add_filter( 'discourse_publish_format_html', 'your_namespace_publish_format_html' );
> 
> ```

Now I am experiencing a couple of issues in getting my custom filter to work as I’d like with the CPTs. After referencing [link 1] and [link 2], I successfully added a check for if the post type was ‘event’ (generated by Events Manager) and outputting custom fields associated with that CPT. However, I wanted the default to remain oneboxed, but the aforementioned onebox code snippet returns nothing but a “See Full Post” link. (Clicking to see full post does load the content of the post, fwiw.)

If I replace the onebox code snippet with something else, like

```plaintext
// else return
    ob_start();
    ?>

    <small>Originally published at: {blogurl}</small><br><br>
    <?php echo $image ?>
    {excerpt}

    <?php
    $output = ob_get_clean();
    
    return $output; 

```

I’ll get the “Originally published at…” + the excerpt, but not `$image` (based on [link 3] for checking whether a post in fact has a featured image). I want to have the onebox back if the post type doesn’t match my CPTs, but this curious lack of picking up the featured image in this experiment has me thinking I have a mistake in my logic. I will post the full code I am using at the end of this overview.

My second issue is that my Toolset-generated CPT ‘groups’ doesn’t publish with it’s associated `if` post-type customizations. I have the correct post type name, as I’m using it in the theme’s functions.php for a different purpose but with expected results in that context. I based this `if` section on my successful `if ( 'event' === $post->post_type)` section, but referencing fields that pertain to the ‘groups’ CPT. Even if I have the custom field names wrong in this section, I expect to see at least the featured image and excerpt, etc, as I did when I was working out how to get the right fields for the ‘event’ CPT. Instead, this ‘groups’ CPT is using the `// else return` output. So, for example, when I was attempting to use the onebox code snippet, it also only returned the “See Full Post” button (and would also successfully load the post content when clicked).

In conclusion, I’ll reiterate that the `if ( 'event' === $post->post_type)` section totally works as intended and I’ve tested many different events with different date settings, with and without the Video Conference URL event attribute. It renders the `$image` as expected. Given those hidden fields, it was all sorts of fun to work out, and I hope my code helps someone else struggling to integrate Events Manager with Discourse. However, something seems to be amiss in the combination of that with the rest of what I’m trying to do here, and I hope someone can see where I’m going wrong. Here’s the full function with the non-onebox default:

```plaintext
// when publishing a post to Discourse
function cosmos_custom_publish_format_html() {
	global $post;
	
	// if featured image is present, use it
	if ( has_post_thumbnail() ) {
		$image = "{thumbnail}<br><br>";
	} else {
		$image = "";
	}

    // if post is an event, get the custom field information
    if ( 'event' === $post->post_type) {
    	$startdate = get_post_meta($post->ID, '_event_start_date', true);
    	$starttime = get_post_meta($post->ID, '_event_start_time', true);
    	$enddate = get_post_meta($post->ID, '_event_end_date', true);
    	$endtime = get_post_meta($post->ID, '_event_end_time', true);
        $startdateformatted = date('j M Y', strtotime($startdate));
        $starttimeformatted = date('g:i a', strtotime($starttime));
        $enddateformatted = date('j M Y', strtotime($enddate));
        $endtimeformatted = date('g:i a', strtotime($endtime));
        $eventallday = get_post_meta($post->ID, '_event_all_day', true);
        $eventtimezone = get_post_meta($post->ID, '_event_timezone', true);
        $videoconferenceurl = get_post_meta($post->ID, 'Video Conference URL', true);
        
        if ($startdate == $enddate && $eventallday !== '1') {
          $eventinfo = "<strong>Date/Time:</strong> {$startdateformatted} @ {$starttimeformatted} - {$endtimeformatted} {$eventtimezone}";
        }
        
        if ($startdate !== $enddate && $eventallday !== '1') {
          $eventinfo = "<strong>Date/Time:</strong> {$startdateformatted} @ {$starttimeformatted} - {$enddateformatted} {$endtimeformatted} {$eventtimezone}";
        }
        
        if ($startdate == $enddate && $eventallday == '1') {
          $eventinfo = "<strong>Date/Time:</strong> {$startdateformatted} <i>All Day</i>";
        }
        
        if ($startdate !== $enddate && $eventallday == '1') {
          $eventinfo = "<strong>Date/Time:</strong> {$startdateformatted} - {$enddateformatted}";
        }
        
        if ($videoconferenceurl !== '') {
          $videoconferenceurlformatted = "<strong>Video Conference Link:</strong> {$videoconferenceurl}<br><br>";
        }
        
        if ($videoconferenceurl == '') {
          $videoconferenceurlformatted = "";
        }
                
        ob_start();
        ?>
	  
        <small>Originally published at: {blogurl}</small><br><br>
        <?php echo $image ?>
        <?php echo $eventinfo ?><br>
        <?php echo $videoconferenceurlformatted ?>
        {excerpt}
	  
        <?php 
        $output = ob_get_clean();
        
        return $output;
    }
    
    // if post is a group, get the custom field information
    if ( 'groups' === $post->post_type) {
    	$groupstartdate = get_post_meta($post->ID, 'wpcf-start-date', true);
    	$groupenddate = get_post_meta($post->ID, 'wpcf-end-date', true);
        $groupstartdateformatted = date('j M Y', strtotime($groupstartdate));
        $groupenddateformatted = date('j M Y', strtotime($groupenddate));
        $groupvideoconferenceurl = get_post_meta($post->ID, 'wpcf-video-conference-url', true);
        
        if ($groupenddate !== '') {
          $groupinfo = "<strong>Start Date:</strong> {$groupstartdateformatted}<br /><strong>End Date:</strong> {$groupenddateformatted}";
        }
        
        if ($groupenddate == '') {
          $groupinfo = "<strong>Start Date:</strong> {$groupstartdateformatted}<br /><strong>End Date:</strong> TBD";
        }
        
        if ($groupvideoconferenceurl !== '') {
          $groupvideoconferenceurlformatted = "<strong>Video Conference Link:</strong> {$groupvideoconferenceurl}<br><br>";
        }
        
        if ($groupvideoconferenceurl == '') {
          $groupvideoconferenceurlformatted = "";
        }
        	
        ob_start();
        ?>
	  
        <small>Originally published at: {blogurl}</small><br><br>
        <?php echo $image ?>
        <?php echo $groupinfo ?><br>
        <?php echo $groupvideoconferenceurlformatted ?>
        {excerpt}
	  
        <?php
        $output = ob_get_clean();
	  
        return $output;
    }   
      
    // else return
    ob_start();
    ?>

    <small>Originally published at: {blogurl}</small><br><br>
    <?php echo $image ?>
    {excerpt}

    <?php
    $output = ob_get_clean();
    
    return $output; 

}
add_filter( 'discourse_publish_format_html', 'cosmos_custom_publish_format_html' );

```

---

<div class="post-metadata">

### Author: ![Kayla](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kayla/32/128523_2.png) [@Kayla](https://meta.discourse.org/u/Kayla)
#### Post date: [January 9, 2019, 2:37pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/2 "2019-01-09T14:37:41Z")

</div>

I’m a new user, so I got a message I had too many links in my post, so

Link 1:

> [@WP-discourse: how to deal with shortcodes in post](https://meta.discourse.org/t/wp-discourse-how-to-deal-with-shortcodes-in-post/58838/4):
>
> For posts where you need the shortcode content to be published to Discourse, it’s possible to publish the post in an iframe. This works best if the WordPress posts uses a custom post-type. That way you can decide which posts are to be published in an iframe. It takes a bit of work on the WordPress end so that posts are published in a format that’s suitable for putting in an iframe. You also need to be able to whitelist the iframe on Discourse for this to work. I’ve been testing this with both a…

Link 2:

> [@How to pass custom field types and taxonomies to the WordPress plugin?](https://meta.discourse.org/t/how-to-pass-custom-field-types-and-taxonomies-to-the-wordpress-plugin/77817/2):
>
> Yes. You can customize the discourse\_publish\_format\_html template for a specific post type. See this topic for more details about customizing the templates: [Customize the structure of WP Discourse templates](https://meta.discourse.org/t/wp-discourse-template-customization/50754) Something like this, added to a plugin, or to your theme’s functions.php file should work. You can use the following tags in the template: {excerpt}, {blogurl}, {author}, {thumbnail}, {featuredimage} add\_filter( 'discourse\_publish\_format\_html', 'wpdc\_custom\_discourse\_publish\_format\_html' …

Link 3:  
[https://meta.discourse.org/t/wp-discourse-template-customization/50754/13](https://meta.discourse.org/t/wp-discourse-template-customization/50754/13)

---

<div class="post-metadata">

### Author: ![jtbayly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jtbayly/32/119510_2.png) [@jtbayly](https://meta.discourse.org/u/jtbayly)
#### Post date: [January 9, 2019, 4:46pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/3 "2019-01-09T16:46:50Z")

</div>

> [@Kayla](#):
>
> However, I wanted the default to remain oneboxed, but the aforementioned onebox code snippet returns nothing but a “See Full Post” link.

I’m running into the same trouble right now (inconsistently), but I’m not using a custom post type or anything else odd in my setup. I think it’s only with scheduled posts that it happens for me.

---

<div class="post-metadata">

### Author: ![bts](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bts/32/184556_2.png) [@bts](https://meta.discourse.org/u/bts)
#### Post date: [January 9, 2019, 6:32pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/4 "2019-01-09T18:32:00Z")

</div>

Same, we just published a normal blog post, with ‘discourse\_publish\_format\_html’ filtered as follows:

```plaintext
function ccmm_discourse_publish_format_html()
{
	ob_start();
	echo "<h2>View on the Cracking the Code Platform:</h2><br />\n\n";
	the_permalink(); // The post's WordPress permalink
	$output = ob_get_clean();
	return $output;
}
add_filter('discourse_publish_format_html', 'ccmm_discourse_publish_format_html');

```

And only the “view on platform” part worked, not `the_permalink()`.

@simon I believe this is the first blog post we’ve published since upgrading to WP 5.0 (w/ Gutenberg editor), I wonder if that could have something to do with this?

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [January 9, 2019, 7:56pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/5 "2019-01-09T19:56:30Z")

</div>

> [@bts](#):
>
> I believe this is the first blog post we’ve published since upgrading to WP 5.0 (w/ Gutenberg editor), I wonder if that could have something to do with this?

Yes, when I try to use `the_permalink()` or `get_permalink()` with a post published using the Block Editor it’s returning an empty string. When I publish the same post with the Classic Editor plugin, the permalink is retrieved. I’ll look into this.

Edit: it looks like the `post_id` needs to be passed to the custom template function for this to work with the Block Editor. I’ll need to make a small update to the plugin for this to be possible. When that’s been done, you’ll have to update your custom template if you want to use the permalink.

I’ll try to get this done by tomorrow. In the meantime, installing the Classic Editor plugin and publishing your posts with it should solve the problem.

---

<div class="post-metadata">

### Author: ![Kayla](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kayla/32/128523_2.png) [@Kayla](https://meta.discourse.org/u/Kayla)
#### Post date: [January 9, 2019, 8:48pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/6 "2019-01-09T20:48:26Z")

</div>

I think the Block Editor might be the source of the issues I’m having, then. I kept playing around and even if I reduce my entire function to the same output regardless of post type, I realized I can get the featured image to show if I use `{thumbnail}` but not if I try the `global $post;` with either `if ( has_post_thumbnail() )` or `if (has_post_thumbnail( $post->ID ) )`. I couldn’t understand why the ‘event’ CPT was picking up the featured image just fine either way, but I have realized the difference is indeed: the events are still using the Classic Editor, while the posts and groups I’ve been testing with are using the Block Editor. This must be also why the entire `if ( 'groups' === $post->post_type)` wasn’t working for me either.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [January 9, 2019, 8:54pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/7 "2019-01-09T20:54:59Z")

</div>

> [@Kayla](#):
>
> This must be also why the entire `if ( 'groups' === $post->post_type)` wasn’t working for me either.

Yes, when the Block Editor is used, posts are published through the WordPress REST API. This means that `global $post` doesn’t return anything.

When I update the template so that it accepts a `$post_id` parameter, what you are trying to do should work. I’ll update it tomorrow, and provide some example code.

---

<div class="post-metadata">

### Author: ![jtbayly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jtbayly/32/119510_2.png) [@jtbayly](https://meta.discourse.org/u/jtbayly)
#### Post date: [January 9, 2019, 9:54pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/8 "2019-01-09T21:54:23Z")

</div>

We have the block editor disabled. Not sure why this has happened occasionally, but all I can figure out that’s different from the other posts is that it is scheduled. Would that possibly mean it’s done via REST API?

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [January 9, 2019, 9:56pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/9 "2019-01-09T21:56:30Z")

</div>

> [@jtbayly](#):
>
> all I can figure out that’s different from the other posts is that it is scheduled. Would that possibly mean it’s done via REST API?

Yes, if permalinks are failing to appear for scheduled posts, this is most likely the problem. The next update should make it possible for you to fix the issue.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [January 11, 2019, 12:31am UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/10 "2019-01-11T00:31:07Z")

</div>

If you update to [WP Discourse Version 1.8.2](https://wordpress.org/plugins/wp-discourse/), you can now pass a `$post_id` parameter to the `publish_format_html` template. Doing this will make it possible to access the current post when the post is published with the Block Editor, or through the REST API.

Here’s a quick example of how to use it. I’ll add more detailed examples and update [Customize the structure of WP Discourse templates](https://meta.discourse.org/t/wp-discourse-template-customization/50754) very soon.

```plaintext
function wpdc_custom_publish_format_html( $output, $post_id ) {
	ob_start();
    the_permalink( $post_id );
	$output = ob_get_clean();
	return $output;
}
add_filter( 'discourse_publish_format_html', 'wpdc_custom_publish_format_html', 10, 2 );

```

To have access to the `$post_id` parameter, you need to be sure to call `add_filter` with the priority and accepted\_args parameters from the example.

For cases where you are trying to access properties of the current post, instead of using `global $post` use

```plaintext
$post = get_post( $post_id );

```

---

<div class="post-metadata">

### Author: ![Kayla](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kayla/32/128523_2.png) [@Kayla](https://meta.discourse.org/u/Kayla)
#### Post date: [January 11, 2019, 2:36pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/11 "2019-01-11T14:36:59Z")

</div>

The updated plugin and modified function/filter have solved my original issues. I was playing some more with the output and decided to move the `<small>Originally published at: {blogurl}</small>` to below the excerpt. Even if I reduce it to `{excerpt}{blogurl}`, the url prints as plain text (no link). Works if changed to `{blogurl}{excerpt}`, why is that?

---

<div class="post-metadata">

### Author: ![Kayla](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kayla/32/128523_2.png) [@Kayla](https://meta.discourse.org/u/Kayla)
#### Post date: [January 11, 2019, 2:51pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/12 "2019-01-11T14:51:54Z")

</div>

For others, here’s how you’d modify my original block of code to work with the updated plugin, but this time with the desired oneboxed default 🙂:

```plaintext
// when publishing a post to Discourse
function cosmos_custom_publish_format_html( $output, $post_id ) {
	$post = get_post( $post_id );
	
	// if featured image is present, use it
	if ( has_post_thumbnail( $post_id ) ) {
		$image = "{thumbnail}<br><br>";
	} else {
		$image = "";
	}

    // if post is an event, get the custom field information
    if ( 'event' === $post->post_type) {
    	$startdate = get_post_meta($post->ID, '_event_start_date', true);
    	$starttime = get_post_meta($post->ID, '_event_start_time', true);
    	$enddate = get_post_meta($post->ID, '_event_end_date', true);
    	$endtime = get_post_meta($post->ID, '_event_end_time', true);
        $startdateformatted = date('j M Y', strtotime($startdate));
        $starttimeformatted = date('g:i a', strtotime($starttime));
        $enddateformatted = date('j M Y', strtotime($enddate));
        $endtimeformatted = date('g:i a', strtotime($endtime));
        $eventallday = get_post_meta($post->ID, '_event_all_day', true);
        $eventtimezone = get_post_meta($post->ID, '_event_timezone', true);
        $videoconferenceurl = get_post_meta($post->ID, 'Video Conference URL', true);
        
        if ($startdate == $enddate && $eventallday !== '1') {
          $eventinfo = "<strong>Date/Time:</strong> {$startdateformatted} @ {$starttimeformatted} - {$endtimeformatted} {$eventtimezone}";
        }
        
        if ($startdate !== $enddate && $eventallday !== '1') {
          $eventinfo = "<strong>Date/Time:</strong> {$startdateformatted} @ {$starttimeformatted} - {$enddateformatted} {$endtimeformatted} {$eventtimezone}";
        }
        
        if ($startdate == $enddate && $eventallday == '1') {
          $eventinfo = "<strong>Date/Time:</strong> {$startdateformatted} <i>All Day</i>";
        }
        
        if ($startdate !== $enddate && $eventallday == '1') {
          $eventinfo = "<strong>Date/Time:</strong> {$startdateformatted} - {$enddateformatted}";
        }
        
        if ($videoconferenceurl !== '') {
          $videoconferenceurlformatted = "<strong>Video Conference Link:</strong> {$videoconferenceurl}<br><br>";
        }
        
        if ($videoconferenceurl == '') {
          $videoconferenceurlformatted = "";
        }
                
        ob_start();
        ?>
	  
        <small>Originally published at: {blogurl}</small><br><br>
        <?php echo $image ?>
        <?php echo $eventinfo ?><br>
        <?php echo $videoconferenceurlformatted ?>
        {excerpt}
	  
        <?php 
        $output = ob_get_clean();
        
        return $output;
    }
    
    // if post is a group, get the custom field information
    if ( 'groups' === $post->post_type) {
    	$groupstartdate = get_post_meta($post->ID, 'wpcf-start-date', true);
    	$groupenddate = get_post_meta($post->ID, 'wpcf-end-date', true);
        $groupstartdateformatted = date('j M Y', strtotime($groupstartdate));
        $groupenddateformatted = date('j M Y', strtotime($groupenddate));
        $groupvideoconferenceurl = get_post_meta($post->ID, 'wpcf-video-conference-url', true);
        
        if ($groupenddate !== '') {
          $groupinfo = "<strong>Start Date:</strong> {$groupstartdateformatted}<br /><strong>End Date:</strong> {$groupenddateformatted}";
        }
        
        if ($groupenddate == '') {
          $groupinfo = "<strong>Start Date:</strong> {$groupstartdateformatted}<br /><strong>End Date:</strong> TBD";
        }
        
        if ($groupvideoconferenceurl !== '') {
          $groupvideoconferenceurlformatted = "<strong>Video Conference Link:</strong> {$groupvideoconferenceurl}<br><br>";
        }
        
        if ($groupvideoconferenceurl == '') {
          $groupvideoconferenceurlformatted = "";
        }
        	
        ob_start();
        ?>
	  
        <small>Originally published at: {blogurl}</small><br><br>
        <?php echo $image ?>
        <?php echo $groupinfo ?><br>
        <?php echo $groupvideoconferenceurlformatted ?>
        {excerpt}
        	  
        <?php
        $output = ob_get_clean();
	  
        return $output;
    }   
      
    // else return
    ob_start();
    the_permalink( $post_id );
	$output = ob_get_clean();
	return $output;
    
}
add_filter( 'discourse_publish_format_html', 'cosmos_custom_publish_format_html', 10, 2 );

```

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [February 10, 2019, 2:51pm UTC](https://meta.discourse.org/t/wp-discourse-advanced-custom-filter-for-discourse-publish-format-html/106059/13 "2019-02-10T14:51:58Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
