1

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 !

3 Answers 3

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).

1

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).

11
  • ok, by reading your post again & again, i think i start to understand it. what you want me to do, is to add a page in my wp pages. Add your rewrite rule to my functions.php and then add a page template in my theme and assign it to the page created before ? In this page, i will be able to get all the data i needed ! That seems to be logic
    – Gregory
    Apr 11, 2019 at 7:30
  • so : i created a page : "book" with id 2100 i set $page_id to 2100 i created a page model "book". i assign this model to the page "book". in page model, i added code for add filter. i save back my permalinks to generate them but if i go on mysite.com/go/test i go on a 404 page.
    – Gregory
    Apr 11, 2019 at 7:47
  • You need to also visit the permalinks page so that the new rewrite rules are refreshed. Sorry, I should have mentioned that (updated my answer) Apr 11, 2019 at 10:30
  • Hi Alexander, as sait just before, "i save back my permalinks to generate them", but it doesn't change anything. I'll look at the solution of dboris. But maybe i have an idea. I add .html to all my pages, cpt, & articles slug. So maybe i have a conflict with this ?
    – Gregory
    Apr 11, 2019 at 10:39
  • You can test that with the Rewrite Rules Inspector plugin. Just try both links mysite.com/go/test and mysite.com/go/test.html to see what happens. dboris's solution will work just fine, perhaps slightly more elegant than mine, however it may have the same problem if you are altering your URLs - give it a try and let us know. Apr 11, 2019 at 11:34
0

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!

Your Answer

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

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