1

Facebook's Instant Articles rejects articles that contain hyperlinks to the current page (e.g. <a href="#_ftn1">[1]</a>). How can I filter the post content to remove these links before publishing to Facebook Instant Articles?

I'm aware of a similar question on StackOverflow: How to remove hyperlink of images in wordpress post?, but my RegEx skills aren't good enough to convert that to what I need.

PS - I'm using the semi-official Instant Articles for WP, which means I can filter instant_articles_content.

PPS - It would be nice to know both how to remove the link but leave the link text, and how to remove both the link and the link text.

3 Answers 3

1

Inspired by @Samuel Elh, but accounting for single or double quoted attributes and a href that might not be the first attribute of an anchor:

function wpse_227315_strip_hyperlinks( $content ) {
    preg_match_all( '!<a[^>]*? href=[\'"]#[^<]+</a>!i', $content, $matches );

    foreach ( $matches[0] as $link )
        $content = str_replace( $link, strip_tags( $link ), $content );

    return $content;
}

add_filter( 'the_content', 'wpse_227315_strip_hyperlinks' );

Note this will completely remove the link node/HTML from the post content. This will replace the HTML link with just the inner text.

2
  • This works well, but I'd appreciate an alternative which removes the link but retains the link text. I could use WordPress' wp_kses function, but that's probably overkill... Commented May 20, 2016 at 14:25
  • Just add strip_tags, see revision Commented May 20, 2016 at 14:43
1

You can use the Interconnectit DB Search/Replace Tool to search and replace all instances of strings in your database. This may not fully solve your problem, but you could start with searching for <a href="# and replacing it with <a href=".

I don't think that's exactly what you're trying to do, but hopefully it's a start in the right direction.

1

Try this function:

function wpse_227315_strip_hyperlinks( $content ) { 

    preg_match_all( '/<a href=\\"([^\\"]*)\\">(.*)<\\/a>/iU', $content, $matches );

    foreach( $matches[0] as $link ) {

        preg_match_all('/(?<=href=\").+(?=\")/', $link, $matches2);
        $href = isset( $matches2[0][0] ) ? $matches2[0][0] : false;

        if( 0 === strpos($href, '#') ) {

            $content = str_replace( $link, strip_tags($link), $content );
        }

    }

    return $content;

}

Hook it into your content filter e.g add_filter(tag_name, 'wpse_227315_strip_hyperlinks'). You should remove the filter (with remove_filter() e.g remove_filter(tag_name, 'wpse_227315_strip_hyperlinks')) after you post to Facebook.

5
  • Why are you regexing all links & iterating & regexing again for the hash? Just use the hash regex to begin with and iterate => replace Commented May 20, 2016 at 13:43
  • @TheDeadMedic lol I am really new to Regex I couldn't put together such expression but I'll try again and edit the answer. Thank you.
    – Ismail
    Commented May 20, 2016 at 13:53
  • 1
    No worries, I'm surprised you're new to it! I've also posted an answer to illustrate. Commented May 20, 2016 at 14:03
  • Awesome! Thank you for the answer, it helped me and it should help the question author as well :)
    – Ismail
    Commented May 20, 2016 at 14:12
  • The code isn't working reliably for me. Using simple test data, it's fine. But using it with one of my actual posts, and the first preg_match_all function returns an empty array. Here's a Fiddle: phpfiddle.org/main/code/8vjk-n0wx Commented May 20, 2016 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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