1

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.

1 Answer 1

1
+150

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().

7
  • I've added an EDIT2 to my question as an attempt to wrap your answer in functions.
    – Steve
    May 12 at 5:59
  • we only need to run the update on site meta once and we should remember escaping the outputs with esc_url and esc_attr (Im just writing from a phone. :-)
    – birgire
    May 12 at 6:12
  • if you want to skip site meta you can define an array relating blog id to hreflang.
    – birgire
    May 12 at 6:41
  • I can only award the bounty 24 hours after I created it. I will award it to you tomorrow.
    – Steve
    May 12 at 7:04
  • 1
    Glad to hear it helped @Steve
    – birgire
    May 12 at 7:05

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.