skip to Main Content

This one has got me stumped.

I am offloading my wp_posts > post_content data to a custom field called post_content. See class at end of question to see how I am doing this.

And I am trying to filter the content loaded into my classic or block editor, so the content is actually loaded from my custom field called post_content, rather than loaded from the default wp_posts table.

I’ve tried these 3 filters and actions (not at the same time and no luck)…

add_action('edit_form_after_title', [ $this, 'load_custom_post_content_editor' ]);
    
public function load_custom_post_content_editor($post) {
        // Check if the post type is 'post' or 'page'
        if (in_array($post->post_type, array('post', 'page'))) {
            $custom_post_content = get_post_meta($post->ID, 'post_content', true);
            if (!empty($custom_post_content)) {
                $post->post_content = $custom_post_content;
            }
        }
    }
add_action('wp_insert_post_data', [ $this, 'modify_post_data' ], 10, 2);

public function modify_post_data($data, $postarr) {
        // Check if the post type is allowed.
        if (in_array($data['post_type'], self::$allowed_post_types)) {
            $custom_post_content = get_post_meta($postarr['ID'], 'post_content', true);
            if (!empty($custom_post_content)) {
                $data['post_content'] = $custom_post_content;
            }
        }
        return $data;
    }
add_filter('block_editor_content', [ $this, 'filter_block_editor_content' ], 10, 2);

public function filter_block_editor_content($content, $post) {
        // Check if the post type is allowed.
        if ($post && in_array($post->post_type, self::$allowed_post_types)) {
            $custom_post_content = get_post_meta($post->ID, 'post_content', true);
            if (!empty($custom_post_content)) {
                $content = $custom_post_content;
            }
        }
        return $content;
    }

None of these successfully load the content from my custom field in the WordPress editor, even though a ‘post_content’ custom field exists with the block editor content code inside the field.

Here the rest of my working class which offloads the post content to a custom field called post_content when saving post/pages in the admin…

<?php
/**
 * Plugin Name: WP JSON Search
 * Description: The WP JSON Search plugin allows you to search your WordPress website by merging complete post content, custom fields, and taxonomies into a single JSON string, which is then stored in your post_content in wp_posts table.
 * Version: 1.0
 * Author: Josh Cranwell
 * Author URI: https://github.com/joshmoto
 */

class WP_JSON_Search {

    /**
     * @var array|string[] Allowed post types to save json search content.
     */
    private static array $allowed_post_types = ['post', 'page'];

    /**
     * WP_JSON_Search constructor.
     */
    public function __construct () {

        // Save post_content to custom meta field when saving a draft or publishing a post/page.
        add_action('save_post', [ $this, 'save_post_content' ], 10, 2);

        // Filter the content to get data from the custom meta field.
        add_filter('the_content', [ $this, 'filter_the_content' ]);

    }

    /**
     * Save post_content to custom meta field when saving a draft or publishing a post/page.
     * @param $post_id
     * @param $post
     * @return void
     */
    public function save_post_content($post_id, $post): void
    {

        // Check if the post type is allowed.
        if (in_array($post->post_type, self::$allowed_post_types)) {

            // Set the post_content to the custom meta field.
            $post_content = $post->post_content;
            update_post_meta($post_id, 'post_content', $post_content);
            $post->post_content = ''; // Empty the default post_content field.

            // Unhook this function so it doesn't loop infinitely.
            remove_action('save_post', [ $this, 'save_post_content' ]);

            // Update the post, which calls save_post again.
            wp_update_post($post);

            // Re-hook this function.
            add_action('save_post', [ $this, 'save_post_content' ]);

        }
    }

    /**
     * Filter the content to get data from the custom meta field.
     * @param $content
     * @return mixed
     */
    public function filter_the_content($content): mixed
    {

        // Get the current post.
        global $post;

        // Check if the post type is allowed.
        if ($post && in_array($post->post_type, self::$allowed_post_types)) {

            // Get the post_content from the custom meta field.
            $custom_post_content = get_post_meta($post->ID, 'post_content', true);
            if (!empty($custom_post_content)) {
                $content = $custom_post_content;
            }
        }

        // Return the content.
        return $content;
    }

}

new WP_JSON_Search();

If anyone has any suggestions about how I can filter the content in the editor to load data from a custom field that would be so helpful.

2

Answers


  1. class WP_JSON_Search {
    
        // ... (existing code)
    
        public function __construct () {
    
            // Use 'edit_form_after_title' action to load custom post content into the editor.
            add_action('edit_form_after_title', [ $this, 'load_custom_post_content_editor' ]);
    
            // Use 'save_post' action to save post_content to the custom meta field.
            add_action('save_post', [ $this, 'save_post_content' ], 10, 2);
    
            // Use 'the_content' filter to filter the content in the editor.
            add_filter('the_content', [ $this, 'filter_the_content' ]);
    
        }
    
        public function load_custom_post_content_editor($post) {
            // Check if the post type is 'post' or 'page'
            if (in_array($post->post_type, array('post', 'page'))) {
                $custom_post_content = get_post_meta($post->ID, 'post_content', true);
                if (!empty($custom_post_content)) {
                    $post->post_content = $custom_post_content;
                }
            }
        }
    
        public function save_post_content($post_id, $post): void
        {
            // Check if the post type is allowed.
            if (in_array($post->post_type, self::$allowed_post_types)) {
                // Set the post_content to the custom meta field.
                $post_content = $post->post_content;
                update_post_meta($post_id, 'post_content', $post_content);
                $post->post_content = ''; // Empty the default post_content field.
            }
        }
    
        public function filter_the_content($content): mixed
        {
            // Get the current post.
            global $post;
    
            // Check if the post type is allowed.
            if ($post && in_array($post->post_type, self::$allowed_post_types)) {
                // Get the post_content from the custom meta field.
                $custom_post_content = get_post_meta($post->ID, 'post_content', true);
                if (!empty($custom_post_content)) {
                    $content = $custom_post_content;
                }
            }
    
            // Return the content.
            return $content;
        }
    
    }
    
    new WP_JSON_Search();
    

    Changes made:

    Used edit_form_after_title action to load custom post content into the editor. This action occurs before the editor is displayed.
    Removed the remove_action and wp_update_post calls from the save_post_content method. They were causing unnecessary recursion and might interfere with the expected behavior.
    
    Login or Signup to reply.
  2. Gutenburg’s editor uses WordPress’s internal REST API. You can tap into that and manipulate the response being sent back.

    Add the below filters:

    // filter our rest post content
    add_filter('rest_post_content', function (array $content, string $type, int $post_id) {
    
        $content['raw'] = 'Updated content!';
    
        return $content;
    }, 10, 3);
    
    // filter the rest response
    add_filter('rest_post_dispatch', function (WP_Rest_Response $object) {
        if (
            !property_exists($object, 'data')
            || !array_key_exists('content', $object->data)
            || !array_key_exists('type', $object->data)
            || !array_key_exists('id', $object->data)
        ) {
            return $object;
        }
    
        $object->data['content'] = apply_filters(
            'rest_post_content',
            $object->data['content'],
            $object->data['type'],
            $object->data['id']
        );
    
        return $object;
    }, 10, 1);
    

    rest_post_dispatch is an internal WordPress filter, you can check the response and if all the data is there, apply a custom rest_post_content filter to manipulate your data before it gets sent to the Gutenburg editor!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search