This tutorial is was originally published by Alex Tester at smoothwebsites.net, and is shared here at his request.
I work on a number of different affiliate websites, and as anyone who does the same will tell you, getting your affiliate links right is crucial.
For the uninitiated: affiliate websites link out to certain other sites in the hope of gaining them a customer, which then leads to a commission for us. Usually this link is included in a top 10 list, or a review, but it can appear anywhere.
The other website provides you a specially generated ‘tracker link’ containing your particular affiliate code. When someone then clicks on it and arrives on the other site, they know that the traffic came from you and can compensate you appropriately.
Unfortunately, these links are often quite.. ugly. A typical example:
examplesite.com?refquery=123445&affid4gnnsndhd
This looks pretty spammy to the average user.
Of course you can wrap it in a text link or a button, but your user will still see this URL if they hover over the link, and that might be enough to put them off.
In affiliation, every link counts – which is why most affiliate websites disguise their tracker links to look something like this:
mysite.com/go/example-site
Much better!
Redirections plugins are commonly used for this – they are ideal if you need a nice simple GUI where you can put in the desired ‘pretty’ link and its final destination. 301 Redirection, Pretty Links, Rank Math and plenty more options exist.
The problem is that once you surpass 50 links, it starts to get unwieldy. Scalability becomes a problem. I’m all about that, so I set about finding a way of storing this link inside the data of the page it related to. And here it is.
All you need to follow this tutorial is Advanced Custom Fields, plus the excellent and free Code Snippets plugin. This allows you to add snippets of code which translate into added functionality. Adding the code to functions.php is also an option but I prefer Code Snippets because:
On with the tutorial..
// Register Affiliate Links Custom Post Type
function affiliate_links_post_type() {
$labels = array(
'name' => _x( 'Affiliate Links', 'Post Type General Name', 'text_domain' ),
'singular_name' => _x( 'Affiliate Link', 'Post Type Singular Name', 'text_domain' ),
'menu_name' => __( 'Affiliate Links', 'text_domain' ),
'name_admin_bar' => __( 'Affiliate Link', 'text_domain' ),
'archives' => __( 'Item Archives', 'text_domain' ),
'attributes' => __( 'Item Attributes', 'text_domain' ),
'parent_item_colon' => __( 'Parent Affiliate Link:', 'text_domain' ),
'all_items' => __( 'All Affiliate Links', 'text_domain' ),
'add_new_item' => __( 'Add New Affiliate Link', 'text_domain' ),
'add_new' => __( 'Add Affiliate Link', 'text_domain' ),
'new_item' => __( 'New Item', 'text_domain' ),
'edit_item' => __( 'Edit Affiliate Link', 'text_domain' ),
'update_item' => __( 'Update Affiliate Link', 'text_domain' ),
'view_item' => __( 'View Affiliate Link', 'text_domain' ),
'view_items' => __( 'View Items', 'text_domain' ),
'search_items' => __( 'Search affiliate links', 'text_domain' ),
'not_found' => __( 'No affiliate links found', 'text_domain' ),
'not_found_in_trash' => __( 'No affiliate links found in Trash', 'text_domain' ),
'featured_image' => __( 'Featured Image', 'text_domain' ),
'set_featured_image' => __( 'Set featured image', 'text_domain' ),
'remove_featured_image' => __( 'Remove featured image', 'text_domain' ),
'use_featured_image' => __( 'Use as featured image', 'text_domain' ),
'insert_into_item' => __( 'Insert into item', 'text_domain' ),
'uploaded_to_this_item' => __( 'Uploaded to this item', 'text_domain' ),
'items_list' => __( 'Items list', 'text_domain' ),
'items_list_navigation' => __( 'Items list navigation', 'text_domain' ),
'filter_items_list' => __( 'Filter items list', 'text_domain' ),
);
$args = array(
'label' => __( 'Affiliate Link', 'text_domain' ),
'description' => __( 'Affiliate Links.', 'text_domain' ),
'labels' => $labels,
'supports' => array( 'title', 'revisions', ),
'taxonomies' => false,
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 8,
'menu_icon' => 'dashicons-media-text',
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => false,
'rewrite' => array('slug' => 'go'),
'exclude_from_search' => true,
'publicly_queryable' => true,
'capability_type' => 'page',
);
register_post_type( 'affiliate_link', $args );
}
add_action( 'init', 'affiliate_links_post_type', 0 );
<?php
// Get ID of current Affiliate Link page
$post_id = get_the_ID();
// Get slug of Affiliate Link page
$slug = get_post_field( 'post_name', $post_id );
// Get related Post with the same slug
$related_post = get_page_by_path( $slug, OBJECT, 'post' );
// Get ID of Post
$review_id = $related_post->ID;
// Get title of Post
$destination_title = get_the_title( $review_id );
// Get link from Post
$destination = get_field('tracker_link', $review_id);
// Get thumbnail from Post
$destination_logo = get_post_thumbnail_id($review_id);
// If no related review go to this URL
$fallback = "/";
?>
<?php if($related_post) { ?>
<div class="loading-logo-container">
<?php echo wp_get_attachment_image( $destination_logo, 'medium', false, array ('alt' => get_the_title(), 'class' => "loading-logo") ); ?>
</div>
<div class="loading-message">
Sit tight, we're taking you to <?php echo $destination_title; ?>...
</div>
<div class="loading-message">
Not working? <a href="<?php echo $destination; ?>">Click here</a>!
</div>
<div class="thanks-message">
Thanks for visiting <?php bloginfo( 'name' ); ?>!
</div>
<?php
header( "refresh:1;url=$destination" );
?>
<?php } else {
header( "refresh:0;url=$fallback" );
}
?>
.loading-container {
width: 100%;
min-height: 100vh;
padding-top: 20px;
padding-left: 20px;
padding-right: 20px;
padding-bottom: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
@-webkit-keyframes loading {
0% {
-webkit-transform: rotateY(0deg);
transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(360deg);
transform: rotateY(360deg);
}
}
@keyframes loading {
0% {
-webkit-transform: rotateY(0deg);
transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(360deg);
transform: rotateY(360deg);
}
}
.loading-logo-container {
background-color: #ffffff;
padding: 10px;
border-radius: 6px;
box-shadow: 0 0 40px -10px #bbb;
margin-bottom: 20px;
-webkit-animation: 1.8s loading infinite;
animation: 1.8s loading infinite;
}
.loading-rating {
font-weight: 700;
font-size: 2.5em;
margin-bottom: 20px;
}
.loading-message {
font-size: 1.5em;
margin-bottom: 40px;
}
.loading-message a {
font-size: inherit;
font-weight: 700;
}
.thanks-message {
font-size: 2em;
}
That’s it! End result: cleaner and more manageable data architecture, one less plugin, and more efficiency!
See it in action: https://smoothwebsites.net/go/cloudways
The SEOs in particular may want the answer to this one, as 301 is the generally-accepted HTML status code to use for affiliate link redirects.
Technically, this method is not a 301 redirect. What it does is refresh the page after a set period of time (one second, in this example), and by setting the URL of a different page in the refresh parameters, it gives the same user experience as a redirect. In fact, Screaming Frog crawls it as a 301, which suggests that other crawlers may do the same.
Although this is not the done thing really, as an SEO who doesn’t really believe in too many hard-and-fast rules, I think the solution works.
Usually you will be doing all of / some combination of the following:
Which means that Google isn’t going to be looking at them, so as long as the user experience is the same, I say why does it matter what the status code is? Answers on a postcard please 🙂
Yes. The key is in this segment of the code block:
// Get related Post with the same slug
$related_post = get_page_by_path( $slug, OBJECT, 'post' );
Simply replace ‘post’ with the name of your CPT, for example:
// Get related Review with the same slug
$related_post = get_page_by_path( $slug, OBJECT, 'review' );
I hope this helps some people. My name is Alex, I’m a WordPress designer/developer with a background in content writing and SEO – learning more and more each day.
Big thanks to Sridhar for republishing this tutorial here, and for giving me the grounding in PHP that made it possible. The original tutorial can be found here.
Session expired
Please log in again. The login page will open in a new tab. After logging in you can close it and return to this page.