Putting external link icon in WordPress

Last updated on January 30, 2011. Tags: , ,

Web page links may lead to either another page of the same website (internal links) or to another website (external links). With the way HTML works, there's no built-in way of differentiating these two kinds of link. Website developers, however, can provide a way for visitors to know which link goes outside the website and which link points to the same website.

One way of doing it, which I already discussed, is to have all internal links open in the same window and all external links open in another window (or tab). However, there are issues with regards to the usability of this technique; some web developers claim that the users are the ones who should decide whether to open a link to the same window or to a new window.

While I personally do not believe in this idea, another popular way of differentiating internal and external links is by putting a small graphic, usually a square with an arrow pointing up-right (external-small). Wikipedia and other websites that run in Wiki CMS are just few of the websites that use this method.

Putting an external link graphic to your WordPress-powered website requires three steps:

  1. Configuring the graphic and uploading it to your website hosting/server
  2. Setting up the CSS code of external link
  3. Inserting a PHP code in WordPress theme to detect all external links

I will explain these steps in details in the following sections.

Step 1. Configuring the graphic

Thanks to Wikipedia, the square with portruding arrow icon is now a universally recognized indicator of external link (I'm not sure if Wikipedia is the one that started this convention). You can download it here; it's a public domain image so you don't need to worry about copyright issues. Then, modify it to the color that suits the WordPress theme of your website using GIMP or some other image editing software.

Another option is to make your own icon from scratch using GIMP (or other image editing software). Just be sure that it will be recognized as external link. Another variant is to have the arrow entirely inside the square.

After you created or modified the graphic, reduce it to the same height as the characters in your content area i.e. if the height of your text as defined in the CSS is 12px, then make the height of the external link graphic 12px. Then, upload it to /wp-content/themes/<your theme folder>/images/.

Step 2. Setting-up the CSS code

For this step, you need to open the style.css file that comes with your theme and insert the following CSS code:

.external {
	padding-right: 11px;
	background: url('images/external.gif') no-repeat right top;
}

In the above code, we decided to name the class "external" and the name of the external link icon graphic is external.gif. Just name the class with whatever you want and change the name of the graphic to the actual name of the file you saved and uploaded in Step 1. The padding 11 px is something you can adjust to ensure that the link text (or graphic) does not overlap with the external link icon.

Step 3. Automating the insertion of external link icon

Finally, open the functions.php file of your theme and insert the PHP code below. As usual, insert it in a way that it does not prevent other functions from working. If you're new to PHP, the safest place to insert it is either immediately after the first <?php or immediately before the last ?> in functions.php. Replace www.domain.com with the actual domain of your website.

function autoicon($text) {
$return = str_replace('<a href=', '<a class="external" href=', $text);
$return = str_replace('<a class="external" href="http://www.domain.com', '<a href="http://www.domain.com', $return);
$return = str_replace('<a class="external" href="#', '<a href="#', $return);
return $return;
}
add_filter('the_content', 'autoicon');

This code will insert class="external" to all hyperlinks in all your content (posts and static pages) that points to pages outside your website. The "external" class is the class that we defined in CSS in Step 2, and inserting this class on a link means the external link icon we created in Step 1 will appear together with it. If you named this class with something else, just replace "external" with the name you've given.

This is how it works:

  • The first line defines the function autoicon, which starts in an open bracket({).
  • The second line inserts class="external" to ALL links found.
  • The third line removes the class="external" to a link if the domain in it happens to be your own domain.
  • The fourth line removes the class="external" to an anchor HTML link (i.e., link to a part of the same webpage).
  • The fifth line returns the results of second to fourth line.
  • The sixth line ends the function autoicon with a close bracket (}).
  • In the seveth line, the function autoicon is applied to the content of the page or post.

As mentioned by Clay in the comment section below, you can replace '<a href=' in the second line with just 'href' and you need to do it this way if you will implement the title attribute for the hyperlink: WordPress implement it as <a title="something" href="http://domain.com/page.htm" and thus, the function will not be able to detect the string '<a href='  (Addendum, Jan. 30, 2011).

In most cases, you can remove the '<a ' string in the second to fourth line and the function will work as fine. You will only need the string '<a ' if your website or blog discusses web development topics wherein you need to mention 'href' as part of the discussion. Without the string '<a ', the autoicon function will scan and replace 'href' whether it is used as link code or as plain text (Addendum, Jan. 30, 2011).

The code we discussed in Step 3 can work only if you've been consistent in your internal links, either as http://www.domain.com or http://domain.com only. In case you used both the www and non-www version of your domain throughout the site, you need to change all www to non-www or vice versa, whichever domain version you prefer.

You can make the domain in your internal links consistent by doing search and replace on the database, either manual or with the aid of a plugin. Another solution is to insert the function canonical in the functions.php to make all internal links consistent. However, if you opt for this method, the function canonical should come first before the function autoicon in the functions.php.

This technique was last tested in WordPress ver. 3.0.3 and would likely work in near versions (Addendum, Jan. 30, 2011).

Miscellaneous

If you allow links in the comment text (the actual comment, not the name of the commentator) and you also want to differentiate internal and external links there, just add the following below the seventh line of the PHP code.

add_filter('comment_text', 'autoicon');

If you use to manually set the link target of external links to a new window or tab (using WordPress visual editor), and no longer want them to open in a new window since you're already using the external link icon, insert the following between the fourth and the fifth lines of the PHP code.

$return = str_replace(' target="_blank">', '>', $return);
$return = str_replace('<a class="external" href="#', '<a href="#', $return);

Posted by Greten on January 30, 2010 under Cascading Stylesheet

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • StumbleUpon
  • Technorati

Related Posts

You might also be interested (randomly generated):

Read Comments

  1. Posted by Clay on 01.28.11 5:47 pm

    I’ve changed the code to scan for ‘” href’ instead of ‘<a href' to catch only links with titles, as the above code misses those and also adds the external link icon to any linked images (awkward…)

    Since WP adds the title between '<a ' and 'href=', the above code ignores any posts with titles. We entitle all posts on our blog, so the replacement I have suggested works for us. Of course, if you only entitle _some_, neither solution works for everything.

    My $0.02. I will post a more comprehensive solution if I ever figure out how to wrangle regular expressions to auto-detect and keep those from being updated.

    Cheers
    C

  2. Posted by Greten on 01.29.11 7:17 pm

    Thanks Clay, your solution has been incorporated in this post. I just realized that I don’t really need to scan the “<a” part since whenever href is used, it is always there.

  3. Posted by Clay on 01.31.11 10:54 pm

    So I have a slightly obsessive nature at times… I generated the following to handle links regardless of their inclusion of a title, to exclude links that contain an image, and to be flexible enough to adapt to other filters (like if you wanted to change the class of a text block if it contains specific text.)

    You can define the start and end of a section to search for (in this case ‘<a' and '</a' to find anchors), define a trigger term (in this case 'href=' to find linked anchors), and define exclusion terms (so in the case that the trigger term exists within the section but one of the exclusion terms also exists, in this case either an img '<img' or a relative reference 'www.domain.com', '"#', or '""', the new text will not be inserted.

    The new text is defined as $r. The function is not as hairy as it looks — I just commented it up profusely.

    Hope this helps someone :)
    C

    ============================================
    function exticon( $t ) {
    // $n is the needle array, where
    // $n[0] defines the section beginning,
    // $n[1] defines the trigger term, or the term that determines insertion,
    // $n[2] defines the section end,
    // $n[3] – $n[n] define exclusion term/s, or the term/s that preclude insertion

    $n = array(
    "<a", // section beginning
    "href=", // trigger term
    "</a", // section end
    "<img", // from here to end – exclusion terms
    "www.domain.com",
    "\"#",
    "\"\""
    );
    // $pN is a position marker to move the point of focus along the string
    $pN = 0;
    // $r is the text to insert into the string
    $r = " class=\"ext-link\"";
    // $iR is length (+1) of $r to add to marker to account for string padding after insertion
    $iR = strlen( $r ) + 1;
    // while the position marker is before the end of the string,
    while( $pN < strlen( $t ) ) {
    // get the position of the first element of the needle array
    // ( if the element does not appear, the result is FALSE )
    $p[0] = strpos( $t, $n[0], $pN );
    // if section beginning exists,
    if( $p[0] ) {
    // get the position of the remaining elements of the needle array
    for( $i = 1; $i < count( $n ); $i++ ) {
    $p[$i] = strpos( $t, $n[$i], $p[0] );
    }
    // move the marker to the section end and
    $pN = $p[2] + 1;
    // if trigger term exists within the section,
    if( $p[1] && ( $p[1] < $p[2] ) ) {
    // check for the exclusion terms –
    for( $j = 3; $j < count( $n ); $j++ ) {
    if( $p[$j] && ( $p[$j] < $p[2] ) ) {
    // if ANY exist within the section, move the marker to the section end and restart the while loop
    $pN = $p[2] + 1;
    continue 2;
    }
    }
    // set position for insertion at 2 past section beginning
    $pR = $p[0] + 2;
    // insert $r
    $t = substr_replace( $t, $r, $pR, 0 );
    // move the marker to the section end (padded to account for the insertion text length
    $pN = $p[2] + $iR;
    }
    // if there is no section beginning string, break the loop
    } else break;
    }
    return $t;
    }

  4. Posted by Greten on 02.02.11 2:43 pm

    Obsessive nature? Ha ha ha! I’m like that too although I learned lately to focus on what I really need to make life less stressful.

    Thank you for sharing that code. I hope one of the visitors of this page will find it useful. Regards!

Post Comments





Comment Rules and Reminders

  • The links to the commentator's e-mail do not have nofollow tag. However, I will be very strict in approving comments.
  • When you comment, please say something that indicates that you indeed read my post. If your comment is a general statement that can fit to any blog post about any topic, it will be regarded as spam.
  • What you write in the name field may include keywords to your website provided that (1) it's only up to four words long and (2) at least one of these four words is your first name or nickname. I rather reply to Bob or to Joe Smith than to Online Marketing Tips.
  • Please double check your comment before clicking the "Post" button. Once you clicked it, there will be no way for you to edit your comment.
  • Fields marked with asterisks (*) are required. Your email will never be displayed in public.