I've amended the URLs for my custom post type from:

url.com/jobs/job-name to url.com/jobs/job-location/job-name

Problem is, because this isn't a standard rewrite wordpress doesn't do the 301 redirecting for you.

Does anyone know how I could do a 301 redirect for all custom posts to the new URL bearing in mind that job-location would be different depending on the post?



Since job-location is a variable part - which content we do not know beforehand - it is not possible to easily solve this in a .htaccess redirect. You could however generate a list of posts with their old and new URI and place those redirects in the .htaccess - I would prefer it that way because then PHP is not needed at all.

If that is not an option, the following should work

add_action('wp_loaded', 'WPSE_redirect_jobs_new_url');
function WPSE_redirect_jobs_new_url(){
    // current request
    $uri = $_SERVER['REQUEST_URI'];

    $parts = explode('/', $uri);
    if (substr($uri, 0, 6) !== '/jobs/' || count($parts) > 3) {
        // either URI does not start with jobs
        // or URI is already longer than /jobs/foo
        // so end early

    $slug = array_pop($parts);
    $page = get_page_by_path($slug, OBJECT, 'MY_CPT');

    if (!$page instanceof WP_Post) {

    // get new link
    $link = get_permalink($page->ID);

    wp_redirect($link, 301);

Because WordPress has its own way of guessing redirects, it is important to use an early action. In my test, wp_loaded sufficed for this. Sadly, the global $wp is not fully populated by that time, so here I am checking the requested URI via $_SERVER['REQUEST_URI'] instead of $wp->request.

This of course relies on permalinks being set up for jobs as you wish them, otherwise get_permalink() will not yield the results you're looking for.

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.