tags. * * Uses a single combined regex pattern to match ALL abbreviations in one pass, * providing O(1) performance regardless of the number of abbreviations defined. * * @param string $content The post content. * @return string Modified content with abbreviations wrapped. */ function abbreviations_process_content( $content ) { // Early bail-out conditions for performance. if ( empty( $content ) ) { return $content; } $abbreviations = abbreviations_get_cached(); if ( empty( $abbreviations ) ) { return $content; } // Build a lookup map: abbreviation => [title, lang]. $abbr_map = array(); foreach ( $abbreviations as $abbr ) { $abbr_map[ $abbr[0] ] = array( 'title' => $abbr[1], 'lang' => isset( $abbr[2] ) ? $abbr[2] : '', ); } // Sort abbreviations by length (longest first) to match longer terms first. $abbr_keys = array_keys( $abbr_map ); usort( $abbr_keys, function ( $a, $b ) { return strlen( $b ) - strlen( $a ); } ); // Build a single regex pattern with alternation for all abbreviations. // Using word boundaries and negative lookbehind/lookahead to avoid existing tags. $escaped_abbrs = array_map( 'preg_quote', $abbr_keys ); $pattern = '/((?:^|[\s>]))(' . implode( '|', $escaped_abbrs ) . ')((?:[\s><.,:;!?]|$))/s'; // Track which abbreviations have been replaced (first occurrence only). $replaced = array(); $content = preg_replace_callback( $pattern, function ( $matches ) use ( $abbr_map, &$replaced ) { $prefix = $matches[1]; $abbr = $matches[2]; $suffix = $matches[3]; // Skip if already inside an abbr tag (check for closing tag after). // Skip if this abbreviation was already replaced. if ( isset( $replaced[ $abbr ] ) ) { return $matches[0]; } // Mark as replaced. $replaced[ $abbr ] = true; $title = esc_attr( $abbr_map[ $abbr ]['title'] ); $lang = $abbr_map[ $abbr ]['lang']; $lang_attr = ''; if ( '' !== $lang ) { $lang_attr = ' lang="' . esc_attr( $lang ) . '"'; } return $prefix . '' . esc_html( $abbr ) . '' . $suffix; }, $content ); return $content; } add_filter( 'the_content', 'abbreviations_process_content' ); add_action( 'admin_menu', function () { add_options_page( 'Abbreviations', 'Abbreviations', 'manage_options', 'abbreviations', function () { // check user capabilities if ( ! current_user_can( 'manage_options' ) ) { return; } // show error/update messages settings_errors( 'abbreviations' ); ?>

An abbreviation like FYI is a shortened form of a word or phrase, by any method. This plugin adds abbreviation HTML tag which creates meaningful abbreviation expansion and provides useful information to the browsers, translation systems, and search-engines.
The optional global attribute can be specified in case it differs from the language of the entire page.

' . __( 'Settings', 'abbreviations' ) . '', ); $actions = array_merge( $actions, $links ); return $actions; } ); add_action( 'admin_init', function () { $args = array( 'type' => 'array', 'sanitize_callback' => function ( $value ) { $res = array(); $all_abbrs = array(); foreach ( $value as $item ) { $abbr = sanitize_text_field( $item[0] ); $desc = sanitize_text_field( $item[1] ); $lang = sanitize_text_field( $item[2] ); if ( $abbr && $desc && ! in_array( $abbr, $all_abbrs, true ) ) { $res[] = array( $abbr, $desc, $lang ); $all_abbrs[] = $abbr; } } return $res; }, 'default' => array(), ); register_setting( 'abbreviations', 'abbreviations', $args ); // Register a new section in the "abbreviations" page. add_settings_section( 'abbreviations', '', function () { return 'Sexy'; }, 'abbreviations' ); add_settings_field( 'abbreviations_field', // As of WP 4.6 this value is used only internally. null, // output function is none, we rely on form data due to 3 column headers impossible to print via WP API null, 'abbreviations', 'abbreviations' ); } );