• Resolved Adrian Toll

    (@adriantoll)


    I’ve been trying to get a custom wysiwyg field to output as it normally would when using the_content(). To this end I’ve been passing the contents of the custom field through apply_filters using the_content filter. However, all this is doing is parsing shortcodes without triggering oembed magic for YouTube URLs.

    I’ve read quite a few blog posts that suggest it needs a post ID (i.e. it needs to be in the loop) leading to solutions like this – https://www.ads-software.com/support/topic/oembed-filter.

    However, my code *is* in the loop as you can see from the_content() being used at the top, which outputs as expected and outputs the correct embed code, so I’m scratching my head about why it’s not picking up the YouTube URLs and using oembed.

    The other post I’ve read is here – https://dancameron.org/code/wp_embed-oembed-filter-the_content-post_content/ – which talks about caching, but I’m not quite sure what that refers to (I’ve had a look at the WP_Embed class, and can’t figure it out from there).

    Does anyone have any ideas why this wouldn’t be picked up? My code is below, which uses slt_cf_field_value() from Developers Custom Fields (https://www.ads-software.com/plugins/developers-custom-fields/) to retrieve the custom field values:

    the_content();
    
    if (slt_cf_field_value('tab_title_1') != '') {
    
        echo '<div id="tab-container" class="tab-container">';
    
            echo '<ul class="etabs">';
    
            for ($i=1;$i<6;$i++) { if (slt_cf_field_value('tab_title_'.$i) !== '') {
    
                echo '<li class="tab"><a href="#tabs'. $i .'">'. slt_cf_field_value('tab_title_'.$i) .'</a></li>';
    
            }}
    
            echo '</ul>';
    
            for ($i=1;$i<6;$i++) { if (slt_cf_field_value('tab_title_'.$i) !== '') {
    
                $tabContent = apply_filters('the_content', slt_cf_field_value('tab_content_'.$i));
    
                echo '<div class="tab-content" id="tabs'. $i .'">'. $tabContent .'</div>';
    
            }}
    
        echo '</div>';
    
    }
Viewing 7 replies - 1 through 7 (of 7 total)
  • Moderator bcworkz

    (@bcworkz)

    FYI, using the_content() does not make a loop. The Loop has to begin with something very close to while ( have_posts() ) : the_post();. The Loop must constitute some looping structure and must call the_post() at the top of each loop. Maybe this code is elsewhere and you are in the Loop, but your presenting evidence of such is weak ??

    I’m not sure that’s really the issue. If anything, I suspect things are not happening in the right order. It depends on what you mean by the correct embed codes are output. If you mean the [embed] shortcode, then not all shortcodes were parsed and you need to run the content through do_shortcode(). If you mean the actual embed HTML, like youtube references in <iframe>, that’s all you get. What’s not working?

    About the caching, if you have a real post ID, there’s nothing to worry about there. Your reference was concerned their content with a fake ID could overwrite real post content in the cache if the fake ID matched a real post ID.

    Thread Starter Adrian Toll

    (@adriantoll)

    Hi bcworkz

    Thanks for the reply. My page does have a loop – it’s just a bit further up the page, and I didn’t want to post the whole code, but I should probably have added that for clarity ??

    The first line in the template is…

    <?php get_header(); while ( have_posts() ): the_post(); ?>

    … and as the_content() (and everything else in the template) is working as expected I presume the relevant post ID is available at the point I’m calling apply_filters.

    When I mentioned shortcodes, I mean that things like a Gravity Forms [form] shortcode is being parsed correctly, and the form HTML is being written out in place of that shortcode. However, a single YouTube URL like …

    https://www.youtube.com/watch?v=OKY6BGcx37k

    … on its own line isn’t being turned into the iframe embed code, so the oembed isn’t being triggered, as I would expect from

    apply_filters('the_content',$tabContent)

    Any other thoughts?

    Thanks

    Adrian

    Thread Starter Adrian Toll

    (@adriantoll)

    There’s an answer on WordPress Answers here which says:

    So I’ve never really found out why oembed urls added via apply_filters(‘the_content’, $output), are not processed while embed shortcodes are. Im still hopeful someone might shed some light on that.

    From that it sounds like it’s a replicable issue, but I’d expect to see more blog posts about it if it was a common issue. Happy to post the full template code if you think it’d help.

    Adrian

    Thread Starter Adrian Toll

    (@adriantoll)

    Thought I may as well post the whole lot in case it’s useful: https://pastebin.com/finF7jWM

    Moderator bcworkz

    (@bcworkz)

    Thanks for the extra information. I obviously didn’t need all of it, but it paints a certain picture that I find helpful.

    Forget about my previous comment about wrong order. I had the wrong picture in my head. Applying ‘the_content’ filter should result in the same process as calling the_content(). Do ensure the strings returned by your functions that feed ‘the_content’ are properly constructed including newlines before the video URLs. Oembed uses regexp to locate video URLs, part of which starts with "^https?://...". If the ‘http’ does not start on a new line, the match will fail.

    I suspect you’ve done that. Like the loop thing, I’m just making sure ?? I’ve had issues with oembed working on video URLs even in normal content unprocessed by custom code – straight out of the box templates. Application is erratic at best. I’ve dozens of posts where I had to explicitly embed videos because oembed didn’t “take”. It seems to be specific videos that have issues, one’s that do not work always fail, and ones that work always work.

    I suspect the regexp matching isn’t happening sometimes, though I can’t see why not on visual inspection. I don’t fully understand how oembed comes to be part of ‘the_content’ filter. The callback in the global $wp_filter has the appearance of dynamic allocation (callback name includes large random number), so the filter could be added and removed due to contexts that I couldn’t even guess at. Surely you would expect it to be in place for your context though.

    None of this solves your problem, it just supports that something odd is going on. You seem to have done all that is expected for this to work. All I can suggest is to explicitly match media URLs yourself and pass the matches through wp_embed_handler_video() and it’s siblings yourself. In addition to the expected regexp, you’ll need to exclude any embed code that may have leaked through from the real oembed.

    Sorry I can’t help more, without understanding why it’s failing, it’s difficult to propose a real solution.

    Thread Starter Adrian Toll

    (@adriantoll)

    Thanks bcworkz

    “I suspect you’ve done that.” Never assume anything!

    The plugin wysiwyg custom fields were storing exactly what TinyMCE was giving them, which includes automatically added <p> and </p> tags. So the content lines in the database start <p>https://www.youtube.com... which doesn’t match the regexp.

    To get it working I’m now stripping the <p> and </p> tags from the returned content with str_replace(array('<p>','</p>'), $tabContent) and apply_filters('the_content',$tabContent) is adding them back in. I’m also going to suggest an update to the plugin so that it stores a value with the <p> and </p> tags stripped, and applies the_content to the output.

    Thanks again!

    Nice Adrian – thanks for identifying the issue – that was stumping me. Appears to be a problem with regular the_content() too if you get something like <p style="text-align: justify;">https://www.youtube.com/watch?v=pWxnGf7isqc</p> in your html saved in the database.

    I found deleting and redoing the copy and paste on a single line in the editor now works.

    Also, if you want to use the code above, there’s a small typo. Use:

    str_replace(array('<p>','</p>'), '', $tabContent)

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘apply_filters the_content not triggering oembed even in the loop’ is closed to new replies.