Adding hreflang tags automatically in WordPress subdirectory multisite

We have a WordPress MU subdirectory network setup:

We want to add hreflang tags for each webpage and exclude the locations custom post type.

From this question, I've adjusted the code in the child theme's functions.php to:

function add_hreflang_attribute() {
   $site_url = network_site_url(); // base URL
   $alt_langs = array( 'au', 'uk' ); // two-letter language code
   $page_path = substr(get_permalink(), strlen(home_url('/'))); // path of page after base URL
   
   if (!( is_singular( 'locations' ) ) ) {
           
       // loop through the alternative languages, and get the appropriate hreflang tag for each that exists
       foreach ($alt_langs as $lang) {
           $updated_url_lang_path = $site_url . $lang . '/' . $page_path;
           $url_headers = @get_headers($updated_url_lang_path);
           if($url_headers  strpos( $url_headers[0], '200')) {
               if ($lang == 'uk') {
                   echo 'link rel=alternate href=' . $updated_url_lang_path . ' hreflang=en-gb /'. PHP_EOL;
               } elseif ($lang == '') {
                 
               }
               else {
                   echo 'link rel=alternate href=' . $updated_url_lang_path . ' hreflang=en-' . $lang . ' /'. PHP_EOL;
               }
           }
       }
       
       // set primary as x-default
       echo 'link rel=alternate href=' . $site_url . $page_path . ' hreflang=x-default /';
        
   }

}

This code works on the main website's home page example page: www.example.com/features/;

link rel=alternate href=https://www.example.com/au/features/ hreflang=en-au /
link rel=alternate href=https://www.example.com/uk/features/ hreflang=en-gb /
link rel=alternate href=https://www.example.com/features/ hreflang=x-default /

and it works for the:

  • AU site's home page,
  • the AU site's features page: https://www.example.com/au/features/,

but on www.example.com/uk/ it only produces:

link rel=alternate href=https://www.example.com/au/ hreflang=en-au /
link rel=alternate href=https://www.example.com/ hreflang=x-default /

It is missing:

link rel=alternate href=https://www.example.com/uk/ hreflang=en-gb /

The features page is a simple WordPress page.

Help appreciated.

Topic php multisite Wordpress

Category Web


Alternatively we can set the hreflang as a site meta for each site:

update_site_meta( 1, 'hreflang', 'x-default' );
update_site_meta( 3, 'hreflang', 'en-au' );
update_site_meta( 5, 'hreflang', 'en-gb' );

and then for the hreflang attribute use;

get_site_meta( $site->blog_id, 'hreflang' )

and for the href attribute:

get_home_url( $site->blog_id, $page_path )

If we want to skip the site meta and use:

$hreflangs = array(
    1 => 'x-default',
    3 => 'en-au',
    5 => 'en-gb',
);  

then the sites loop becomes:

$page_path = substr( get_permalink(), strlen( home_url('/') )); 

$sites = get_sites();
foreach ( $sites as $site ) {
    if ( isset( $hreflangs[ $site->blog_id ] ) ) {
        printf ( 
            '<link rel="alternate" href="%s" hreflang="%s" />'. PHP_EOL,
            esc_url( get_home_url( $site->blog_id, $page_path ) ),
            esc_attr( $hreflangs[ $site->blog_id ] )
        );
    }
}

One might further check if the page-path/slug exists on each site with e.g. get_page_by_path() or get_posts() via switch_to_blog().

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.