DiggingIntoWordPress

by Chris Coyier & Jeff Starr

Easy Shortcode Permalinks

Posted by on

When you are building a theme, and the circumstance comes up where you need to create a link to a specific page hard-baked right into the theme, there is a function you should be using.

Not great:

<a href="/contact/">Contact</a>

Much better:

<a href="<?php echo get_permalink(12); ?>">Contact</a>

That “12″ would be the ID of the Post or Page. Why is this better?

  • If the slug ever changes, you are still cool.
  • If the site moves from a subdomain (like if you were developing and then moving) to a top level domain or vice versa, you are still cool.

Doing it this way is a permanent reference to that Post or Page that will never change. This works great when we are working within our theme files, but what about when we are working within WordPress and actually writing Posts and Pages?

By default, we can’t run PHP within the content of our Posts and Pages, so we can’t use the get_permalink function. What we can do, is create a shortcode with just about the same functionality. And here it is:

function permalink_thingy($atts) {
	extract(shortcode_atts(array(
		'id' => 1,
		'text' => ""  // default value if none supplied
    ), $atts));
    
    if ($text) {
        $url = get_permalink($id);
        return "<a href='$url'>$text</a>";
    } else {
	   return get_permalink($id);
	}
}
add_shortcode('permalink', 'permalink_thingy');

This shortcode can be used in two ways:

Basic:

<a href="[permalink id=49]">Using without providing text</a>

This way you only provide the id parameter and it only returns a URL. This was you can use that URL however you want. For example, if you needed to add a special class name to the link or something (but only occasionally).

Providing text:

[permalink id=49 text='providing text']

This way returns a fully formatted anchor link back, using the text you pass.

13 Responses

  1. Perfect!!!
    I have on question though: if i change the links on my blog to this shortcode, will it turn them to “not found” on google site maps??

    thanks :)

    • Wladia Viviani September 28, 2009

      Don’t worry, PHP works in back end, meaning that the page is served (to Google as well as to readers) with the value of the permalink – as opposed to the function call

  2. Thanks for the help Wladia!

  3. It’s best practice to wrap the $url in esc_attr(), like so:

    return "<a href='" . esc_attr($url) . "'>$text</a>";

  4. This may be a dumb question, but where do I write the php code?

  5. Does it mean an SQL request by link ?

    • I could be terribly wrong, but I’m pretty sure it’s not any SQL request at all.

      But it depends on what you mean by a “SQL request”, basicly every page you view, any action you do whatshowever in WordPress grabs content of some database.

      This thing simply checks the table of all posts, finds that id, and then outputs the URL the way you have permalinks set up.

      So whenever the page-slug changes, or whenever you change permalink structure for whatever reason, your links will stay functional :)

      • By request i mean a query, so if this function make a query for each link, it an lead soon to a large number of queries. did you try to test it with $wpdb->num_queries ?

  6. Daniel Groves September 29, 2009

    Thats a cool idea, I like that.

  7. Is there a solution to a similar problem with images and/or called in files? Right now I’m working on a theme (in a test location on a sub directory) and I want to be able to link in my header to a .js file without needing to go back and change that. I’m having the same prob with ‘s too.

    I hope this question wasn’t too far off topic.

  8. This is a brilliant little piece of code. Thanks for sharing!

  9. Thanks for explaining the difference between codes and your examples. Very informative.

Comments are closed. Contact us with any critical information. Thank you!

Code is poetry