This is a list of useful WordPress functions that I often reference to enhance or clean up my sites. Please be careful and make backups.
- Hide WordPress Update Nag to All But Admins
- Utilize Proper WordPress Titles
- Create Custom WordPress Dashboard Widget
- Remove All Dashboard Widgets
- Include Navigation Menus
- Insert Custom Login Logo
- Modify Admin Footer Text
- Enqueue Styles and Scripts
- Enqueue Google Fonts
- Modify Excerpt Length
- Change Read More Link
- Change More Excerpt
- Disable Emoji Mess
- Remove Comments
- Change Media Gallery URL
- Create Custom Thumbnail Size
- Add Categories for Attachments
- Add Tags for Attachments
- Add Custom Excerpt to Pages
- Create a Global String
- Support Featured Images
- Support Search Form
- Excluding pages from search
- Disable XMLRPC
- Escape HTML in Posts
- Create Custom Global Settings
- Remove WordPress Admin Bar
- Add Open Graph Meta Tags
- Add Custom Post Type
- Implement Preconnect to Google Fonts in Themes
- Add Thumbnail Column to Post Listing
- Add Lead Class to First Paragraph
- Exclude Custom Post Type from Search
- Remove Query String from Static Resources
- Disable Website Field From Comment Form
- Modify jQuery
- Disable JSON Rest API
- Switch Post Type
- PHP Logger
- Always Show Second Bar in TinyMCE
- Remove Admin Menu Items Depending on User Role
- Remove Admin Menu Items Depending on Email Address (Domain)
- Reorder Admin Menu Items
- Exclude a Category From WordPress Loops
- Disable the message "JQMIGRATE: Migrate is installed, version 1.4.1"
- Load heavy 3rd-party scripts later for better performance
/**
* Hide WordPress update nag to all but admins
*/
function hide_update_notice_to_all_but_admin() {
if ( !current_user_can( 'update_core' ) ) {
remove_action( 'admin_notices', 'update_nag', 3 );
}
}
add_action( 'admin_head', 'hide_update_notice_to_all_but_admin', 1 );
Make sure to remove the <title>
tag from your header.
/**
* Utilize proper WordPress titles
*/
add_theme_support( 'title-tag' );
/**
* Create custom WordPress dashboard widget
*/
function dashboard_widget_function() {
echo '
<h2>Custom Dashboard Widget</h2>
<p>Custom content here</p>
';
}
function add_dashboard_widgets() {
wp_add_dashboard_widget( 'custom_dashboard_widget', 'Custom Dashoard Widget', 'dashboard_widget_function' );
}
add_action( 'wp_dashboard_setup', 'add_dashboard_widgets' );
/**
* Remove all dashboard widgets
*/
function remove_dashboard_widgets() {
global $wp_meta_boxes;
unset( $wp_meta_boxes['dashboard']['side']['core']['dashboard_quick_press'] );
unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_incoming_links'] );
unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'] );
unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_plugins'] );
unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_recent_drafts'] );
unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_recent_comments'] );
unset( $wp_meta_boxes['dashboard']['side']['core']['dashboard_primary'] );
unset( $wp_meta_boxes['dashboard']['side']['core']['dashboard_secondary'] );
remove_meta_box( 'dashboard_activity', 'dashboard', 'normal' );
}
add_action( 'wp_dashboard_setup', 'remove_dashboard_widgets' );
/**
* Include navigation menus
*/
function register_my_menu() {
register_nav_menu( 'nav-menu', __( 'Navigation Menu' ) );
}
add_action( 'init', 'register_my_menu' );
Insert this where you want it to appear, and save the menu in Appearance -> Menus.
wp_nav_menu( array( 'theme_location' => 'nav-menu' ) );
Here's the code for multiple menus:
function register_my_menus() {
register_nav_menus(
array(
'new-menu' => __( 'New Menu' ),
'another-menu' => __( 'Another Menu' ),
'an-extra-menu' => __( 'An Extra Menu' ),
)
);
}
add_action( 'init', 'register_my_menus' );
/**
* Insert custom login logo
*/
function custom_login_logo() {
echo '
<style>
.login h1 a {
background-image: url(image.jpg) !important;
background-size: 234px 67px;
width:234px;
height:67px;
display:block;
}
</style>
';
}
add_action( 'login_head', 'custom_login_logo' );
/**
* Modify admin footer text
*/
function modify_footer() {
echo 'Created by <a href="mailto:[email protected]">you</a>.';
}
add_filter( 'admin_footer_text', 'modify_footer' );
/**
* Enqueue styles and scripts
*/
function custom_scripts() {
wp_enqueue_style( 'bootstrap', get_template_directory_uri() . '/css/bootstrap.min.css', array(), '3.3.6' );
wp_enqueue_style( 'style', get_template_directory_uri() . '/css/style.css' );
wp_enqueue_script( 'bootstrap', get_template_directory_uri() . '/js/bootstrap.min.js', array('jquery'), '3.3.6', true );
wp_enqueue_script( 'script', get_template_directory_uri() . '/js/script.js' );
}
add_action( 'wp_enqueue_scripts', 'custom_scripts' );
/**
* Enqueue Google Fonts
*/
function google_fonts() {
wp_register_style( 'OpenSans', '//fonts.googleapis.com/css?family=Open+Sans:400,600,700,800' );
wp_enqueue_style( 'OpenSans' );
}
add_action( 'wp_print_styles', 'google_fonts' );
/**
* Modify excerpt length
*/
function custom_excerpt_length( $length ) {
return 25;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
/**
* Change Read More link
*/
function custom_read_more_link() {
return '<a href="' . get_permalink() . '">Read More</a>';
}
add_filter( 'the_content_more_link', 'custom_read_more_link' );
/**
* Change More excerpt
*/
function custom_more_excerpt( $more ) {
return '...';
}
add_filter( 'excerpt_more', 'custom_more_excerpt' );
/**
* Disable Emoji mess
*/
function disable_wp_emojicons() {
remove_action( 'admin_print_styles', 'print_emoji_styles' );
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
add_filter( 'tiny_mce_plugins', 'disable_emojicons_tinymce' );
add_filter( 'emoji_svg_url', '__return_false' );
}
add_action( 'init', 'disable_wp_emojicons' );
function disable_emojicons_tinymce( $plugins ) {
return is_array( $plugins ) ? array_diff( $plugins, array( 'wpemoji' ) ) : array();
}
/**
* Remove comments
*/
// Removes from admin menu
function my_remove_admin_menus() {
remove_menu_page( 'edit-comments.php' );
}
add_action( 'admin_menu', 'my_remove_admin_menus' );
// Removes from post and pages
function remove_comment_support() {
remove_post_type_support( 'post', 'comments' );
remove_post_type_support( 'page', 'comments' );
}
add_action( 'init', 'remove_comment_support', 100 );
// Removes from admin bar
function mytheme_admin_bar_render() {
global $wp_admin_bar;
$wp_admin_bar->remove_menu( 'comments' );
}
add_action( 'wp_before_admin_bar_render', 'mytheme_admin_bar_render' );
/**
* Change Media Gallery URL
*/
if ( empty( get_option( 'upload_url_path' ) ) ) {
update_option( 'upload_url_path', 'http://assets.website.com/wp-content/uploads' );
}
Also, you can filter the option value before it's retrieved from the database, which is slightly better:
/**
* Change Media Gallery URL
*/
add_filter( 'pre_option_upload_url_path', function() {
return 'http://assets.website.com/wp-content/uploads';
});
/**
* Create custom thumbnail size
*/
add_image_size( 'custom-thumbnail', 250, 250, true );
Retrieve Thumbnail
$thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'custom-thumbnail' );
echo $thumb[0];
Since WordPress 4.4.0, you can use:
the_post_thumbnail_url( $size );
/**
* Add categories for attachments
*/
function add_categories_for_attachments() {
register_taxonomy_for_object_type( 'category', 'attachment' );
}
add_action( 'init' , 'add_categories_for_attachments' );
/**
* Add tags for attachments
*/
function add_tags_for_attachments() {
register_taxonomy_for_object_type( 'post_tag', 'attachment' );
}
add_action( 'init' , 'add_tags_for_attachments' );
/**
* Add custom excerpt to pages
*/
function add_page_excerpt() {
add_post_type_support( 'page', array( 'excerpt' ) );
}
add_action( 'init', 'add_page_excerpt' );
/**
* Create a global string
*/
function global_string() {
return 'String';
}
Retrieve Field
echo global_string();
/**
* Support featured images
*/
add_theme_support( 'post-thumbnails' );
/**
* Support search form
*/
add_theme_support( 'html5', array( 'search-form' ) );
/**
* Excluding pages from search
*/
function exclude_pages_from_search() {
global $wp_post_types;
$wp_post_types['page']->exclude_from_search = true;
}
add_action( 'init', 'exclude_pages_from_search' );
/**
* Disable xmlrpc.php
*/
add_filter( 'xmlrpc_enabled', '__return_false' );
remove_action( 'wp_head', 'rsd_link' );
remove_action( 'wp_head', 'wlwmanifest_link' );
/**
* Escape HTML in <code> or <pre><code> tags.
*/
function escapeHTML($arr) {
if (version_compare(PHP_VERSION, '5.2.3') >= 0) {
$output = htmlspecialchars($arr[2], ENT_NOQUOTES, get_bloginfo('charset'), false);
}
else {
$specialChars = array(
'&' => '&',
'<' => '<',
'>' => '>'
);
// decode already converted data
$data = htmlspecialchars_decode( $arr[2] );
// escape all data inside <pre>
$output = strtr( $data, $specialChars );
}
if (! empty($output)) {
return $arr[1] . $output . $arr[3];
} else {
return $arr[1] . $arr[2] . $arr[3];
}
}
function filterCode($data) { // Uncomment if you want to escape anything within a <pre> tag
//$modifiedData = preg_replace_callback( '@(<pre.*>)(.*)(<\/pre>)@isU', 'escapeHTML', $data );
$modifiedData = preg_replace_callback( '@(<code.*>)(.*)(<\/code>)@isU', 'escapeHTML', $data );
$modifiedData = preg_replace_callback( '@(<tt.*>)(.*)(<\/tt>)@isU', 'escapeHTML', $modifiedData );
return $modifiedData;
}
add_filter( 'content_save_pre', 'filterCode', 9 );
add_filter( 'excerpt_save_pre', 'filterCode', 9 );
Modified from Escape HTML.
/**
* Create custom global settings
*/
function custom_settings_page() { ?>
<div class="wrap">
<h1>Custom Settings</h1>
<form method="post" action="options.php">
<?php
settings_fields( 'section' );
do_settings_sections( 'theme-options' );
submit_button();
?>
</form>
</div>
<?php }
function custom_settings_add_menu() {
add_theme_page( 'Custom Settings', 'Custom Settings', 'manage_options', 'custom-settings', 'custom_settings_page', null, 99 );
}
add_action( 'admin_menu', 'custom_settings_add_menu' );
// Example setting
function setting_twitter() { ?>
<input type="text" name="twitter" id="twitter" value="<?php echo get_option('twitter'); ?>" />
<?php }
function custom_settings_page_setup() {
add_settings_section( 'section', 'All Settings', null, 'theme-options' );
add_settings_field( 'twitter', 'Twitter Username', 'setting_twitter', 'theme-options', 'section' );
register_setting( 'section', 'twitter' );
}
add_action( 'admin_init', 'custom_settings_page_setup' );
Retrieve Field
echo get_option( 'twitter' );
Modified from Create a WordPress Theme Settings Page with the Settings API.
/**
* Remove WordPress admin bar
*/
function remove_admin_bar() {
remove_action( 'wp_head', '_admin_bar_bump_cb' );
}
add_action( 'get_header', 'remove_admin_bar' );
/**
* Add Open Graph Meta Tags
*/
function meta_og() {
global $post;
if ( is_single() ) {
if( has_post_thumbnail( $post->ID ) ) {
$img_src = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'thumbnail' );
}
$excerpt = strip_tags( $post->post_content );
$excerpt_more = '';
if ( strlen($excerpt ) > 155) {
$excerpt = substr( $excerpt,0,155 );
$excerpt_more = ' ...';
}
$excerpt = str_replace( '"', '', $excerpt );
$excerpt = str_replace( "'", '', $excerpt );
$excerptwords = preg_split( '/[\n\r\t ]+/', $excerpt, -1, PREG_SPLIT_NO_EMPTY );
array_pop( $excerptwords );
$excerpt = implode( ' ', $excerptwords ) . $excerpt_more;
?>
<meta name="author" content="Your Name">
<meta name="description" content="<?php echo $excerpt; ?>">
<meta property="og:title" content="<?php echo the_title(); ?>">
<meta property="og:description" content="<?php echo $excerpt; ?>">
<meta property="og:type" content="article">
<meta property="og:url" content="<?php echo the_permalink(); ?>">
<meta property="og:site_name" content="Your Site Name">
<meta property="og:image" content="<?php echo $img_src[0]; ?>">
<?php
} else {
return;
}
}
add_action('wp_head', 'meta_og', 5);
/**
* Add custom post type
*/
function create_custom_post() {
register_post_type( 'custom-post', // slug for custom post type
array(
'labels' => array(
'name' => __( 'Custom Post' ),
),
'public' => true,
'hierarchical' => true,
'has_archive' => true,
'supports' => array(
'title',
'editor',
'excerpt',
'thumbnail'
),
'can_export' => true,
'taxonomies' => array(
'post_tag',
'category'
)
));
}
add_action('init', 'create_custom_post');
/**
* Implement preconnect to Google Fonts in themes
*/
function twentyfifteen_resource_hints( $urls, $relation_type ) {
// Checks whether the subject is carrying the source of fonts google and the `$relation_type` equals preconnect.
// Replace `enqueue_font_id` the `ID` used in loading the source.
if ( wp_style_is( 'enqueue_font_id', 'queue' ) && 'preconnect' === $relation_type ) {
// Checks whether the version of WordPress is greater than or equal to 4.7
// to ensure compatibility with older versions
// because the 4.7 has become necessary to return an array instead of string
if ( version_compare( $GLOBALS['wp_version'], '4.7-alpha', '>=' ) ) {
// Array with url google fonts and crossorigin
$urls[] = array(
'href' => 'https://fonts.gstatic.com',
'crossorigin',
);
} else {
// String with url google fonts
$urls[] = 'https://fonts.gstatic.com';
}
}
return $urls;
}
add_filter( 'wp_resource_hints', 'twentyfifteen_resource_hints', 10, 2 );
/**
* Add thumbnail column to post listing
*/
add_image_size( 'admin-list-thumb', 80, 80, false );
function wpcs_add_thumbnail_columns( $columns ) {
if ( !is_array( $columns ) )
$columns = array();
$new = array();
foreach( $columns as $key => $title ) {
if ( $key == 'title' ) // Put the Thumbnail column before the Title column
$new['featured_thumb'] = __( 'Image');
$new[$key] = $title;
}
return $new;
}
function wpcs_add_thumbnail_columns_data( $column, $post_id ) {
switch ( $column ) {
case 'featured_thumb':
echo '<a href="' . $post_id . '">';
echo the_post_thumbnail( 'admin-list-thumb' );
echo '</a>';
break;
}
}
if ( function_exists( 'add_theme_support' ) ) {
add_filter( 'manage_posts_columns' , 'wpcs_add_thumbnail_columns' );
add_action( 'manage_posts_custom_column' , 'wpcs_add_thumbnail_columns_data', 10, 2 );
}
/**
* Add lead class to first paragraph
*/
function first_paragraph( $content ) {
return preg_replace( '/<p([^>]+)?>/', '<p$1 class="lead">', $content, 1 );
}
add_filter( 'the_content', 'first_paragraph' );
Adds a lead
class to the first paragraph in the_content.
/**
* Exclude custom post type from search
*/
function excludePages( $query ) {
if ( $query->is_search ) {
$query->set( 'post_type', 'post' );
}
return $query;
}
add_filter( 'pre_get_posts','excludePages' );
/**
* Remove query string from static resources
*/
function remove_cssjs_ver( $src ) {
if ( strpos( $src, '?ver=' ) )
$src = remove_query_arg( 'ver', $src );
return $src;
}
add_filter( 'style_loader_src', 'remove_cssjs_ver', 10, 2 );
add_filter( 'script_loader_src', 'remove_cssjs_ver', 10, 2 );
/**
* Modify jQuery
*/
function modify_jquery() {
wp_deregister_script( 'jquery' );
wp_register_script( 'jquery', 'https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js', false, '3.2.1' );
wp_enqueue_script( 'jquery' );
}
if (!is_admin()) add_action('wp_enqueue_scripts', 'modify_jquery');
/**
* Disable website field from comment form
*/
function disable_website_field( $field ) {
if( isset($field['url']) ) {
unset( $field['url'] );
}
return $field;
}
add_filter('comment_form_default_fields', 'disable_website_field');
/**
* Disable JSON REST API
*/
add_filter('json_enabled', '__return_false');
add_filter('json_jsonp_enabled', '__return_false');
/**
* Switch post type
*/
function switch_post_type ( $old_post_type, $new_post_type ) {
global $wpdb;
// Run the update query
$wpdb->update(
$wpdb->posts,
// Set
array( 'post_type' => $new_post_type),
// Where
array( 'post_type' => $old_post_type )
);
}
/**
* PHP Logger
*/
function php_logger( $data ) {
$output = $data;
if ( is_array( $output ) )
$output = implode( ',', $output );
// print the result into the JavaScript console
echo "<script>console.log( 'PHP LOG: " . $output . "' );</script>";
}
/**
* Always show second bar in TinyMCE
*/
function show_tinymce_toolbar( $in ) {
$in['wordpress_adv_hidden'] = false;
return $in;
}
add_filter( 'tiny_mce_before_init', 'show_tinymce_toolbar' );
/**
* Clone the administrator user role
*/
function clone_admin_role() {
global $wp_roles;
if ( ! isset( $wp_roles ) )
$wp_roles = new WP_Roles();
$adm = $wp_roles->get_role( 'administrator' );
// Add new "Client" role with all admin capabilities
$wp_roles->add_role( 'client', 'Client', $adm->capabilities );
}
add_action( 'init', 'clone_admin_role' );
/**
* Specify which admin menu items are visible for users with role "Client"
*/
function remove_dashboard_menus() {
if ( current_user_can( 'client' ) ) {
// Hide Updates under Dashboard menu
remove_submenu_page( 'index.php', 'update-core.php' );
// Hide Comments
remove_menu_page( 'edit-comments.php' );
// Hide Plugins
remove_menu_page( 'plugins.php' );
// Hide Themes, Customizer and Widgets under Appearance menu
remove_submenu_page( 'themes.php', 'themes.php' );
remove_submenu_page( 'themes.php', 'customize.php?return=' . urlencode( $_SERVER['REQUEST_URI'] ) );
remove_submenu_page( 'themes.php', 'widgets.php' );
// Hide Tools
remove_menu_page( 'tools.php' );
// Hide General Settings
remove_menu_page( 'options-general.php' );
}
}
add_action( 'admin_menu', 'remove_dashboard_menus' );
/**
* Specify which users can see admin menu items based on their email address
*/
function remove_dashboard_menus() {
$user_data = get_userdata( get_current_user_id() );
$user_email = isset( $user_data->user_email ) ? $user_data->user_email : '';
if ( ! strpos( $user_email, '@yourcompany.com' ) ) {
// Hide Updates under Dashboard menu
remove_submenu_page( 'index.php', 'update-core.php' );
// Hide Comments
remove_menu_page( 'edit-comments.php' );
// Hide Plugins
remove_menu_page( 'plugins.php' );
// Hide Themes, Customizer and Widgets under Appearance menu
remove_submenu_page( 'themes.php', 'themes.php' );
remove_submenu_page( 'themes.php', 'customize.php?return=' . urlencode( $_SERVER['REQUEST_URI'] ) );
remove_submenu_page( 'themes.php', 'widgets.php' );
// Hide Tools
remove_menu_page( 'tools.php' );
// Hide General Settings
remove_menu_page( 'options-general.php' );
}
}
add_action( 'admin_menu', 'remove_dashboard_menus' );
/**
* Reorder admin menu
*/
function custom_menu_order( $menu_ord ) {
if ( ! $menu_ord ) { return true; }
return array(
'index.php',
'separator1',
'edit.php?post_type=page',
'edit.php',
'edit.php?post_type=[your_post_type_slug]',
'upload.php',
'edit-comments.php',
'separator2',
'themes.php',
'plugins.php',
'users.php',
'tools.php',
'options-general.php'
);
}
}
add_filter( 'custom_menu_order', 'custom_menu_order' );
add_filter( 'menu_order', 'custom_menu_order' );
/**
* Exclude a category from all WordPress loops
*/
add_action( 'pre_get_posts', function( $query ) { // anonymous callback
global $wp_query;
// Hard coded category ID, but can be dynamic: esc_attr(get_option('your-cat-id'));
$excluded_cat_id = 25;
// add category ID to existing, avoid overwriting it
$cat[] = $query->get( 'cat' );
$cat[] = "-" . $excluded_cat_id;
$query->set( 'cat', $cat );
}
});
add_action('wp_default_scripts', function ($scripts) {
if (!empty($scripts->registered['jquery'])) {
$scripts->registered['jquery']->deps = array_diff($scripts->registered['jquery']->deps, ['jquery-migrate']);
}
});
Lighthouse and similar performance analysis tools always complain about render-blocking scripts (and styles), short cache TTL etc. Most of these scripts and styles come from 3rd-party sources which we can't control – Google's own Tag Manager and Analytics, Facebook Pixel, other trackers and chat scripts etc. However, we can load them only when a real user interacts with a page, significantly reducing the Time To Interactive metric and scoring much higher performance results.
Depending on where you like these 3rd-party scripts to be, you can either use wp_footer
action to print the
code in footer, or put it in your main app.js
script which, in turn, is enqueued on wp_enqueue_scripts
action.
<script>
var fired = false;
window.addEventListener('scroll', () => {
if (fired === false) {
fired = true;
setTimeout(() => {
// Marketing scripts go here.
}, 1000) // 1000ms or 1s works fine, but you can adjust this timeout.
}
});
</script>