We have a client who has had a brand new site developed by another agency, it is multilingual via some custom fields and some basic logic to display the relevant language via a simple language selector. No plugins involved.
The issue is that the client wants to ensure that their site has SEO that targets the various countries/languages they serve, but the current implementation is not SEO friendly whatsoever due to it being almost locale-adaptive (ie no specific URLs for each language).
Due to the costs, the client is not willing to rebuild the entire site with a plugin such as polylang/WPML etc, and we need to figure out a solution that can almost be dropped in and integrate with their existing fields/translations.
Our agency has proposed the following - we simply create a query variable "lang" that is then prepended to URLs if the selected language is not English, so if French is chosen, site.com/page becomes site.com/fr/page, site.com/blog-category/post becomes site.com/fr/blog-category/post etc. We can detect the query variable and serve the appropriate language.
I have got this partially working with some rewrite rules which I have little experience working with, where lang is a two character query variable:
// Register lang query var
function wf_register_query_vars( $vars ) {
$vars[] = 'lang';
return $vars;
}
add_filter( 'query_vars', 'wf_register_query_vars' );
// Add rewrite rules
function wf_rewrite_tag_rule() {
add_rewrite_tag( '%lang%', '([a-z]{2})' );
add_rewrite_rule( '^([a-z]{2})/?$', 'index.php?lang=$matches[1]', 'top' );
add_rewrite_rule( '^([a-z]{2})/?$', 'index.php?lang=$matches[1]&page_id=12', 'top' ); // Home page
add_rewrite_rule( '^([a-z]{2})/example/?$', 'index.php?lang=$matches[1]&post_type=example', 'top' ); // Example CPT Archive
add_rewrite_rule( '^([a-z]{2})/example/(.?.+?)(/[0-9]+)?/?$', 'index.php?lang=$matches[1]&example=$matches[2]', 'top' ); // Example CPT
add_rewrite_rule( '^([a-z]{2})/(.?.+?)(/[0-9]+)?/?$', 'index.php?lang=$matches[1]&name=$matches[2]&page=$matches[3]', 'bottom' ); // Posts
add_rewrite_rule( '^([a-z]{2})/(.?.+?)(/[0-9]+)?/?$', 'index.php?lang=$matches[1]&pagename=$matches[2]&page=$matches[3]', 'top' ); // Pages
}
add_action('init', 'wf_rewrite_tag_rule', 10, 0);
With the above, the home page works (it's a static page set as the home page), as do single "post" post-types, and single "example" post types. Pages do not work however (404), and have not yet begun looking into archives, categories, tags, taxonomies etc.
If I swap the order of the bottom two (posts and pages), posts will stop working (404), but pages will start working.
So the question is, is there a way to add a rewrite rule that just covers everything - pages, posts, archives, custom post types, custom taxonomies, pagination etc?
I can handle all other logic (serving 404's for non-existent translations, generating hreflangs, changing WP's locale, html lang attribute etc), it is just the rewrite rules that have left me absolutely stumped!