Categories

Text Replace

Author: Scott Reilly
Version: 3.9.1
First released: 2004-12-21
Last update: 2020-07-12
Compatibility: WP 4.9 – 5.4.2
Download: [ zip ]
Description:

Replace text with other text. Handy for creating shortcuts to common, lengthy, or frequently changing…

Extended Description

This plugin allows you to easily define text or HTML that should be used in your posts in place of words or phrases that are actually present in the posts. This is a handy technique for creating shortcuts to common, lengthy, or frequently changing text/HTML, or for smilies.

Additional features of the plugin controlled both via settings and filters:

  • Text replacement can be enabled for comments (it isn’t by default)
  • Text replacement can be made case insensitive (it is case sensitive by default)
  • Text replacement can be limited to doing only one replacement per term, per post (by default, all occurrences of a term are replaced)
  • Text replacement can be handled early or late in WordPress’s text filtering process (it’s early by default)

A few things to keep these things in mind:

  • Your best bet with defining shortcuts is to define something that would never otherwise appear in your text. For instance, bookend the shortcut with colons:

    :wp: => WordPress
    :aol: => America Online, Inc.

Otherwise, you risk proper but undesired replacements:

Hi => Hello

Would have the effect of changing “His majesty” to “Hellos majesty”.

  • If you intend to use this plugin to handle smilies, you should probably disable WordPress’s default smilie handler on the Writing Settings admin page.

  • This plugin is set to filter the_content, the_excerpt, widget_text, and optionally, get_comment_text and get_comment_excerpt. Filters from popular plugins such as Advanced Custom Fields (ACF) and Elementor are also handled by default (see FAQ for specifics). The filter ‘c2c_text_replace_filters’ can be used to add or modify the list of filters affected.

  • Text inside of HTML tags (such as tag names and attributes) will not be matched. So, for example, you can’t expect the :mycss: shortcut to work in: <a href=”” :mycss:>text</a>.’.

  • SPECIAL CONSIDERATION: Be aware that the shortcut text that you use in your posts will be stored that way in the database (naturally). While calls to display the posts will see the filtered, text replaced version, anything that operates directly on the database will not see the expanded replacement text. So if you only ever referred to “America Online” as “:aol:” (where “:aol:” => “America Online“), visitors to your site will see the linked, expanded text due to the text replace, but a database search would never turn up a match for “America Online”.

  • However, a benefit of the replacement text not being saved to the database and instead evaluated when the data is being loaded into a web page is that if the replacement text is modified, all pages making use of the shortcut will henceforth use the updated replacement text.

Links: Plugin Homepage | Plugin Directory Page | GitHub | Author Homepage

Hooks

The plugin exposes a number of filters for hooking. Typically, the code to utilize these hooks would go inside your active theme’s functions.php file. Bear in mind that all of the features controlled by these filters are configurable via the plugin’s settings page. These filters are likely only of interest to advanced users able to code.

c2c_text_replace_filters (filter)

The ‘c2c_text_replace_filters’ hook allows you to customize what hooks get text replacement applied to them.

Arguments:

  • $hooks (array): Array of hooks that will be text replaced.

Example:

/**
 * Enable text replacement for post/page titles.
 *
 * @param array $filters Filters handled by the Text Replace plugin.
 * @return array
 */
function more_text_replacements( $filters ) {
    $filters[] = 'the_title'; // Here you could put in the name of any filter you want
    return $filters;
}
add_filter( 'c2c_text_replace_filters', 'more_text_replacements' );

c2c_text_replace_third_party_filters (filter)

The ‘c2c_text_replace_third_party_filters’ hook allows you to customize what third-party hooks get text replacement applied to them. Note: the results of this filter are then passed through the c2c_text_replace_filters filter, so third-party filters can be modified using either hook.

Arguments:

  • $filters (array): The third-party filters whose text should have text replacement applied. Default array( 'acf/format_value/type=text', 'acf/format_value/type=textarea', 'acf/format_value/type=url', 'acf_the_content', 'elementor/frontend/the_content', 'elementor/widget/render_content' ).

Example:

/**
 * Stop text replacements for ACF text fields and add text replacements for a custom filter.
 *
 * @param array $filters
 * @return array
 */
function my_c2c_text_replace_third_party_filters( $filters ) {
    // Remove a filter already in the list.
    unset( $filters[ 'acf/format_value/type=text' ] );
    // Add a filter to the list.
    $filters[] = 'my_plugin_filter';
    return $filters;
}
add_filter( 'c2c_text_replace_third_party_filters', 'my_c2c_text_replace_third_party_filters' );

c2c_text_replace_filter_priority (filter)

The ‘c2c_text_replace_filter_priority’ hook allows you to override the default priority for the ‘c2c_text_replace’ filter.

Arguments:

  • $priority (int): The priority for the ‘c2c_text_replace’ filter. The default value is 2.
  • $filter (string): The filter name.

Example:

/**
 * Change the default priority of the 'c2c_text_replace' filter to run after most other plugins.
 *
 * @param int $priority The priority for the 'c2c_text_replace' filter.
 * @return int
 */
function my_change_priority_for_c2c_text_replace( $priority, $filter ) {
    return 1000;
}
add_filter( 'c2c_text_replace_filter_priority', 'my_change_priority_for_c2c_text_replace', 10, 2 );

c2c_text_replace (filter)

The ‘c2c_text_replace’ hook allows you to customize or override the setting defining all of the text replacement shortcuts and their replacements.

Arguments:

  • $text_replacement_array (array): Array of text replacement shortcuts and their replacements. This will be the value set via the plugin’s settings page.

Example:

/**
 * Add dynamic shortcuts.
 *
 * @param array $replacements Array of replacement terms and their replacement text.
 * @return array
 */
function my_text_replacements( $replacements ) {
    // Add replacement
    $replacements[':matt:'] => 'Matt Mullenweg';
    // Unset a replacement that we never want defined
    if ( isset( $replacements[':wp:'] ) )
        unset( $replacements[':wp:'] );
    // Important!
    return $replacements;
}
add_filter( 'c2c_text_replace', 'my_text_replacements' );

c2c_text_replace_comments (filter)

The ‘c2c_text_replace_comments’ hook allows you to customize or override the setting indicating if text replacement should be enabled in comments.

Arguments:

  • $state (bool): Either true or false indicating if text replacement is enabled for comments. The default value will be the value set via the plugin’s settings page.

Example:

// Prevent text replacements from ever being enabled in comments.
add_filter( 'c2c_text_replace_comments', '__return_false' );

c2c_text_replace_case_sensitive (filter)

The ‘c2c_text_replace_case_sensitive’ hook allows you to customize or override the setting indicating if text replacement should be case sensitive.

Arguments:

  • $state (bool): Either true or false indicating if text replacement is case sensitive. This will be the value set via the plugin’s settings page.

Example:

// Prevent text replacement from ever being case sensitive.
add_filter( 'c2c_text_replace_case_sensitive', '__return_false' );

c2c_text_replace_once (filter)

The ‘c2c_text_replace_once’ hook allows you to customize or override the setting indicating if text replacement should be limited to once per term per piece of text being processed regardless of how many times the term appears.

Arguments:

  • $state (bool): Either true or false indicating if text replacement is to only occur once per term. The default value will be the value set via the plugin’s settings page.

Example:

// Only replace a term/shortcut once per post.
add_filter( 'c2c_text_replace_once', '__return_true' );

Find out more at the plugin’s WordPress Plugin Repository page.

Screenshots

Click to see full-size image.

  1. A screenshot of the admin options page for the plugin, where you define the terms/phrases/shortcuts and their related replacement text

    A screenshot of the admin options page for the plugin, where you define the terms/phrases/shortcuts and their related replacement text

Installation

  1. Whether installing or updating, whether this plugin or any other, it is always advisable to back-up your data before starting
  2. Install via the built-in WordPress plugin installer. Or download and unzip text-replace.zip inside the plugins directory for your site (typically wp-content/plugins/)
  3. Activate the plugin through the ‘Plugins’ admin menu in WordPress
  4. Go to the Settings -> Text Replace admin options page and customize the options (notably to define the shortcuts and their replacements)

Frequently Asked Questions

Q. Does this plugin modify the post content in the database?
A. No. The plugin filters post content on-the-fly.

Q. Will this work for posts I wrote prior to installing this plugin?
A. Yes, if they include strings that you’ve now defined as shortcuts.

Q. What post fields get handled by this plugin?
A. By default, the plugin filters the post content, post excerpt fields, widget text, and optionally comments and comment excerpts. You can use the ‘c2c_text_replace_filters’ filter to modify that behavior (see Hooks section).

Q. How can I get text replacements to apply for post titles (or something not text-replaced by default)?
A. You can add to the list of filters that get text replacements using something like this (added to your theme’s functions.php file, for instance):

function more_text_replacements( $filters ) {
    $filters[] = 'the_title'; // Here you could put in the name of any filter you want
    return $filters;
}
add_filter( 'c2c_text_replace_filters', 'more_text_replacements' );

Q. Is the plugin case sensitive?
A. By default, yes. There is a setting you can change to make it case insensitive. Or you can use the ‘c2c_text_replace_case_sensitive’ filter (see Hooks section).

Q. I use :wp: all the time as a shortcut for WordPress, but when I search posts for the term “WordPress”, I don’t see posts where I used the shortcut; why not?
A. Rest assured search engines will see those posts since they only ever see the posts after the shortcuts have been replaced. However, WordPress’s search function searches the database directly, where only the shortcut exists, so WordPress doesn’t know about the replacement text you’ve defined.

Q. Will all instances of a given term be replaced in a single post?
A. By default, yes. There is a setting you can change so that only the first occurrence of the term in the post gets replaced. Or if you are a coder, you can use the ‘c2c_text_replace_once’ filter (see Hooks section).

Q. Does this plugin explicitly support any third-party plugins?
A. Yes. While this plugin is compatible with many other plugins that modify post and widget text, this plugin has explicit built-in support for Advanced Custom Fields and Elementor, which provide additional content areas. See documentation on the hook c2c_text_replace_third_party_filters for a complete list of default supported third-party filters and how to enable compatibility with other plugins and themes.

Q. Does this plugin include unit tests?
A. Yes.

Release Log

3.9.1 (2020-07-11)

  • This minor release updates a bunch of documentation, updates a few URLs to be HTTPS, improves unit testing, and notes compatibility through WP 5.4+.

Details:

  • Change: Revamp a lot of the help text on the settings page
  • Change: Improve and expand upon documentation
  • Change: Note compatibility through WP 5.4+
  • Change: Update links to coffee2code.com to be HTTPS
  • Change: Add a number of new TODO items
  • Unit tests:
    • New: Add test for options_page_description()
    • New: Add test for setting name
    • Change: Remove unnecessary unregistering of hooks in tearDown()
    • Change: Remove duplicative reset_options() call
    • Change: Store plugin instance in test object to simplify referencing it
    • Change: Use HTTPS for link to WP SVN repository in bin script for configuring unit tests (and delete commented-out code)

3.9 (2020-01-15)

  • This feature release adds support for Advanced Custom Fields and Elementor, adds a new setting that can allow the plugin to run later to avoid potential conflicts with other plugins, adds a number of filters, updates compatibility to be WP 4.9-5.3+, and more.

Details:

  • New: Add support for third-party plugins: Advanced Custom Fields, Elementor
  • New: Add filter c2c_text_replace_third_party_filters for filtering third party filters
  • New: Add new setting to allow control over when text replacements are handled early or late in text processing process
  • New: Add filter c2c_text_replace_filter_priority for filtering hook priority for text replacement handler
  • Fix: Ensure the lack of any defined replacements doesn’t remove zeroes from text
  • Change: Alter handling of replace_once value to ensure a valid value is used as arg for preg_replace()
  • Change: Initialize plugin on plugins_loaded action instead of on load
  • Change: Remove plugin setting page help text indicating order matters (it hasn’t since v3.8)
  • Change: Update plugin framework to 050
    • 050:
    • Allow a hash entry to literally have ‘0’ as a value without being entirely omitted when saved
    • Output donation markup using printf() rather than using string concatenation
    • Update copyright date (2020)
    • Note compatibility through WP 5.3+
    • Drop compatibility with version of WP older than 4.9
    • 049:
    • Correct last arg in call to add_settings_field() to be an array
    • Wrap help text for settings in label instead of p
    • Only use label for help text for checkboxes, otherwise use p
    • Ensure a textarea displays as a block to prevent orphaning of subsequent help text
    • Note compatibility through WP 5.1+
    • Update copyright date (2019)
  • New: Add CHANGELOG.md and move all but most recent changelog entries into it
  • New: Add TODO.md and move existing TODO list from top of main plugin file into it (and add more items to the list)
  • New: Add inline documentation for hooks
  • Unit tests:
    • New: Add capture_filter_value() as a method for capturing default values provided for a filter
    • New: Add get_filter_names() as a helper method for getting the default and third-party filter names
    • New: Add unhook_default_filters() as a helper method to unhook plugin’s default filters hooked to text_replace()
    • New: Add tests for setting defaults
    • New: Add text_to_replace example values to verify replacement to 0 and an empty string are valid
    • New: Add failing tests for replacements affecting shortcode tags and shortcode attributes (though current behavior may be desired)
    • New: Add failing test for replacement text itself getting a replacement (though current behavior may be desired)
    • New: Add new test_does_not_replace_within_markup_attributes()
    • Change: Rename old test_does_not_replace_within_markup_attributes() to test_does_not_replace_within_markup_attributes_but_does_between_tags()
    • Change: Update unit test install script and bootstrap to use latest WP unit test repo
    • Change: Explicitly check hook priority when checking that hook is registered
    • Change: Update some inline docs and function names to reflect their relevance to this plugin (and not to the plugin they were copied from)
    • Fix: Fix unit test function name so that it is treated as a unit test
  • Change: Note compatibility through WP 5.3+
  • Change: Drop compatibility with version of WP older than 4.9
  • Change: Tweak some documentation in readme.txt
  • Change: Update copyright date (2020)
  • Change: Update License URI to be HTTPS
  • Change: Split paragraph in README.md’s “Support” section into two
  • Fix: Correct typo in GitHub URL

3.8 (2018-07-14)

  • This release adds a setting for links to open in a new window, adds support for linkable text spanning multiple lines in your post, adds a filter for customizing link attributes, improves performance, and makes numerous behind-the-scenes improvements and changes.

Details:

  • New: Ensure longer, more precise link strings match before shorter strings that might also match, regardless of order defined
  • Fix: Honor setting to limit text replacements to just once a post for multibyte strings
  • New: Add support for finding text to replace that may span more than one line or whose internal spaces vary in number and type
  • Change: Update plugin framework to 048
    • 048:
    • When resetting options, delete the option rather than setting it with default values
    • Prevent double “Settings reset” admin notice upon settings reset
    • 047:
    • Don’t save default setting values to database on install
    • Change “Cheatin’, huh?” error messages to “Something went wrong.”, consistent with WP core
    • Note compatibility through WP 4.9+
    • Drop compatibility with version of WP older than 4.7
    • 046:
    • Fix reset_options() to reference instance variable $options
    • Note compatibility through WP 4.7+
    • Update copyright date (2017)
    • 045:
    • Ensure reset_options() resets values saved in the database
    • 044:
    • Add reset_caches() to clear caches and memoized data. Use it in reset_options() and verify_config()
    • Add verify_options() with logic extracted from verify_config() for initializing default option attributes
    • Add add_option() to add a new option to the plugin’s configuration
    • Add filter ‘sanitized_option_names’ to allow modifying the list of whitelisted option names
    • Change: Refactor get_option_names()
  • Change: Cast return values of hooks to expected data types
  • New: Add README.md
  • New: Add GitHub link to readme
  • Change: Store setting name in constant
  • Unit tests:
    • Change: Improve test initialization
    • Change: Improve tests for settings handling
    • Change: Default WP_TESTS_DIR to /tmp/wordpress-tests-lib rather than erroring out if not defined via environment variable
    • Change: Enable more error output for unit tests
    • New: Add more tests
    • New: Add header comments to bootstrap
  • Change: Note compatibility through WP 4.9+
  • Change: Drop compatibility with version of WP older than 4.7.
  • Change: Rename readme.txt section from ‘Filters’ to ‘Hooks’
  • Change: Modify formatting of hook name in readme to prevent being uppercased when shown in the Plugin Directory
  • Change: Update installation instruction to prefer built-in installer over .zip file
  • Change: Update URLs used in examples and docs to be HTTPS where appropriate
  • Change: Update copyright date (2018)

Copyright & Disclaimer

Copyright © 2004-2020 by Scott Reilly (aka coffee2code)

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Discussion / Support

Have any questions, comments, or suggestions? Please provide them via the plugin’s WordPress.org support forum. I’ll do my best to reply in a timely fashion and help as best I can.

Unfortunately, I cannot provide guaranteed support, nor do I provide support via any other means.

Was this plugin useful useful to you? Consider giving it a rating. If you’re inclined to give it a poor rating, please first post to the support forum to give me a chance to address or explain the situation.

6 replies on “Text Replace”