Get WordPress permalink for posts & pages

Get WordPress permalink for posts & pages

Today I present PHP code to remedy a long-vexing (to me) deficiency in WordPress.

Zero-day use cases

The first-day needs of those starting with new software are what I call “zero-day use cases”. For example, users of a word processor require the ability to change typefaces and apply bolding to text usually pretty early in their experience. Footnoting is rarely needed immediately, if ever.

WordPress is pretty awesome, from its five-minute install to a user interface that allows those non-technical to create and maintain websites and blogs.

Irksome deficiencies and bizarre dichotomies

Two things which seriously irritate me about the stock deployment of WordPress are

  1. the bizarre dichotomy, foisted on users, between pages and posts. When programmatically dealing with the WordPress under the hood why should I have to think about two fundamentally different kinds of things when they’re both just content, albeit with pages not being anchored in the timeline. Grrr. I’ll explain below.
  2. the inability to simply link to another page or post in the same website. There are so many times when I want to refer to something else I’ve written, like about that great video I recently made.

A programmatic statement of the problem

What follows is how I’d like to refer to other pages or posts, some syntactic examples, and some error cases.

My use cases

The basic idea is that I want to create a shortcode to allow me to link to another page or post, knowing only the title, not caring about whether it was a page or a post.

[link t="title of page or post" a="optional alternative text"]

The first of two use cases is using the title as the text displayed in the link.

[link t="Migrating an HTML website to WordPress, pt. 1"]

This shows up as Migrating an HTML website to WordPress, pt. 1.

The second use case is supplying some alternative text as the link text.

[link t="Migrating an HTML website to WordPress, pt. 1" a="moving to WordPress"]

Which shows up as moving to WordPress.

You’ll notice I don’t specify whether the target is a page or a post; the truth is I can’t remember and don’t want to care. The computer ought to do my bidding. This shortcode works.

Handling errors

Showing you success is nice, but how we handle errors is vital. Here are common types of errors; missing arguments and passing arguments with typos or other errors.

[link t=""]
[link t="tpyo"]

Errors look like this: [[link]] shortcode error: can't find "tpyo".

Non-programmatic solutions

I looked for solutions for those who aren’t PHP programmers or uncomfortable mucking about in WordPress installations. I found nothing. Let me know if you find something to offer. In the meantime, adding this functionality is reasonably simple; there’s one step: insert the bit of code shown below into the functions.php file in your CHILD THEME.

A programmatic solution

add_shortcode( 'link', '___permalink_by_title' ) ;

function ___permalink_by_title( $args = array() ) {
    extract( shortcode_atts( array(
        't' => '',                              // page or post title
        'a' => ''                               // alternative text to display
    ), $args ) ) ;

    // how we emphasize error messages
    $eo='<font color="red"></strong>' ;         // usage: "{$eo}string{$ec}"
    $ec='</strong></font>' ;

    $types = array( 'post', 'page' ) ;          // look for both page and post
    $p = get_page_by_title( $t, OBJECT, $types ) ;
    if ( empty( $p ) ) {
        $name = "{$eo}[link] shortcode error: can't find \"$t\"{$ec}" ;
        $url = '' ;                             // no href for you :-/
    } else {
        $url = get_permalink( $p->ID ) ;
        if ( empty( $a ) ) { $name ="$t" ; }    // use page's name as link text
        else { $name ="$a" ; }                  // use alt as the link text

    return "<a href=\"{$url}\">$name</a>" ;

You may also find this code in this gist (which I would have inlined except my WordPress configuration refuses).

Leave a Reply

%d bloggers like this: