How to create a php url redirection for nicer links

The question:

I’m looking for a way to make a URL redirection for affiliate links on my website.

Something like : site.com/go/keyword

I know there is many plugins for doiing this, but i don’t like plugin, and i love to learn new things.

I imagine 2 custom fields for each posts with :

  • keyword
  • url to redirect to

But i have no idea how to process this redirect file.

Any help or advice is welcome.

thanks !

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

This solution works without creating new pages or changing anything.

We will:
1. Set up a new rewrite rule and add a new query variable
2. Catch that case in a ‘pre_get_posts’ hook, fetch the post we need and do the redirection

Note that if you have multiple posts with the same keyword_meta value, this might not work as planned. I have not implemented the checks for this, the first matching post will be selected.

Code should go into the functions.php or similar:

add_action( 'init',
    function () {
        add_rewrite_rule(
            '^(go)/([^/]+)$',
            'index.php?redirection=$matches[2]',
            'top'
        );

        add_filter( 'query_vars',
            function ( $vars ) {
                $vars[] = "redirection";

                return $vars;
            } 
        );
    }
);

add_action( 'pre_get_posts',
    function ( $query ) {
        if ( $redirection = get_query_var( 'redirection' ) ) {

            // Change this:
            $keyword_meta         = 'keyword_meta_field_name';
            $redirection_url_meta = 'redirection_url_meta_field_name';
            $post_type            = 'post';

            $args = [
                'meta_key'       => $keyword_meta,
                'meta_value'     => $redirection,
                'posts_per_page' => 1,
                'post_type'      => $post_type,
            ];

            $post_query = new WP_Query( $args );
            $posts      = $post_query->get_posts();

            // If no posts found, redirect back to referer
            if ( count( $posts ) < 1 ) {
                wp_safe_redirect( wp_get_referer() );
            }

            $redirection_url = get_post_meta( $posts[0]->ID, $redirection_url_meta, true );

            // If no redirection URL found, redirect back to referer
            if ( ! $redirection_url ) {
                wp_safe_redirect( wp_get_referer() );
            }

            // Finally, do the redirection
            if ( headers_sent() ) {
                echo( "<script>location.href='$redirection_url'</script>" );
            } else {
                header( "Location: $redirection_url" );
            }
            exit;
        }

        return $query;
    }
);

Please do not forget to refresh your Permalinks in the dashboard (open Settings > Permalinks and click on Save Changes).

Method 2

You will need to use add_rewrite_rule to register a new URL, and then also create a new page & template to handle where to link off to.

For example:

add_action('init', function() {
    $page_id = 2;
    $page_data = get_post($page_id);

    if(!is_object($page_data)) {
        return;
    }

    add_rewrite_rule(
        $page_data->post_name . '/go/([^/]+)/?$',
        'index.php?pagename=' . $page_data->post_name . '&affiliate=$matches[1]',
        'top'
    );
});

Replace the $page_id with the correct ID of a new page which will handle the links.

You also need to use add_filter to setup the variable:

add_filter('query_vars', function($vars) {
    $vars[] = "affiliate";
    return $vars;
});

Your new page & template will then access this value using get_query_var and redirect accordingly:

$affiliate = get_query_var('affiliate', false);
// Do whatever lookup you need here to get the actual link to redirect to
wp_redirect($url);
exit;

UPDATE:
You will also need to visit the permalinks admin page so that the new rewrite rules are applied. You can also test the rules are working using the Rewrite Rules Inspector plugin, (although it’s a little old now).

Method 3

Combining the answear of @alexander & of @dboris

here is the final solution :

  1. Create a page to handle redirections
  2. add to functions.php
    add_action('init', function() {
        $page_id = 2100;
        $page_data = get_post($page_id);

        if(!is_object($page_data)) {
            return;
        }

        add_rewrite_tag('%affiliate%','([^/]+)');
        add_rewrite_rule(
            'go/([^/]+)/?$',
            'index.php?pagename=' . $page_data->post_name . '&affiliate=$matches[1]',
            'top'
        );
    });

Replace %affiliate% and affiliate by the tag you wish to use.
Replace page_id with the ID of your page defined on step 1.

Add a page model that you assign to page defined on sted 1 and add this code to it :

$args = array(
    'posts_per_page'   => -1,
    'meta_key'         => 'booking_slug',
    'meta_value'       => $aff,
    'post_type'        => 'hotel'
);
$query = new WP_Query( $cc_args );
if($query->have_posts()) : while ($query->have_posts() ) : $query->the_post();
    the_title();
    echo get_field('booking_affiliate');
endwhile;
endif;

Need to secure a bit this stuff, and make the redirection using the way you want!


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment