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.

4
  • why json make any difference? what is you code that you use to redirect? Commented Jul 12, 2016 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
    Commented Jul 12, 2016 at 6:16
  • @mmm How can I trigger the flush from another separated app (which generates the redirects json file)? Commented Jul 12, 2016 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). Commented Jul 12, 2016 at 11:37

1 Answer 1

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');
10
  • 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. Commented Jul 13, 2016 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 Commented Jul 13, 2016 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. Commented Jul 13, 2016 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 Commented Jul 13, 2016 at 9:43
  • Shouldn't wp-> be $wp->? Also, the $wp variable is undefined... I'm not a php expert... Commented Jul 13, 2016 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.