Wordpress Override rel=canonical

(2013)

A recent project required cross-posting content between two sites. To avoid duplicate content issues, we're using rel="canonical" to indicate which post is the original and which is the duplicate. While not 100% ideal, evidently cross-domain rel canonical is an okay thing to do. Oddly, right now, Wordpress does not seems to have a filter to modify the canonical link, but it does have an action you can replace with your own. Here's what you do:

// in an init hook
// unregister the default action
// and register our own
//
do_action('init', 'my_init');
function my_init() {
    remove_action( 'wp_head', 'rel_canonical' );
    add_action( 'wp_head', 'my_rel_canonical' );
}

// this is slightly modified from the original
// rel_canonical function in /wp-includes/link-template.php
// 
// assumes we have a custom post_meta property
// called 'my_canonical'
//
function my_rel_canonical() {
    if ( ! is_singular() )
     return;

    global $wp_the_query;
    if ( ! $id = $wp_the_query->get_queried_object_id() )
     return;

    // if there is a meta property defined
    // use that as the canonical url
    $canonical = get_post_meta( $id, 'my_canonical', TRUE );
    if( $canonical ) {
        echo "<link rel='canonical' href='$canonical' />\n";
        return;
    }

    $link = get_permalink( $id );
    if ( $page = get_query_var('cpage') )
        $link = get_comments_pagenum_link( $page );
        echo "<link rel='canonical' href='$link' />\n";
    }
}

And.. that's it.

Pretty easy! As mentioned above, this assumes you have a custom meta property called 'my_canonical' to store the url. If you had a really complicated use case, it might be even cleaner to override this action to implement a custom filter, but this is pretty clean and was good enough for my purpose.