CHECKING STATUS
I AM LISTENING TO
|

Solutions: WordPress + MultiSite + WPML + Simplied folder structure

4. May 2024
.SHARE

Table of Contents

THE QUESTION

A while back a potential customer asked me, if it is possible to restructure a WordPress Multisite setup and WPML with a more simplified and custom url structure?


THE ROUGH IDEA

1 . BASE.website web.site (with possibly different languages)

web.site/de/
web.site/en/

2. SUB.website web.site/nl-nl/ 

Languages would normally be added like this:

web.site/nl-nl/de/
web.site/nl-nl/en/

The customer wanted it to be restructured / simplified like this:

web.site/de-nl/
web.site/en-nl/

This basically mimics the structure of a single WPML website with custom languages, but with all the benefits of a multisite.

THE SOLUTION

This is nothing that WPML or WordPress Multisite provides out of the box. 
I built a prototype setup to make it work. 

Not something that I would propose for anyone, as it requires a lot of tweaks for anything that handles dynamic links (plugins, hooks, core systems, page.builder …) 

Its doable :)

BASIC URL HANDLING

One thing that needs to be tweaked globally, is the mapping of the new url structure.

So web.site/nl-nl/en/ needs to become web.site/en-nl/

This needs to be handled on the server side, by proxying the original to the new structure.
This can be easily done using Apache or NGINX.

With that web.site/nl-nl/en/ will be proxied to web.site/en-nl/, but any core navigation will not work yet.

This is the fastest solution that I came up with, within the hour I gave myself ;) 

There surely are other options, like the core rewrites / restructuring of the core shorturl handling. But these approaches might break things in far more areas. 

Using the proxy approach, keeps the core as it is. The solution needs to be as simple as possible, allowing to maintain it in the future :)

HOOKS TO THE RESCUE

Just for the basic setup a couple of hooks are required to make this work, more might be needed depending on the plugins in use.

Here a couple of examples ….
WordPress site_url

add_filter( 'site_url', 'custom_site_url' );

function custom_site_url( $url )
{
    if( is_admin() ) // you probably don't want this in admin side
        return $url;

    return  str_replace( "/nl-nl/en/","/en-nl/", $url);
}

WordPress Nav Links

add_filter( 'post_link',  'changePermalinks', 10, 3);
add_filter( 'page_link', 'changePermalinks', 10, 3);
add_filter( 'post_type_link',  'changePermalinks', 10, 3);
add_filter( 'category_link',  'changePermalinks', 11, 3);
add_filter( 'tag_link',  'changePermalinks', 10, 3);
add_filter( 'author_link',  'changePermalinks', 11, 3);
add_filter( 'day_link',  'changePermalinks', 11, 3);
add_filter( 'month_link','changePermalinks', 11, 3);
add_filter( 'year_link',  'changePermalinks', 11, 3);

function changePermalinks( $url, $post, $leavename=false ) {
    $url = str_replace("/nl-nl/en/","/en-nl/", $url);
    return $url;
}

WPML

add_filter( 'icl_ls_languages', 'wpml_url_fix');

function wpml_url_fix( $languages ) {
 
  global $wpml_url_converter;
 
  $abs_home = $wpml_url_converter->get_abs_home();
  foreach( $languages as $lang => $element ){


    $languages[$lang]['url'] = str_replace( "/nl-nl/en/","/en-nl/", $languages[$lang]['url'] );
    
  }
  return $languages;
}



Rankmath

add_filter( 'rank_math/frontend/canonical', function( $canonical ) {
	return str_replace( "/nl-nl/en/","/en-nl/", $canonical);
});

This will not cover every angle, but will give you a starting point! I love my puzzles and there always is a viable solution :)

Need something similar … get in touch!

Happy coding …

Let’s Talk!

Looking for a reliable partner to bring your project to the next level? Whether it’s development, design, security, or ongoing support—I’d love to chat and see how I can help.

Get in touch,
and let’s create something amazing together!

RELATED POSTS

This is my own task / project / workflow solution fully integrated into WordPress, which I began developing in 2025. After the recent cloud outages—and following a significant investment in the Asana ecosystem—I decided to build a robust, self-hosted WordPress solution featuring an almost complete Asana Sync API integration. I don’t have plans to make […]

UPDATED: Asana is a great project management tool, but for those who prioritize data privacy, control, and customization, self-hosted alternatives are a better option. In 2026, there are several robust and feature-rich self-hosted project management tools that can effectively replace Asana while giving you full control over your data. Here’s a look at some of […]

Inspired byGutenberg Blocks in Gravity Forms: Seamless Widget IntegrationGutenberg Blocks in Elementor: Seamless Widget IntegrationMeet the Isolated Block Editor – Gutenberg, Untethered – Integrated into Elementor The idea took over Once you start working on an idea its hard not to see all the other possibilities ;) The plugin automatically detects and replaces TinyMCE textareas […]

Alexander

I am a full-stack developer. My expertise include:

  • Server, Network and Hosting Environments
  • Data Modeling / Import / Export
  • Business Logic
  • API Layer / Action layer / MVC
  • User Interfaces
  • User Experience
  • Understand what the customer and the business needs


I have a deep passion for programming, design, and server architecture—each of these fuels my creativity, and I wouldn’t feel complete without them.

With a broad range of interests, I’m always exploring new technologies and expanding my knowledge wherever needed. The tech world evolves rapidly, and I love staying ahead by embracing the latest innovations.

Beyond technology, I value peace and surround myself with like-minded individuals.

I firmly believe in the principle: Help others, and help will find its way back to you when you need it.