If your blog includes articles about Web sites you have built, here’s a simple way to automagically and uniformly show “Visit Web Site” links at the end of all such posts.
Here’s what I’m talking about:

An “old way” would be to manually enter the hyperlink for each Web site at the end of each post, like this:
<a class="web-url" target="_blank" rel="noopener" href="https://somesite.com">Visit Web Site</a>
An improvement over that method would be to create a special shortcode with a single parameter (the Web URL) that you would manually enter at the end of each post.
But there’s a better way that doesn’t involve hard coding anything into the post content.
The better way to add a “Visit Web Site” link to each portfolio post
This better way involves:
- a custom field, whose name I’ll call “web_url”
- a custom function that generates the HTML for the “Visit Web Site” link
- an add_filter call that hooks the above function to the WordPress
the_contenthook. - css to dress up the link
Step 1: Add the custom field and value
If the Custom Fields section of the editor page isn’t showing, expand “Screen Options” and checkmark “Custom Fields”.

Enter web_url in the “Name” box and the URL of the Web site in the “Value” box.

(If you previously added the web_url custom field to another post, you can select it from the custom field “Name” dropdown.)
Step 2: Create a function to generate the HTML for the “Visit Web Site” link.
Do this in your child theme’s functions.php file or in a separate file in the mu-plugsins/ folder.
Here’s the code I used:
function nwb_show_web_url($content) {
if ( is_single() && $web_url = get_post_meta(get_the_ID(), 'web_url', true) ) {
$content .= '<div class="web-url"><a target="_blank" href="'.$web_url.'">Visit Web Site</a></div>';
}
return $content;
}
Code Explanation:
Line 1: Creates the custom function, passing the global $content variable as a parameter. This $content is the post content entered into the editor box.
Line 2: The first part of the “if” statement uses the WordPress is_single() function to test whether the current query is for an existing single post. The second part uses the WordPress get_post_meta() function to attempt to capture the value of the post’s “web_url” custom field. If the post has that custom field assigned to it, the value is assigned to the “$web_url” variable, and the second part of the condition is true.
Line 3: If both conditions evaluate to true, the HTML for the “Visit Web Site” link is appended to $content (using the .= operator).
Line 5: Finally, we return the new (“filtered”) $content.
Step 3: Use an add_filter call
add_filter( 'the_content', 'nwb_show_web_url', 10);
This tells wordpress to perform the instructions in the ‘nwb_show_web_url’ function and to change the post content to the return value of the function (because the function is hooked to the “the_content” hook).
Step 4: The CSS
.web-url {
text-align: center;
display: block;
margin-bottom: 2em;
}
.web-url a {
display: inline-block;
text-align: center;
padding: 1em;
border: 1px solid;
}
.web-url a:after {
font-family: 'FontAwesome';
content: " \f08e";
}
The first two rules are probably pretty straightforward.
The third rule uses the :after pseudo-element. It uses the FontAwesome Web font to generate the “external link” icon:
Epilogue
One of the benefits of posting articles like this is that I often find ways to improve things.
Case in point: I don’t know why I didn’t insert a return in my custom function in the event the conditions evaluated false.
Here’s the better way, and I’ll fix the code soon:
function nwb_show_web_url($content) {
if ( ! ( is_single() && $web_url = get_post_meta(get_the_ID(), 'web_url', true) ) ) {
return;
} else {
$content .= '<div class="web-url"><a target="_blank" href="'.$web_url.'">Visit Web Site</a></div>';
}
return $content;
}
And yes, there’s a shorthand version:
function nwb_show_web_url($content) {
if ( ! ( is_single() && $web_url = get_post_meta(get_the_ID(), 'web_url', true) ) )
return;
$content .= '<div class="web-url"><a target="_blank" href="'.$web_url.'">Visit Web Site</a></div>';
return $content;
}
Like what you see? Share with others and join my mailing list. No long-term commitment, unsubscribe any time.

Leave a Reply