Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Automatically link post titles
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Get post titles.
*
* Get a list of the post titles and related post IDs.
*
* @since 1.0.0
*
* @return array List of post titles/ post IDs.
*/
function wpal_get_post_titles() {
$post_titles = array();
if ( false === $post_titles = get_transient( 'wpal_post_titles' ) ) :
global $wpdb;
$post_titles = $wpdb->get_results( ( "SELECT ID, post_title from $wpdb->posts WHERE post_type='post' AND post_status = 'publish' AND CHAR_LENGTH(post_title) > 5" ) );
set_transient( 'wpal_post_titles', $post_titles, WEEK_IN_SECONDS );
endif;
return $post_titles;
}
/**
* Replace content.
*
* Search the content for the post titles and replace them when found.
*
* @since 1.0.0
*
* @param string $content Existing post content.
* @return string Modified post content.
*/
function wpal_replace_the_content( $content ) {
// Prepare pot titles
$post_titles = wpal_get_post_titles();
$titles = wp_list_pluck( $post_titles, 'post_title', 'ID' );
$preg_quote_titles = array();
// Escape post titles
foreach ( $titles as $key => $title ) :
$preg_quote_titles[ $key ] = preg_quote( $title, '/' );
endforeach;
// Search for any post titles
$content = preg_replace_callback( '/(' . implode( '|', $preg_quote_titles ) . ')/i', function( $matches ) use ( $preg_quote_titles ) {
global $post;
// Get post ID
$post_id = array_search( strtolower( $matches[0] ), array_map( 'strtolower', $preg_quote_titles ) );
// Don't link to the current page
if ( isset( $preg_quote_titles[ $post_id ] ) && $post->ID !== $post_id ) :
// Use the post title from the DB to its casing is the same
return '<a href="' . get_permalink( $post_id ) . '" class="post-link">' . $preg_quote_titles[ $post_id ] . '</a>';
endif;
return $matches[0];
}, $content );
return $content;
}
add_filter( 'the_content', 'wpal_replace_the_content' );
/**
* Remove transient on save.
*
* Remove the transient holding the post_titles every time a
* post is saved to ensure no unwanted links occur.
*
* ALSO re-index the post titles.
*
* @since 1.0.0
*/
function wpal_remove_transient() {
// Delete old post title transient
delete_transient( 'wpal_post_titles' );
// Re-index post titles
wpal_get_post_titles();
}
add_action( 'save_post', 'wpal_remove_transient' );
@jakedeg

This comment has been minimized.

Copy link

jakedeg commented Aug 12, 2017

How do I actually implement this on a wordpress site? Do I have to copy it to functions.php? Do I have to somehow tell the site to load this file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.