We offer a multi-tenant solution on Wordpress where we give each of our partners a sub-url. Each sub-url has access to an Angular app:
example.com/our-first-partner/angular/
example.com/our-second-partner/angular/
Further, the Angular supports routes, so each app instance has its own set of pages:
example.com/our-first-partner/angular/dashboard
example.com/our-first-partner/angular/client/3
example.com/our-first-partner/angular/clients?type=A
Each "partner" angular url (example.com/<partner_slug>/angular) points to a Wordpress page post type. Assume that we have at least 200 "angular" pages, one for each partner.
What I'm trying to accomplish is for both Wordpress and Angular to be able to receive the un-tampered URL and direct to the correct page. For example, let's say I type in my browser:
example.com/our-second-partner/angular/client/3?showDetails=true
On the Wordpress side, I expect a redirect rule to take any URL matching "<partnerSlug>/angular/(.*)" and internally load the page post that has a permalink matching the URL (minus the captured suffix). The "angular" page would use a custom PHP template that would set <base href=""> to its permalink, that is, "<partnerSlug>/angular/".
On the Angular side, I expect the angular app to have access to the full URL as it was entered into the browser. The Angular app would see this URL as a route for /client/3 with queryParams { showDetails: true }. Currently, the Angular app's routing when run standalone from localhost:4200 works perfectly.
The issue I'm running into is that I don't know the best way to redirect a wildcard URL to a specific Wordpress post while preserving the URL. Solutions I've found recommend using .htaccess. When I try it:
.htaccess
RewriteEngine On
RewriteRule (.*/angular/).+$ $1 [R=301,L]
PHP Template assigned to the page in Wordpress
Permalink is <?php echo get_permalink(); ?>
URL being accessed is <?php echo "$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" ?>
Result when requesting https://example.com/our-second-partner/angular/client/3?showDetails=true
Permalink is https://example.com/our-second-partner/angular/
URL being accessed is https://example.com/our-second-partner/angular/
So, the redirect goes to the correct Wordpress post page, but I lose the Angular routing portion of the URL.
I feel like WP_Rewrite might redirect like the .htaccess rule does and without changing the URL suffix, but I haven't found many examples in the WP documentation on how to properly-use WP Rewrite in this way. Any recommendations?
Being new to Wordpress url rewriting, I hit a few "gotchas" while trying to create a custom rewrite rule. For one, Wordpress caches its rewrite rules in the database, so unless those are flushed, new rewrites added in the theme don't take effect.
I was able to get the desired url rewriting with the following code in a theme's functions.php or derivative file:
function angular_redirects() {
// Redirect to Angular app page
// Omitted $ because we want to match every suffix stemmed from the pagename.
add_rewrite_rule('(.?.+?\/angular)/', 'index.php?pagename=$matches[1]', 'top');
// Equivalent to Settings > Permalinks > click save.
// Your custom rule won't take effect until rules are flushed!
// Make sure to remove this after testing that url rewrite works.
flush_rewrite_rules();
}
add_action('init', 'angular_redirects');
This rewrite gets added to the 'top' of the redirect list, meaning this rewrite is encountered and matched before any built-in rewrites.
The result is, Wordpress's get_permalink()
function returns the wordpress page's URL to be used in
<base url="<?php get_permalink(); ?>"/>
Meanwhile, the URL in the browser as well as the value generated by <?php echo "$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" ?>
now matches the full URL that the user entered, so Angular can route to whichever sub-page was requested.
Hope this obscure use-case helps somebody out there!