Replacing Permalinks With Truly Permanent Links For Everlasting Ranks

Replace-permalinks-with-shortlinks

There are several usage scenarios when you’d want to replace permalinks with permanent links. Permalink is just another fancy word for your WordPress url structure. However for internal links to be truly permanent you need to use / insert shortlinks instead.

A permanent internal link structure comes handy when:

  1. You change the permalink structure of your WordPress site.
  2. Change the slug of pages (since WordPress doesn’t do an automatic 301 redirect for pages)

The right thing to do is to never insert permalinks at the first place. If you’ve already done that, then here’s the code that replaces them with the shortlinks.

The code is well commented. It certainly can be improved, but it did the job for me. The code works in the loop and needs to be hooked within the loop.

<?php
function bt_replace() {
    If ( ! current_user_can('switch_themes')) return;
    $post_id = get_the_id();
    if ( 'page' == get_post_type($post_id) || 'post' == get_post_type($post_id)) { // If we are on a post or a page (we want to avoid attachments etc.)
        $content = get_the_content(); // get the unfiltered content

        // $exp = "/href=[\"|\'](https\:\/\/www\.binaryturf\.com\/[^\"|\']+)/" ; // Uncomment this and set your website url

        $content = preg_replace_callback($exp, 'bt_replace_url', $content); // replacement magic. Match urls begining with our WP site.
        if(is_user_logged_in()){
            wp_update_post( array('ID' => $post_id, 'post_content' => $content) ,$error); // update the post with the new content
            bt_log($error);
        }
    }
}
function bt_replace_url($matches) {
    // as usual: $matches[0] is the complete match
    // $matches[1] the match for the first subpattern
    // enclosed in '(...)' and so on

    $postid = url_to_postid( matches[1] ); // get the post id from the matched url
    $post_type = get_post_type($postid);
    if ( $postid && ('page' == $post_type || 'post' == $post_type)){ // If this is the link to a post or page (we want to avoid attachments etc.)
        $shorturl = wp_get_shortlink($postid); // convert it into shorturl
        if(empty($shorturl)) {
            return matches[0];
        }
        if('page' == $post_type) {
            $shorturl = str_replace('?p=','?page_id=',$shorturl);
        }
        return str_replace(matches[1], $shorturl, matches[0]);
    }
    return $matches[0];
}
//add_action('genesis_before_entry','bt_replace'); // uncomment and edit this. any hook within the loop should do
function bt_log($str) {
    echo '<pre>';
    print_r($str);
    echo '</pre>';
}

Note: After adding this code to your functions.php you will need to revisit all the posts on your blog. You can do this by simply visiting the blog as well.

The catch is, in this particular case wp_update_post is fired on genesis_before_entry. And to update the post content you will have to trigger genesis_before_entry which happens only when the post content is reloaded.

Divi WordPress Theme