0

EDIT: Thanks to @mozboz I've got a solution to this. The post has been updated to reflect was I was originally trying to do, and what I am doing now.

I am developing a plugin that creates a custom post type, adds some meta fields to it, and then displays that meta information in a specifically formatted way. The meta fields are for a YouTube link and an mp3 link, and the plugin displays tabbed content for those (first tab is an embedded YouTube player, second tab is an embedded audio player, third tab is a download link for the mp3). It was working great with the Twenty Twenty theme, but not with any of the other themes I tried. Here was my original code:

function my_custom_post_type_the_post($post_object)
{
    // The post object is passed to this hook by reference so there is no need to return a value.
    if(
        $post_object->post_type == 'my_custom_post_type' &&
        ( is_post_type_archive('my_custom_post_type') || is_singular('my_custom_post_type') ) &&
        ! is_admin()
    ) {

        $video = get_post_meta($post_object->ID, 'my_custom_post_type_video_url', true);
        $mp3 = get_post_meta($post_object->ID, 'my_custom_post_type_mp3_url', true);
        $textfield = get_post_meta($post_object->ID, 'my_custom_post_type_textfield', true);

        // Convert meta data to HTML-formatted media content
        $media_content = $this->create_media_content($video, $mp3, $bible);

        // Prepend $media_content to $post_content
        $post_object->post_content = $media_content . $post_object->post_content;
    }
}
add_action( 'the_post', 'my_custom_post_type_the_post' );

I used print_r($post_content) at the end of this function to verify that the conditions were working as expected and that the $post_object contained what I expect it to. For some reason, the Twenty Twenty theme would display the $media_content, but with other themes, it was still missing.

I decided that perhaps I was mis-using the "the_post" hook. I tried to modify my plugin to use the "the_content" hook instead, and that got it working:

    public function my_custom_post_type_the_content($content_object)
    {
        global $post;
        if(
            $post->post_type == 'my_custom_post_type' &&
            ( is_post_type_archive('my_custom_post_type') || is_singular('my_custom_post_type') ) && ! is_admin()
        ) {

            $video = get_post_meta($post->ID, 'my_custom_post_type_video_url', true);
            $mp3 = get_post_meta($post->ID, 'my_custom_post_type_mp3_url', true);
            $textfield = get_post_meta($post->ID, 'my_custom_post_type_text_field', true);

            $media_content = $this->create_media_content($video, $mp3, $textfield);

            $content_object = $media_content . $content_object;
        }
        return $content_object
    }
add_filter( 'the_content', 'my_custom_post_type_the_content');

Note that the "$content_object" passed to the function is NOT passed by reference, so it has to be returned.

One thing that was not solved was that with this approach, the archive listing of the posts strips off all of the HTML, so that my media object is gone from archive listings. In my case I decided to not solve this problem, because I decided that loading all of these media objects for multiple posts on an archive page would negatively affect page load times too much.

Thanks again for the help!

0
0

As your code looks quite generic, the obvious answer and thing to debug is that either the if condition is not true when you're expecting it to be, or $media_content isn't getting generated as you expect.

Are you 100% sure that on all the other sites the post_type is 'my_custom_post_type' when you expect it to be?

You can debug things like this by temporarily inserting code like:

function my_custom_post_type_the_post($post_object)
{
    $post_object->post_content = "debug: " . ( $post_object->post_type == 'my_custom_post_type' ? "yes" : "no" ) . $post_object->post_content;

    $media_content_test = generate_media_content( ... ); // make this stuff self contained so it's easy to test

    $post_object->post_content = "debug: " . $media_content_test . $post_object->post_content;

    // original code below

    // The post object is passed to this hook by reference so there is no need to return a value.
    if(

This way you know things like:

  • The hook definitely ran?
  • The conditions you were expecting are actually true or not
  • The output you were expecting is getting generated properly
7
  • Thank you for your comment. I should have mentioned this above (I will edit my original post if I'm able). I debugged using print_r and verified that $post_object contains what I expect it to contain at the end of that function. And given that the Twenty Twenty theme displays the information correct, this further points to the fact that yes, the media content is getting generated correctly within the function.
    – EliT
    Aug 6 '20 at 14:08
  • So what happens if you add some test string to $post_object->post_content inside that hook in an unconditional way as per my first line of code there. It should show up everywhere?
    – mozboz
    Aug 6 '20 at 14:36
  • Well in the Twenty Twenty theme, yes--it shows up everywhere without those conditions. But in the other themes mentioned, even outside of the conditions, the updated post object is NOT the post object that ends up getting printed to the page. And I've verified that the post ID is the same between this post_object and the one used in the post. It's just missing my edits.
    – EliT
    Aug 6 '20 at 15:06
  • Please see my edit2 above, the_content gets me closer than the_post, with an issue with the archive listing. Thanks again for your suggestions.
    – EliT
    Aug 6 '20 at 15:23
  • Yes, I was just going to suggest the the_content filter.. developer.wordpress.org/reference/hooks/the_content
    – mozboz
    Aug 6 '20 at 15:24
0

With the help of @mozboz I have solved my issue. The original post is updated with the answer. However, for whatever reason people are asking that I also post the answer here. So here it is:

public function my_custom_post_type_the_content($content_object)
{
    global $post;
    if(
        $post->post_type == 'my_custom_post_type' &&
        ( is_post_type_archive('my_custom_post_type') || is_singular('my_custom_post_type') ) && ! is_admin()
    ) {

        $video = get_post_meta($post->ID, 'my_custom_post_type_video_url', true);
        $mp3 = get_post_meta($post->ID, 'my_custom_post_type_mp3_url', true);
        $textfield = get_post_meta($post->ID, 'my_custom_post_type_text_field', true);

        $media_content = $this->create_media_content($video, $mp3, $textfield);

        $content_object = $media_content . $content_object;
    }
    return $content_object
}

add_filter( 'the_content', 'my_custom_post_type_the_content');

3
  • if you have time code quick code sniippets of what worked might be useful for anyone else who runs across your question
    – mozboz
    Aug 6 '20 at 16:55
  • My initial comment was updated and the code that worked is included there.
    – EliT
    Aug 6 '20 at 18:35
  • What comment? Please edit your answer and include a solution.
    – fuxia
    Aug 7 '20 at 5:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.