The issue arises because str_replace()
is replacing partial matches (like “POA” inside “POA (+)”). To fix this and ensure only exact matches are replaced, we can switch to using regular expressions with preg_replace()
.
Here’s a refined version of your function:
function auto_link_post_titles( $content, $post_id, $field ) {
$excluded_ids = array();
$excluded_field_names = array();
if ( isset( $_GET['ntb'] ) || did_action( 'ninja_tables_loaded' ) ) {
return $content;
}
if ( !in_array( $post_id, $excluded_ids ) && !in_array( $field['name'], $excluded_field_names ) ) {
$desired_post_types = array( 'my_post_type', 'my_other_post_type' );
$args = array(
'post_type' => $desired_post_types,
'post_status' => 'publish',
'posts_per_page' => -1,
);
$posts = get_posts( $args );
foreach ( $posts as $post ) {
$post_title = esc_html( $post->post_title );
$post_link = esc_url( get_permalink( $post->ID ) );
$link = '<a href="' . $post_link . '" target="_blank">' . $post_title . '</a>';
// Escape special characters and match exact title
$escaped_post_title = preg_quote($post_title, "https://wordpress.stackexchange.com/");
$content = preg_replace('/\b' . $escaped_post_title . '\b/u', $link, $content);
}
}
return $content;
}