17+ Useful WordPress snippets

Date posted: 2016-05-30
Last updated: 2026-10-03

Small PHP snippets for functions.php or a site-specific plugin: WordPress filters, actions and functions to add the functionality you need.

Here are 17+ valuable WordPress snippets for site-specific plugins and functions.php to provide you a better WordPress experience. Enhance your WordPress site with these small PHP snippets: WordPress filters, actions and functions. Quickly add or extend the functionality you need for your WordPress website! Read on...

A handful of small PHP snippets in a site-specific plugin or your theme's functions.php go a long way: hide login hints, load JavaScript async or deferred, add resource hints, remove version query strings and clean up your <head>. Always test a snippet on a staging site first, and prefer a child theme or site-specific plugin so theme updates don't wipe your changes.

I originally wrote this post in 2016. Several snippets are specific to the Enfold theme or to jQuery and Facebook SDK versions of that time, and WinCache has since been discontinued. WordPress core also caught up: since WordPress 4.9 expired transients are deleted automatically by a daily cron event, since WordPress 6.3 you can pass a defer or async loading strategy when you register a script, and the prerender resource hint has been superseded by the Speculation Rules API, which WordPress 6.8 uses for speculative loading out of the box.

Extending your WordPress blog with snippets improves speed, performance and security

A few years ago I wrote a post that summed up 9 WordPress plugins you'll need for your WordPress site, to extend its speed & performance, functionality, security and user experience. Later I wrote a post - in Dutch - with my WordPress plugins must-haves. This post is not about plugins, it's about useful and valuable WordPress code snippets.

Credit where credit is due, some snippets aren't mine. Whenever I could find - or remember - the original author, he or she is credited (some snippets are rather old, collecting dust in my archives, and hardly anywhere to be found anymore).

Redirect to another website after a WordPress login failure

WPBeginner wrote a small post on disabling WordPress login hints. WordPress login hints are the messages telling you your WordPress username and/or password is wrong, during login.

The WordPress filter code snippet for your theme's functions.php file or a site-specific plugin to change the WordPress login hints is:

<?php
function no_wordpress_errors(){
  return 'Something is wrong!';
}
add_filter( 'login_errors', 'no_wordpress_errors' );

This made me decide to play with this filter function: is it possible to redirect a visitor after a failed login in WordPress? Yes, it is! Here's my modified snippet you can use to redirect users after a login failure:

<?php
function saotn_redirect_after_login_errors() {
  wp_redirect( 'https://www.example.com/' );
  exit;
}
add_filter( 'login_errors', 'saotn_redirect_after_login_errors' );

This redirects a user to example.com whenever he or she tries to log on using invalid credentials. Find out more about wp_redirect. I have a Dutch article explaining why you must not use a delay (or PHP sleep() for that matter) in your WordPress login to prevent brute-force attacks. I'm not sure a redirect is a good alternative though...

My colleague Pieter created a plugin, PD Login Security, that:

Disables the default login errors, adding more security to the login form of your WordPress install.

Brute-force attacks don't only target wp-login.php. Learn how to protect WordPress from brute-force XML-RPC attacks.

The following three snippets are specifically for the WordPress theme Enfold, or any other theme using similar code. BTW, I'm in no way associated with Kriesi.

Add a WhatsApp button on Social Share Buttons

You can easily extend the Enfold social share buttons, beneath every post, with a WhatsApp share button. Add the following three (3) filter functions to your functions.php file:

<?php
// Register new icon as a theme icon
add_filter( 'avf_default_icons','avia_add_custom_icon', 10, 1 );
function avia_add_custom_icon($icons) {
  $icons['whatsapp'] = array( 'font' =>'whatsapp-font-icon', 'icon' => 'ue800');
  return $icons;
}

// Adjust icons
add_filter( 'avia_filter_social_icons', 'avia_filter_social_icons_mod', 10, 1 );
function avia_filter_social_icons_mod($icons) {
  $icons['Whatsapp'] = 'whatsapp';
  return $icons;
}

// Add items on the social share section
add_filter( 'avia_social_share_link_arguments', 'avia_add_social_share_link_arguments', 10, 1 );
function avia_add_social_share_link_arguments($args) {
  $args['whatsapp'] = array("encode"=>true,
    "encode_urls"=>false,
    "pattern" => "whatsapp://send?text=[title]&url=[permalink]",
    "label" => __( "Share on Whatsapp", 'avia_framework' )
  );
  return $args;
}

Now you can share your posts via WhatsApp, neat! 🙂

Source: Kriesi Enfold Support - Adding WhatsApp Button on Social Share Buttons and Re Adding WhatsApp Button on Social Share Buttons (Wayback Machine).

Load Facebook Like Box Asynchronously (async)

This one is not only for the Enfold theme, but for any WordPress theme using similar code (Rise of ThriveThemes being one of them).

Asynchronously loading the Facebook Like Box speeds up the loading of your WordPress website: the external resources are loaded asynchronously (async), or in parallel, meaning they don't block the browser. A lot of WordPress themes provide widgets like these Facebook Like Boxes, and it's important to load the scripts async for the reason I stated above.

This often involves making a change to a theme file. It'll be overwritten during a theme update if you don't use a child theme, so please keep that in mind.

First you need to look up where the Facebook Like Box JavaScript code resides, for Enfold it is in framework/php/class-framework-widgets.php. Add js.async = true; around line 80, and the complete Facebook JavaScript then becomes:

<?php
function fb_js() {
  if(self::$script_loaded == 1) return;
    self::$script_loaded = 1;
  echo '
    <script>(function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0]; 
    if (d.getElementById(id)) return; 
    js = d.createElement(s); js.id = id; 
    js.async = true; 
    js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.4"; 
    fjs.parentNode.insertBefore(js, fjs); 
    }
    (document, "script", "facebook-jssdk"));</script> 
  '; 
}

Did you spot js.async = true;? 🙂

Load all JavaScripts asynchronously: how to add the "async" attribute (Bonus!)

It's recommended to load as many JavaScript files asynchronously as possible in WordPress. An easy to use function to load JavaScript files async, using the script_loader_tag filter, is:

<?php
// https://matthewhorne.me/defer-async-wordpress-scripts/
function saotn_add_async_attribute( $tag, $handle ) {
  $scripts_to_async = array( 'google-adsense',      // example handles
    'jquery-sonar', 
    'jquery', 
    'dsq_embed_script', 
    'wpcom-lazy-load-images', 
    'dsq_count_script'
  );

    foreach( $scripts_to_async as $async_script ) {
    if ( $async_script === $handle ) {
      return str_replace( ' src', ' async="async" src', $tag );
    }
  }
  return $tag;
}
add_filter( 'script_loader_tag', 'saotn_add_async_attribute', 10, 2 );

Add the script handles of scripts you want to load async in the $scripts_to_async array.

Defer JavaScripts

Some JavaScripts need to load async, but some need to load deferred. This is how:

<?php
// https://matthewhorne.me/defer-async-wordpress-scripts/
function saotn_add_defer_attribute( $tag, $handle ) {
  $scripts_to_defer = array( 'prismjs',     // example handles
    'sparkling-functions', 
    'sparkling-bootstrapjs', 
    'sparkling-modernizr', 
    'sparkling-skip-link-focus-fix'
  );

   foreach( $scripts_to_defer as $defer_script ) {
    if ( $defer_script === $handle ) {
      return str_replace( ' src', ' defer="defer" src', $tag );
    }
  }
  return $tag;
}
add_filter( 'script_loader_tag', 'saotn_add_defer_attribute', 10, 2 );

Add additional Google fonts in Enfold for heading and content

So you want to prettify your fonts, and Enfold may be lacking some fonts? Here's a quick code snippet to add Ubuntu, Open Sans and Merriweather to your Enfold theme.

Add the following code directly below if(isset($avia_config['use_child_theme_functions_only'])) return; in your functions.php file:

<?php
add_filter( 'avf_google_heading_font',  'avia_add_heading_font');
function avia_add_heading_font($fonts) {
  $fonts['Open+Sans700400'] = 'Open+Sans:700,400';
  $fonts['Ubuntu400400'] = 'Ubuntu:400,400italic,500';
  return $fonts;
}
add_filter( 'avf_google_content_font',  'avia_add_content_font' );
function avia_add_content_font($fonts) {
  $fonts['Merriweather'] = 'Merriweather:300,700,700italic,300italic';
  $fonts['Ubuntu'] = 'Ubuntu:400,400italic,500';
  return $fonts;
}

Remove PHP Sessions in Enfold by Kriesi

Enfold by Kriesi creates a lot of session files on your server. This may clog and slow down your site. The PHP sessions in Enfold are primarily used for breadcrumbs. If you use the portfolio grid for example, sessions are used to save data for each user to track where they came from. This is then used to dynamically generate breadcrumbs.

If you are OK with not having these breadcrumbs (perhaps you're using Yoast SEO?), or you're not using the portfolio grid, and you want to speed up your WordPress site, then you can use the following in your Enfold theme functions.php file:

add_theme_support( 'avia_no_session_support' );

This disables PHP session support in the premium theme Enfold.

Load default WordPress jQuery from Google Library

Sometimes you run into problems with jQuery, and you need to temporarily change the jQuery version in use. You can load the jQuery JavaScript file from Google's CDN, so you can change versions quickly:

<?php
// Available jQuery versions: https://code.jquery.com/jquery/
function modify_jquery() {
  if ( !is_admin() ) {
    wp_deregister_script( 'jquery' );
    wp_register_script( 'jquery', '//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js', false, '2.1.4', true );
    wp_enqueue_script( 'jquery' );
  }
}
add_action( 'wp_enqueue_scripts', 'modify_jquery' );

The final true loads jQuery in the WordPress footer, near </body>, and this may cause unexpected behaviour. Set it to false, or remove it (false is the default value), to load jQuery in your HTML header.

Remove jQuery Migrate

DIYthemes writes in a blog post that "jQuery migrate is used to load any deprecated APIs and functions that were removed in jQuery 1.9". If your site doesn't use any of those deprecated functions (see the jQuery 1.9 upgrade guide for what changed), you can remove jQuery Migrate and save a request to your server. Source: 3 performance tips.

So here's a small function for your site-specific plugin or functions.php file:

/*
 * http://diythemes.com/thesis/3-performance-tips/
 * Remove jquery migrate for enhanced performance
 */
function remove_jquery_migrate($scripts) {
  if ( is_admin() ) return;
  $scripts->remove( 'jquery' );
  $scripts->add( 'jquery', false, array( 'jquery-core' ), '1.10.2' );
}
add_action( 'wp_default_scripts', 'remove_jquery_migrate' );

Clean expired transients automatically

Keeping your MySQL database small (lean & mean) is important for a fast operating database. Pressjitsu open-sourced and released their plugin to automatically clean expired transients from your database. This keeps your database smaller and faster.

You may find its source on Pressjitsu's GitHub. I used this as a basis for my plugin to regularly perform an OPTIMIZE TABLE statement on my MySQL database. They both utilize WordPress Cron.

Prefetch & prerender WordPress' next and previous posts

When a lot of your readers click through to your next or previous posts, you can speed up the loading and rendering of these posts by utilizing HTML5's prefetch & prerender link types - also known as resource hints.

If defined, they tell your browser to start loading the given URL to render in the background. This should give your visitors a near instant load when they click through.

In your site-specific plugin or functions.php, add the following function:

<?php
function saotn_post_prerender_prefetch() {
  $next_post = get_next_post();
  $prev_post = get_previous_post();
  if ( !empty( $next_post ) ) {
    echo '<link rel="prefetch" href="'.get_permalink( $next_post->ID ).'" />
    <link rel="prerender" href="'.get_permalink( $next_post->ID ).'" />';
  }
  if ( !empty( $prev_post ) ) {
    echo '<link rel="prefetch" href="'.get_permalink( $prev_post->ID ).'" />
    <link rel="prerender" href="'.get_permalink( $prev_post->ID ).'" />';
  }
}
add_action( 'wp_head', 'saotn_post_prerender_prefetch', 10 );

You might have guessed: this only helps when visitors do click through to your previous or next post. It doesn't work for random other posts.

DNS prefetch external hostnames (Bonus!)

You can use something similar to the above prefetch & prerender, to add hosts for DNS-prefetching:

<?php
function saotn_dns_prefetch() {
  echo '<meta http-equiv="x-dns-prefetch-control" content="on">
    <link rel="dns-prefetch" href="//secure.gravatar.com" />
    <link rel="dns-prefetch" href="//www.google-analytics.com" />
    <link rel="dns-prefetch" href="//apis.google.com" />
    <link rel="dns-prefetch" href="//ad.doubleclick.net" />
    <link rel="dns-prefetch" href="//fonts.gstatic.com" />
    <link rel="dns-prefetch" href="//fonts.googleapis.com" />
    <link rel="dns-prefetch" href="//www.facebook.com" />
    <link rel="dns-prefetch" href="//scontent.xx.fbcdn.net" />
    <link rel="dns-prefetch" href="//gstatic.com" />
    <link rel="dns-prefetch" href="//cdnjs.cloudflare.com" />
    <link rel="dns-prefetch" href="//platform.twitter.com" />
    <link rel="dns-prefetch" href="//jetpack.wordpress.com" />
    <link rel="dns-prefetch" href="//s0.wp.com" />
    <link rel="dns-prefetch" href="//s1.wp.com" />
    <link rel="dns-prefetch" href="//s2.wp.com" />
    <link rel="dns-prefetch" href="//public-api.wordpress.com" />
    <link rel="dns-prefetch" href="//0.gravatar.com" />
    <link rel="dns-prefetch" href="//1.gravatar.com" />
    <link rel="dns-prefetch" href="//2.gravatar.com" />
  ';
}
add_action( 'wp_head', 'saotn_dns_prefetch', 0 );

Only add hosts you really need prefetched.

WordPress resource hints

You can also make use of WordPress' own wp_resource_hints filter. Add the following to your site-specific plugin file to prefetch and prerender the previous post. It also adds a preconnect for maps.googleapis.com and use.typekit.net as an example, and removes those hosts from the dns-prefetch list.

function change_to_preconnect_resource_hints( $hints, $relation_type ) {
  $prev_post = get_previous_post();
  if ( 'prefetch' === $relation_type && !empty( $prev_post ) ) {
    $hints[] = get_permalink( $prev_post->ID );
  }
  if ( 'prerender' === $relation_type && !empty( $prev_post ) ) {
    $hints[] = get_permalink( $prev_post->ID );
  }
  if ( 'preconnect' === $relation_type ) {
    $hints[] = '//use.typekit.net';
    $hints[] = '//maps.googleapis.com';
  }

  if ( 'dns-prefetch' === $relation_type ) {
    $url_arr = array( 'maps.googleapis.com', 'use.typekit.net' );

    foreach ( $url_arr as $url ) {
      if ( ( $key = array_search( $url, $hints ) ) !== false ) {
        unset( $hints[ $key ] );
      }
    }
  }

  return $hints;
}
add_filter( 'wp_resource_hints', 'change_to_preconnect_resource_hints', 10, 2 );

Switch from [image src=""] shortcode to HTML img tags easily

This one may come in handy sometimes. Suppose you've switched WordPress themes, and your old theme provided an [image src=""] shortcode. If your new theme doesn't provide this same shortcode, all your images are broken and the shortcode code is displayed. That ain't pretty…

By adding your own shortcode, in your site-specific plugin or theme functions.php file, you can easily provide basic [image src=""] functionality: by returning an HTML <img tag.

<?php
function func_image( $atts, $content = null ) {
  $atts = shortcode_atts( array( 'src' => $content ), $atts, 'image' );
  return '<img src="' . esc_url( $atts['src'] ) . '"/>';
}
add_shortcode( 'image', 'func_image' );

This creates the [image src=""] shortcode for your site, and the image URL in its src attribute (e.g. your old image URL like "https://www.example.com/path/to/image.png") is used in the returned <img src="" tag. This fixes your old theme image shortcode, meaning you don't have to manually edit tens or hundreds of posts.

For example the shortcode [image src="https://www.example.com/wp-content/uploads/2016/05/my-image.png"] in posts becomes:

<img src="https://www.example.com/wp-content/uploads/2016/05/my-image.png"/>

But as always, this should be a short term solution until you've edited all your posts.

Google AdSense shortcode

Put your AdSense ad code in a shortcode, to include Google AdSense anywhere in your WordPress posts (source: my Dutch article "Google AdSense advertenties in WordPress met shortcodes"). Paste the ad unit code from your AdSense account between the single quotes:

<?php
function adsenseads_responsive() {
  $output = '<!-- paste your responsive AdSense ad unit code here -->';
  return $output;
}
add_shortcode( 'showmyads_responsive', 'adsenseads_responsive' );

This adds the shortcode [showmyads_responsive] for easy usage in your posts.

Using the block editor? Then a block is nicer than a shortcode: see my Gutenberg block for adding AdSense ads. And while you're tuning WordPress: change the Akismet interval to delete spam comments after three (3) days.

WordPress optimization: remove query strings from static resources, remove WordPress version number, and change stylesheet URL

Three often heard WordPress optimization techniques are to:

  1. remove query strings from static resources, making browsers able to cache the static files
  2. remove the WordPress version number, which adds some extra security - by obscurity, and
  3. change the stylesheet URL for content offloading

These snippets do just that. Remove the ver query string:

<?php
function saotn_remove_query_strings( $src ) {
  if( strpos( $src, '?ver=' ) ) {
    $src = remove_query_arg( 'ver', $src );
  }
  return $src;
}
add_filter( 'style_loader_src', 'saotn_remove_query_strings', 10, 2 );
add_filter( 'script_loader_src', 'saotn_remove_query_strings', 10, 2 );

Or, alternatively, strip everything from ?ver onwards:

<?php
function saotn_remove_script_version( $src ){
  $parts = explode( '?ver', $src );
  return $parts[0];
}
add_filter( 'script_loader_src', 'saotn_remove_script_version', 15, 1 );
add_filter( 'style_loader_src', 'saotn_remove_script_version', 15, 1 );

Remove the WordPress version number generator meta tag:

<?php
function saotn_remove_WP_version() {
  remove_action( 'wp_head', 'wp_generator' );
}
add_action( 'init', 'saotn_remove_WP_version' );

Change the stylesheet directory URL, for example to a CDN:

<?php
function saotn_stylesheet_directory_uri() {
  return "//cdn.example.com/wp-content/themes/[theme name]";
}
add_filter('stylesheet_directory_uri', 'saotn_stylesheet_directory_uri' );

Psst, want to make Twenty Seventeen full width (Wayback Machine)?!

Measure WordPress loading time and queries (Bonus!)

Did you ever want to know how to measure WordPress' loading time and executed database queries? During an HTTP request, WordPress executes a lot of queries on your MySQL database. Not only do these database queries take time, the loading and execution of PHP takes time too. It is important to measure this to be able to improve your WordPress loading speed.

WordPress has built-in functions to measure PHP's loading time and executed MySQL queries: get_num_queries() for the number of database queries, and timer_stop() for PHP execution time. I've written a post on how to measure WordPress loading time and MySQL queries using these native WordPress functions.

Clear opcode caches before updating WordPress (Bonus!)

Sometimes a WordPress update fails. Often this is due to installed opcode cache modules like OPcache, APC/APCu or WinCache. To streamline WordPress updates it's handy to know how to flush this opcode cache before applying updates. My post clear PHP opcode caches before WordPress updates: ease the updating process does just that.

WP-Super-Cache rewrite fix for IIS URL Rewrite Module

WP Super Cache is an extensive caching plugin for your website. It generates static HTML files of your dynamic WordPress website, saving a lot on database traffic and resources.

You can tweak the rewrite rules to make WP Super Cache perform even better! WP Super Cache uses URL rewriting to redirect external requests for your blog posts and pages to a separate directory that contains static HTML and gzip-ed pages. These static files are automatically created and maintained by the plugin.

The WP Super Cache plugin has been written for the Apache web server and will attempt to create and update .htaccess files within your WordPress installation, but those files have no effect when using IIS as the web server. Unless you use an ISAPI filter like ISAPI_Rewrite of course. But then, the rewrites can still be improved.

To rewrite URL requests directly to static cache files created by WP-Super-Cache, you can use these web.config URL Rewrite rules:

<rule name="WP_Super_Cache_rule_1" stopProcessing="true">
  <match url="^(.*)" ignoreCase="false" />
  <conditions logicalGrouping="MatchAll">
    <add input="{URL}" pattern="^.*[^/]$" ignoreCase="false" negate="true" />
    <add input="{URL}" pattern="^.*//.*$" ignoreCase="false" negate="true" />
    <add input="{REQUEST_METHOD}" pattern="POST" ignoreCase="false" negate="true" />
    <add input="{QUERY_STRING}" pattern=".*=.*" ignoreCase="false" negate="true" />
    <add input="{HTTP_COOKIE}" pattern="^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$" ignoreCase="false" negate="true" />
    <add input="{HTTPS}" pattern="on" ignoreCase="false" negate="true" />
    <add input="{DOCUMENT_ROOT}/wp-content/cache/supercache/{HTTP_HOST}/{R:1}/index.html" matchType="IsFile" ignoreCase="false" />
  </conditions>
  <action type="Rewrite" url="/wp-content/cache/supercache/{HTTP_HOST}/{R:1}/index.html" />
</rule>

For gzip content you can use:

<rule name="WP_Super_Cache_rule_2" stopProcessing="true">
  <match url="^(.*)" ignoreCase="false" />
  <conditions logicalGrouping="MatchAll">
    <add input="{URL}" pattern="^.*[^/]$" ignoreCase="false" negate="true" />
    <add input="{URL}" pattern="^.*//.*$" ignoreCase="false" negate="true" />
    <add input="{REQUEST_METHOD}" pattern="POST" ignoreCase="false" negate="true" />
    <add input="{QUERY_STRING}" pattern=".*=.*" ignoreCase="false" negate="true" />
    <add input="{HTTP_COOKIE}" pattern="^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$" ignoreCase="false" negate="true" />
    <add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" ignoreCase="false" />
    <add input="{HTTPS}" pattern="on" ignoreCase="false" negate="true" />
    <add input="{DOCUMENT_ROOT}/wp-content/cache/supercache/{HTTP_HOST}/{R:1}/index.html.gz" matchType="IsFile" />
  </conditions>
  <action type="Rewrite" url="/wp-content/cache/supercache/{HTTP_HOST}/{R:1}/index.html.gz" />
</rule>

Both IIS URL Rewrite Module examples rewrite HTTP requests directly to the static cache files generated by WP-Super-Cache. Thus circumventing WP-Super-Cache's internal redirects, saving processing and time! 🙂 Note that both rules only match plain HTTP requests ({HTTPS} is not on).

For my Dutch site ITFAQ.nl I've written a guide on optimizing .htaccess rewrites for WordPress cache. Just Google Translate it 😉

Running WordPress on IIS? Have a look at my WordPress web.config, and minify WP-Super-Cache HTML cache files for even smaller pages.

Optimizing WordPress with code snippets, the conclusion

Here you found some great WordPress functions.php (or site-specific plugin) code snippets. Snippets I use on a lot of my WordPress sites to optimize and enhance them. I hope you've found them useful.

I write these posts in my spare time, based on real problems from my day job as a sysadmin. If this one saved you some debugging time, a small donation is much appreciated. Thanks! 🙏

Leave a Comment