Search code examples
phpwordpressamp-htmlgoogle-amp

if is amp change internal links to amp version (WordPress)


We use WordPress and would like to link amp to amp if the linked page has an amp version. We have amp structured like that: test.de/test/amp

Unfortunately this code in my functions.php isnt applying to links hard-coded inside of the post content. What do I have to change, so its working for every internal link:

add_filter( 'post_link', function( $url, $post ) {
    static $recursing = false;
    if ( $recursing ) {
        return $url;
    }
    $recursing = true;
    if ( ! function_exists( 'post_supports_amp' ) || ! post_supports_amp( $post ) ) {
        return $url;
    }
    if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) {
        $url = amp_get_permalink( $post->ID );
    }
    $recursing = false;
    return $url;
}, 10, 2 );

At the moment its also applying to the canonical link, which is really bad for seo. How to prevent this?


Solution

  • Add these functions to your theme's 'functions.php'.

    /* post link filter */
    add_filter( 'post_link', 'change_amp_url', 10, 2 );
    
    function change_amp_url( $url, $postobj ) {
        static $recursing = false;
        if ( $recursing ) {
            return $url;
        }
    
        $recursing = true;
        if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) {
            if ( function_exists( 'post_supports_amp' ) && post_supports_amp( $postobj ) ) {
                $url = amp_get_permalink( $postobj->ID );           
            }
        }
        $recursing = false;
        return $url;
    }
    
    /* content link filter */
    add_filter( 'the_content', 'change_amp_url_content' );
    
    function change_amp_url_content($content)
    {
        $dom = new DOMDocument();
        $dom->loadHTML($content);
    
        $tags = $dom->getElementsByTagName('a');
        foreach ($tags as $tag) {
            $link = $tag->getAttribute('href'); // original url
            $extralink = '';
            if(stristr($link,'#')) {
                $pagelinktemp = explode("#",$link);
                $pagelink = $pagelinktemp[0];
                $extralink = '#'.$pagelinktemp[1];
            } else {
                $pagelink = $link;
            }
            if($pagelink!="") {     
                $postid = url_to_postid($pagelink);
                $postobj = get_post($postid); // getting appropriate post object            
                if($postobj) {          
                    $newlink = change_amp_url( $pagelink, $postobj ); //new url
                }
                else {
                    $newlink = $link;
                }
            }
            else {
                $newlink = $link;
            }
            if($link != $newlink) // change if only links are different
            {
                $content = str_replace($link, $newlink.$extralink, $content);
            }
        }
        return $content;
    }
    
    /* override canonical link */
    add_filter( 'wpseo_canonical', 'amp_override_canonical' );
    
    function amp_override_canonical($url) {
        if ( substr($url,-4)=="/amp" ) {    
            $url = substr($url,0,-4);
        }
        return $url;
    }
    

    The first function will provide the AMP URL if exists.

    The second one will loop through each URL in the content and change to AMP URL if valid.

    The last one will rewrite the canonical URL that displayed via Yoast SEO plugin.