0

Having a JSON file, how can we set up WordPress to redirect the urls (if it's found in the JSON file)?

For example:

{
  "foo": "bar",
  "foo-1": "baz"
}

Then /foo will redirect to /bar and /foo-1 to /baz.

What's the best way to do this? Currently I do it with rewrite_rule in functions.php, but each time the redirects change, I have to save the Permalinks Settings.

The redirects in functions.php are handled like this:

function handle_book_redirects() {
  add_rewrite_rule(
    '^(foo|foo-1)$',
    'index.php?myVar=redirect:$matches[1]',
    'top'
  );
}
add_action( 'init', 'handle_book_redirects' );

Then if myVar is appended and it's a redirect, a custom php will handle that request.

  • why json make any difference? what is you code that you use to redirect? – Mark Kaplun Jul 12 '16 at 5:40
  • WordPress use a cache to save ressources when doing the URL Rewriting. then you need to flush the permalinks every time the redirections change – mmm Jul 12 '16 at 6:16
  • @mmm How can I trigger the flush from another separated app (which generates the redirects json file)? – Ionică Bizău Jul 12 '16 at 11:36
  • @MarkKaplun Because I want to make it dynamic. Currently I have to add the redirect urls in two places: in my php file and in functions.php (added in the question). – Ionică Bizău Jul 12 '16 at 11:37
1

The way I do it. Note there may be a more straightforward way.

Step 1

Add a custom query_varlike this to record the redirect from/to variables

function my_custom_query_vars($vars){
     //this allows you to store custom variables with rediect_from and rediect_to in the url
     $vars[] = 'redirect_from';
     $vars[] = 'redirect_to';
    return $vars;
}
add_filter( 'query_vars', 'my_custom_query_vars' );

Step 2

Add foreach loop that does something like this. This will add the rewrite rules to change http://example.com/foo to http://example.com/?redirect_from=foo&redirect_to=bar

function my_custom_rewrite_rules($wp_rewrite){
    $new_rules = array();
    $json = '';//get your json data and store it as this string
    $json_array = json_decode($json, true);
    foreach($json_array as $key => $value){
        $new_rules['^'.$key.'$'] = 'index.php/?redirect_from='.$key.'&redirect_to='.$value;
    }
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'my_custom_rewrite_rules');

Step 3

Hook into the parse_request filter to parse your request and redirect as necessary.

 function my_custom_parse_request($wp){
//we make sure the keys are present and not empty before we redirect
if ((array_key_exists('redirect_from', $wp->query_vars) 
    && !empty($wp->query_vars['redirect_from']))
    && (array_key_exists('redirect_to', $wp->query_vars)
    && !empty($wp->query_vars['redirect_to']))){
        wp_redirect(home_url('/'.$wp->query_vars['redirect_to']));
        exit;        
}
add_action('parse_request', 'my_custom_parse_request');
  • What happens when the JSON file is changed? How can I do it that will trigger an event and will reload the json string? I don't want to read the json file and parse it on every request, but load it in memory and reload it when it's changed. – Ionică Bizău Jul 13 '16 at 9:22
  • I'd suggest you save the json string as an option in the wp_options table using the optionsAPI. You would then load the json string in the function using get_optiom(). All you'll have to do is update the settings whenever the json file changes. If the json file is not external, you could add a custom hook to re-save the function whenever it changes – Stephen Afam-Osemene Jul 13 '16 at 9:29
  • Is my_custom_rewrite_rules called when flushing the permalinks? I think I will use the WP_Rewrite::wp_rewrite_rules() method to reload the json. – Ionică Bizău Jul 13 '16 at 9:34
  • The code I gave should be put either in the functions.php of your child theme or in a plugin. I have been using the method in a couple sites and it works flawlessly – Stephen Afam-Osemene Jul 13 '16 at 9:43
  • Shouldn't wp-> be $wp->? Also, the $wp variable is undefined... I'm not a php expert... – Ionică Bizău Jul 13 '16 at 13:44

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.