├── LICENSE.md └── README.md /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Tania Rascia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Useful WordPress Functions 2 | 3 | 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. 4 | 5 | - [Hide WordPress Update Nag to All But Admins](#hide-wordpress-update-nag-to-all-but-admins) 6 | - [Utilize Proper WordPress Titles](#utilize-proper-wordpress-titles) 7 | - [Create Custom WordPress Dashboard Widget](#create-custom-wordpress-dashboard-widget) 8 | - [Remove All Dashboard Widgets](#remove-all-dashboard-widgets) 9 | - [Include Navigation Menus](#include-navigation-menus) 10 | - [Insert Custom Login Logo](#insert-custom-login-logo) 11 | - [Modify Admin Footer Text](#modify-admin-footer-text) 12 | - [Enqueue Styles and Scripts](#enqueue-styles-and-scripts) 13 | - [Enqueue Google Fonts](#enqueue-google-fonts) 14 | - [Modify Excerpt Length](#modify-excerpt-length) 15 | - [Change Read More Link](#change-read-more-link) 16 | - [Change More Excerpt](#change-more-excerpt) 17 | - [Disable Emoji Mess](#disable-emoji-mess) 18 | - [Remove Comments](#remove-comments) 19 | - [Change Media Gallery URL](#change-media-gallery-url) 20 | - [Create Custom Thumbnail Size](#create-custom-thumbnail-size) 21 | - [Add Categories for Attachments](#add-categories-for-attachments) 22 | - [Add Tags for Attachments](#add-tags-for-attachments) 23 | - [Add Custom Excerpt to Pages](#add-custom-excerpt-to-pages) 24 | - [Create a Global String](#create-a-global-string) 25 | - [Support Featured Images](#support-featured-images) 26 | - [Support Search Form](#support-search-form) 27 | - [Excluding pages from search](#excluding-pages-from-search) 28 | - [Disable XMLRPC](#disable-xmlrpcphp) 29 | - [Escape HTML in Posts](#escape-html-in-posts) 30 | - [Create Custom Global Settings](#create-custom-global-settings) 31 | - [Remove WordPress Admin Bar](#remove-wordpress-admin-bar) 32 | - [Add Open Graph Meta Tags](#add-open-graph-meta-tags) 33 | - [Add Custom Post Type](#add-custom-post-type) 34 | - [Implement Preconnect to Google Fonts in Themes](#implement-preconnect-to-google-fonts-in-themes) 35 | - [Add Thumbnail Column to Post Listing](#add-thumbnail-column-to-post-listing) 36 | - [Add Lead Class to First Paragraph](#add-lead-class-to-first-paragraph) 37 | - [Exclude Custom Post Type from Search](#exclude-custom-post-type-from-search) 38 | - [Remove Query String from Static Resources](#remove-query-string-from-static-resources) 39 | - [Disable Website Field From Comment Form](#disable-website-field-from-comment-form) 40 | - [Modify jQuery](#modify-jquery) 41 | - [Disable JSON Rest API](#disable-json-rest-api) 42 | - [Switch Post Type](#switch-post-type) 43 | - [PHP Logger](#php-logger) 44 | - [Always Show Second Bar in TinyMCE](#always-show-second-bar-in-tinymce) 45 | - [Remove Admin Menu Items Depending on User Role](#remove-admin-menu-items-depending-on-user-role) 46 | - [Remove Admin Menu Items Depending on Email Address (Domain)](#remove-admin-menu-items-depending-on-email-address-domain) 47 | - [Reorder Admin Menu Items](#reorder-admin-menu-items) 48 | - [Exclude a Category From WordPress Loops](#exclude-a-category-from-wordpress-loops) 49 | - [Disable the message "JQMIGRATE: Migrate is installed, version 1.4.1"](#user-content-disable-the-message---jqmigrate-migrate-is-installed-version-141) 50 | - [Load heavy 3rd-party scripts later for better performance](#load-heavy-3rd-party-scripts-later-for-better-performance) 51 | 52 | ## Hide WordPress Update Nag to All But Admins 53 | 54 | ```php 55 | /** 56 | * Hide WordPress update nag to all but admins 57 | */ 58 | 59 | function hide_update_notice_to_all_but_admin() { 60 | if ( !current_user_can( 'update_core' ) ) { 61 | remove_action( 'admin_notices', 'update_nag', 3 ); 62 | } 63 | } 64 | add_action( 'admin_head', 'hide_update_notice_to_all_but_admin', 1 ); 65 | ``` 66 | 67 | ## Utilize Proper WordPress Titles 68 | 69 | Make sure to remove the `` tag from your header. 70 | 71 | ```php 72 | /** 73 | * Utilize proper WordPress titles 74 | */ 75 | 76 | add_theme_support( 'title-tag' ); 77 | ``` 78 | 79 | ## Create Custom WordPress Dashboard Widget 80 | 81 | ```php 82 | /** 83 | * Create custom WordPress dashboard widget 84 | */ 85 | 86 | function dashboard_widget_function() { 87 | echo ' 88 | <h2>Custom Dashboard Widget</h2> 89 | <p>Custom content here</p> 90 | '; 91 | } 92 | 93 | function add_dashboard_widgets() { 94 | wp_add_dashboard_widget( 'custom_dashboard_widget', 'Custom Dashoard Widget', 'dashboard_widget_function' ); 95 | } 96 | add_action( 'wp_dashboard_setup', 'add_dashboard_widgets' ); 97 | ``` 98 | 99 | ## Remove All Dashboard Widgets 100 | 101 | ```php 102 | /** 103 | * Remove all dashboard widgets 104 | */ 105 | 106 | function remove_dashboard_widgets() { 107 | global $wp_meta_boxes; 108 | 109 | unset( $wp_meta_boxes['dashboard']['side']['core']['dashboard_quick_press'] ); 110 | unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_incoming_links'] ); 111 | unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'] ); 112 | unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_plugins'] ); 113 | unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_recent_drafts'] ); 114 | unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_recent_comments'] ); 115 | unset( $wp_meta_boxes['dashboard']['side']['core']['dashboard_primary'] ); 116 | unset( $wp_meta_boxes['dashboard']['side']['core']['dashboard_secondary'] ); 117 | 118 | remove_meta_box( 'dashboard_activity', 'dashboard', 'normal' ); 119 | } 120 | add_action( 'wp_dashboard_setup', 'remove_dashboard_widgets' ); 121 | ``` 122 | 123 | ## Include Navigation Menus 124 | 125 | ```php 126 | /** 127 | * Include navigation menus 128 | */ 129 | 130 | function register_my_menu() { 131 | register_nav_menu( 'nav-menu', __( 'Navigation Menu' ) ); 132 | } 133 | add_action( 'init', 'register_my_menu' ); 134 | ``` 135 | 136 | Insert this where you want it to appear, and save the menu in **Appearance -> Menus**. 137 | 138 | ```php 139 | wp_nav_menu( array( 'theme_location' => 'nav-menu' ) ); 140 | ``` 141 | 142 | Here's the code for multiple menus: 143 | 144 | ```php 145 | function register_my_menus() { 146 | register_nav_menus( 147 | array( 148 | 'new-menu' => __( 'New Menu' ), 149 | 'another-menu' => __( 'Another Menu' ), 150 | 'an-extra-menu' => __( 'An Extra Menu' ), 151 | ) 152 | ); 153 | } 154 | add_action( 'init', 'register_my_menus' ); 155 | ``` 156 | 157 | ## Insert Custom Login Logo 158 | 159 | ```php 160 | /** 161 | * Insert custom login logo 162 | */ 163 | 164 | function custom_login_logo() { 165 | echo ' 166 | <style> 167 | .login h1 a { 168 | background-image: url(image.jpg) !important; 169 | background-size: 234px 67px; 170 | width:234px; 171 | height:67px; 172 | display:block; 173 | } 174 | </style> 175 | '; 176 | } 177 | add_action( 'login_head', 'custom_login_logo' ); 178 | ``` 179 | 180 | ## Modify Admin Footer Text 181 | 182 | ```php 183 | /** 184 | * Modify admin footer text 185 | */ 186 | 187 | function modify_footer() { 188 | echo 'Created by <a href="mailto:you@example.com">you</a>.'; 189 | } 190 | add_filter( 'admin_footer_text', 'modify_footer' ); 191 | ``` 192 | 193 | ## Enqueue Styles and Scripts 194 | 195 | ```php 196 | /** 197 | * Enqueue styles and scripts 198 | */ 199 | 200 | function custom_scripts() { 201 | wp_enqueue_style( 'bootstrap', get_template_directory_uri() . '/css/bootstrap.min.css', array(), '3.3.6' ); 202 | wp_enqueue_style( 'style', get_template_directory_uri() . '/css/style.css' ); 203 | wp_enqueue_script( 'bootstrap', get_template_directory_uri() . '/js/bootstrap.min.js', array('jquery'), '3.3.6', true ); 204 | wp_enqueue_script( 'script', get_template_directory_uri() . '/js/script.js' ); 205 | } 206 | add_action( 'wp_enqueue_scripts', 'custom_scripts' ); 207 | ``` 208 | 209 | ## Enqueue Google Fonts 210 | 211 | ```php 212 | /** 213 | * Enqueue Google Fonts 214 | */ 215 | 216 | function google_fonts() { 217 | wp_register_style( 'OpenSans', '//fonts.googleapis.com/css?family=Open+Sans:400,600,700,800' ); 218 | wp_enqueue_style( 'OpenSans' ); 219 | } 220 | add_action( 'wp_print_styles', 'google_fonts' ); 221 | ``` 222 | 223 | ## Modify Excerpt Length 224 | 225 | ```php 226 | /** 227 | * Modify excerpt length 228 | */ 229 | 230 | function custom_excerpt_length( $length ) { 231 | return 25; 232 | } 233 | add_filter( 'excerpt_length', 'custom_excerpt_length', 999 ); 234 | ``` 235 | 236 | ## Change Read More Link 237 | 238 | ```php 239 | /** 240 | * Change Read More link 241 | */ 242 | 243 | function custom_read_more_link() { 244 | return '<a href="' . get_permalink() . '">Read More</a>'; 245 | } 246 | add_filter( 'the_content_more_link', 'custom_read_more_link' ); 247 | ``` 248 | 249 | ## Change More Excerpt 250 | 251 | ```php 252 | /** 253 | * Change More excerpt 254 | */ 255 | 256 | function custom_more_excerpt( $more ) { 257 | return '...'; 258 | } 259 | add_filter( 'excerpt_more', 'custom_more_excerpt' ); 260 | ``` 261 | 262 | ## Disable Emoji Mess 263 | 264 | ```php 265 | /** 266 | * Disable Emoji mess 267 | */ 268 | 269 | function disable_wp_emojicons() { 270 | remove_action( 'admin_print_styles', 'print_emoji_styles' ); 271 | remove_action( 'wp_head', 'print_emoji_detection_script', 7 ); 272 | remove_action( 'admin_print_scripts', 'print_emoji_detection_script' ); 273 | remove_action( 'wp_print_styles', 'print_emoji_styles' ); 274 | remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' ); 275 | remove_filter( 'the_content_feed', 'wp_staticize_emoji' ); 276 | remove_filter( 'comment_text_rss', 'wp_staticize_emoji' ); 277 | add_filter( 'tiny_mce_plugins', 'disable_emojicons_tinymce' ); 278 | add_filter( 'emoji_svg_url', '__return_false' ); 279 | } 280 | add_action( 'init', 'disable_wp_emojicons' ); 281 | 282 | function disable_emojicons_tinymce( $plugins ) { 283 | return is_array( $plugins ) ? array_diff( $plugins, array( 'wpemoji' ) ) : array(); 284 | } 285 | ``` 286 | 287 | ## Remove Comments 288 | 289 | ```php 290 | /** 291 | * Remove comments 292 | */ 293 | 294 | // Removes from admin menu 295 | 296 | function my_remove_admin_menus() { 297 | remove_menu_page( 'edit-comments.php' ); 298 | } 299 | add_action( 'admin_menu', 'my_remove_admin_menus' ); 300 | 301 | // Removes from post and pages 302 | function remove_comment_support() { 303 | remove_post_type_support( 'post', 'comments' ); 304 | remove_post_type_support( 'page', 'comments' ); 305 | } 306 | add_action( 'init', 'remove_comment_support', 100 ); 307 | 308 | // Removes from admin bar 309 | function mytheme_admin_bar_render() { 310 | global $wp_admin_bar; 311 | 312 | $wp_admin_bar->remove_menu( 'comments' ); 313 | } 314 | add_action( 'wp_before_admin_bar_render', 'mytheme_admin_bar_render' ); 315 | ``` 316 | 317 | ## Change Media Gallery URL 318 | 319 | ```php 320 | /** 321 | * Change Media Gallery URL 322 | */ 323 | 324 | if ( empty( get_option( 'upload_url_path' ) ) ) { 325 | update_option( 'upload_url_path', 'http://assets.website.com/wp-content/uploads' ); 326 | } 327 | ``` 328 | 329 | Also, you can filter the option value before it's retrieved from the database, which is slightly better: 330 | 331 | ```php 332 | /** 333 | * Change Media Gallery URL 334 | */ 335 | 336 | add_filter( 'pre_option_upload_url_path', function() { 337 | return 'http://assets.website.com/wp-content/uploads'; 338 | }); 339 | ``` 340 | 341 | ## Create Custom Thumbnail Size 342 | 343 | ```php 344 | /** 345 | * Create custom thumbnail size 346 | */ 347 | 348 | add_image_size( 'custom-thumbnail', 250, 250, true ); 349 | ``` 350 | 351 | **Retrieve Thumbnail** 352 | 353 | ```php 354 | $thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'custom-thumbnail' ); 355 | 356 | echo $thumb[0]; 357 | ``` 358 | 359 | Since WordPress 4.4.0, you can use: 360 | 361 | ```php 362 | the_post_thumbnail_url( $size ); 363 | ``` 364 | 365 | ## Add Categories for Attachments 366 | 367 | ```php 368 | /** 369 | * Add categories for attachments 370 | */ 371 | 372 | function add_categories_for_attachments() { 373 | register_taxonomy_for_object_type( 'category', 'attachment' ); 374 | } 375 | add_action( 'init' , 'add_categories_for_attachments' ); 376 | ``` 377 | 378 | ## Add Tags for Attachments 379 | 380 | ```php 381 | /** 382 | * Add tags for attachments 383 | */ 384 | 385 | function add_tags_for_attachments() { 386 | register_taxonomy_for_object_type( 'post_tag', 'attachment' ); 387 | } 388 | add_action( 'init' , 'add_tags_for_attachments' ); 389 | ``` 390 | 391 | ## Add Custom Excerpt to Pages 392 | 393 | ```php 394 | /** 395 | * Add custom excerpt to pages 396 | */ 397 | 398 | function add_page_excerpt() { 399 | add_post_type_support( 'page', array( 'excerpt' ) ); 400 | } 401 | add_action( 'init', 'add_page_excerpt' ); 402 | ``` 403 | 404 | ## Create a Global String 405 | 406 | ```php 407 | /** 408 | * Create a global string 409 | */ 410 | 411 | function global_string() { 412 | return 'String'; 413 | } 414 | ``` 415 | 416 | **Retrieve Field** 417 | 418 | ```php 419 | echo global_string(); 420 | ``` 421 | 422 | ## Support Featured Images 423 | 424 | ```php 425 | /** 426 | * Support featured images 427 | */ 428 | 429 | add_theme_support( 'post-thumbnails' ); 430 | ``` 431 | 432 | ## Support Search Form 433 | 434 | ```php 435 | /** 436 | * Support search form 437 | */ 438 | 439 | add_theme_support( 'html5', array( 'search-form' ) ); 440 | ``` 441 | 442 | ## Excluding Pages From Search 443 | 444 | ```php 445 | /** 446 | * Excluding pages from search 447 | */ 448 | 449 | function exclude_pages_from_search() { 450 | global $wp_post_types; 451 | 452 | $wp_post_types['page']->exclude_from_search = true; 453 | } 454 | add_action( 'init', 'exclude_pages_from_search' ); 455 | ``` 456 | 457 | ## Disable xmlrpc.php 458 | 459 | ```php 460 | /** 461 | * Disable xmlrpc.php 462 | */ 463 | 464 | add_filter( 'xmlrpc_enabled', '__return_false' ); 465 | remove_action( 'wp_head', 'rsd_link' ); 466 | remove_action( 'wp_head', 'wlwmanifest_link' ); 467 | ``` 468 | 469 | ## Escape HTML in Posts 470 | 471 | ```php 472 | /** 473 | * Escape HTML in <code> or <pre><code> tags. 474 | */ 475 | 476 | function escapeHTML($arr) { 477 | if (version_compare(PHP_VERSION, '5.2.3') >= 0) { 478 | $output = htmlspecialchars($arr[2], ENT_NOQUOTES, get_bloginfo('charset'), false); 479 | } 480 | else { 481 | $specialChars = array( 482 | '&' => '&', 483 | '<' => '<', 484 | '>' => '>' 485 | ); 486 | 487 | // decode already converted data 488 | $data = htmlspecialchars_decode( $arr[2] ); 489 | // escape all data inside <pre> 490 | $output = strtr( $data, $specialChars ); 491 | } 492 | if (! empty($output)) { 493 | return $arr[1] . $output . $arr[3]; 494 | } else { 495 | return $arr[1] . $arr[2] . $arr[3]; 496 | } 497 | } 498 | function filterCode($data) { // Uncomment if you want to escape anything within a <pre> tag 499 | //$modifiedData = preg_replace_callback( '@(<pre.*>)(.*)(<\/pre>)@isU', 'escapeHTML', $data ); 500 | $modifiedData = preg_replace_callback( '@(<code.*>)(.*)(<\/code>)@isU', 'escapeHTML', $data ); 501 | $modifiedData = preg_replace_callback( '@(<tt.*>)(.*)(<\/tt>)@isU', 'escapeHTML', $modifiedData ); 502 | 503 | return $modifiedData; 504 | } 505 | add_filter( 'content_save_pre', 'filterCode', 9 ); 506 | add_filter( 'excerpt_save_pre', 'filterCode', 9 ); 507 | ``` 508 | 509 | Modified from [Escape HTML](https://wordpress.org/plugins/escape-html/). 510 | 511 | ## Create Custom Global Settings 512 | 513 | ```php 514 | /** 515 | * Create custom global settings 516 | */ 517 | 518 | function custom_settings_page() { ?> 519 | <div class="wrap"> 520 | <h1>Custom Settings</h1> 521 | <form method="post" action="options.php"> 522 | <?php 523 | settings_fields( 'section' ); 524 | do_settings_sections( 'theme-options' ); 525 | submit_button(); 526 | ?> 527 | </form> 528 | </div> 529 | <?php } 530 | 531 | function custom_settings_add_menu() { 532 | add_theme_page( 'Custom Settings', 'Custom Settings', 'manage_options', 'custom-settings', 'custom_settings_page', null, 99 ); 533 | } 534 | add_action( 'admin_menu', 'custom_settings_add_menu' ); 535 | 536 | // Example setting 537 | function setting_twitter() { ?> 538 | <input type="text" name="twitter" id="twitter" value="<?php echo get_option('twitter'); ?>" /> 539 | <?php } 540 | 541 | function custom_settings_page_setup() { 542 | add_settings_section( 'section', 'All Settings', null, 'theme-options' ); 543 | add_settings_field( 'twitter', 'Twitter Username', 'setting_twitter', 'theme-options', 'section' ); 544 | register_setting( 'section', 'twitter' ); 545 | } 546 | add_action( 'admin_init', 'custom_settings_page_setup' ); 547 | ``` 548 | 549 | Retrieve Field 550 | 551 | ```php 552 | echo get_option( 'twitter' ); 553 | ``` 554 | 555 | Modified from [Create a WordPress Theme Settings Page with the Settings API](http://www.sitepoint.com/create-a-wordpress-theme-settings-page-with-the-settings-api/). 556 | 557 | ## Remove WordPress Admin Bar 558 | 559 | ```php 560 | /** 561 | * Remove WordPress admin bar 562 | */ 563 | 564 | function remove_admin_bar() { 565 | remove_action( 'wp_head', '_admin_bar_bump_cb' ); 566 | } 567 | add_action( 'get_header', 'remove_admin_bar' ); 568 | ``` 569 | 570 | ## Add Open Graph Meta Tags 571 | 572 | ```php 573 | /** 574 | * Add Open Graph Meta Tags 575 | */ 576 | 577 | function meta_og() { 578 | global $post; 579 | 580 | if ( is_single() ) { 581 | if( has_post_thumbnail( $post->ID ) ) { 582 | $img_src = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'thumbnail' ); 583 | } 584 | $excerpt = strip_tags( $post->post_content ); 585 | $excerpt_more = ''; 586 | if ( strlen($excerpt ) > 155) { 587 | $excerpt = substr( $excerpt,0,155 ); 588 | $excerpt_more = ' ...'; 589 | } 590 | $excerpt = str_replace( '"', '', $excerpt ); 591 | $excerpt = str_replace( "'", '', $excerpt ); 592 | $excerptwords = preg_split( '/[\n\r\t ]+/', $excerpt, -1, PREG_SPLIT_NO_EMPTY ); 593 | array_pop( $excerptwords ); 594 | $excerpt = implode( ' ', $excerptwords ) . $excerpt_more; 595 | ?> 596 | <meta name="author" content="Your Name"> 597 | <meta name="description" content="<?php echo $excerpt; ?>"> 598 | <meta property="og:title" content="<?php echo the_title(); ?>"> 599 | <meta property="og:description" content="<?php echo $excerpt; ?>"> 600 | <meta property="og:type" content="article"> 601 | <meta property="og:url" content="<?php echo the_permalink(); ?>"> 602 | <meta property="og:site_name" content="Your Site Name"> 603 | <meta property="og:image" content="<?php echo $img_src[0]; ?>"> 604 | <?php 605 | } else { 606 | return; 607 | } 608 | } 609 | add_action('wp_head', 'meta_og', 5); 610 | ``` 611 | 612 | ## Add Custom Post Type 613 | 614 | ```php 615 | /** 616 | * Add custom post type 617 | */ 618 | 619 | function create_custom_post() { 620 | register_post_type( 'custom-post', // slug for custom post type 621 | array( 622 | 'labels' => array( 623 | 'name' => __( 'Custom Post' ), 624 | ), 625 | 'public' => true, 626 | 'hierarchical' => true, 627 | 'has_archive' => true, 628 | 'supports' => array( 629 | 'title', 630 | 'editor', 631 | 'excerpt', 632 | 'thumbnail' 633 | ), 634 | 'can_export' => true, 635 | 'taxonomies' => array( 636 | 'post_tag', 637 | 'category' 638 | ) 639 | )); 640 | } 641 | add_action('init', 'create_custom_post'); 642 | ``` 643 | 644 | ## Implement Preconnect to Google Fonts in Themes 645 | 646 | ```php 647 | /** 648 | * Implement preconnect to Google Fonts in themes 649 | */ 650 | 651 | function twentyfifteen_resource_hints( $urls, $relation_type ) { 652 | // Checks whether the subject is carrying the source of fonts google and the `$relation_type` equals preconnect. 653 | // Replace `enqueue_font_id` the `ID` used in loading the source. 654 | if ( wp_style_is( 'enqueue_font_id', 'queue' ) && 'preconnect' === $relation_type ) { 655 | // Checks whether the version of WordPress is greater than or equal to 4.7 656 | // to ensure compatibility with older versions 657 | // because the 4.7 has become necessary to return an array instead of string 658 | if ( version_compare( $GLOBALS['wp_version'], '4.7-alpha', '>=' ) ) { 659 | // Array with url google fonts and crossorigin 660 | $urls[] = array( 661 | 'href' => 'https://fonts.gstatic.com', 662 | 'crossorigin', 663 | ); 664 | } else { 665 | // String with url google fonts 666 | $urls[] = 'https://fonts.gstatic.com'; 667 | } 668 | } 669 | return $urls; 670 | } 671 | add_filter( 'wp_resource_hints', 'twentyfifteen_resource_hints', 10, 2 ); 672 | ``` 673 | 674 | ## Add Thumbnail Column to Post Listing 675 | 676 | ```php 677 | /** 678 | * Add thumbnail column to post listing 679 | */ 680 | 681 | add_image_size( 'admin-list-thumb', 80, 80, false ); 682 | 683 | function wpcs_add_thumbnail_columns( $columns ) { 684 | 685 | if ( !is_array( $columns ) ) 686 | $columns = array(); 687 | $new = array(); 688 | 689 | foreach( $columns as $key => $title ) { 690 | if ( $key == 'title' ) // Put the Thumbnail column before the Title column 691 | $new['featured_thumb'] = __( 'Image'); 692 | $new[$key] = $title; 693 | } 694 | return $new; 695 | } 696 | 697 | function wpcs_add_thumbnail_columns_data( $column, $post_id ) { 698 | switch ( $column ) { 699 | case 'featured_thumb': 700 | echo '<a href="' . $post_id . '">'; 701 | echo the_post_thumbnail( 'admin-list-thumb' ); 702 | echo '</a>'; 703 | break; 704 | } 705 | } 706 | 707 | if ( function_exists( 'add_theme_support' ) ) { 708 | add_filter( 'manage_posts_columns' , 'wpcs_add_thumbnail_columns' ); 709 | add_action( 'manage_posts_custom_column' , 'wpcs_add_thumbnail_columns_data', 10, 2 ); 710 | } 711 | ``` 712 | ## Add Lead Class to First Paragraph 713 | 714 | ```php 715 | /** 716 | * Add lead class to first paragraph 717 | */ 718 | 719 | function first_paragraph( $content ) { 720 | return preg_replace( '/<p([^>]+)?>/', '<p$1 class="lead">', $content, 1 ); 721 | } 722 | add_filter( 'the_content', 'first_paragraph' ); 723 | ``` 724 | 725 | Adds a `lead` class to the first paragraph in [the_content](https://developer.wordpress.org/reference/functions/the_content/). 726 | 727 | ## Exclude Custom Post Type from Search 728 | 729 | ```php 730 | /** 731 | * Exclude custom post type from search 732 | */ 733 | 734 | function excludePages( $query ) { 735 | if ( $query->is_search ) { 736 | $query->set( 'post_type', 'post' ); 737 | } 738 | return $query; 739 | } 740 | add_filter( 'pre_get_posts','excludePages' ); 741 | ``` 742 | 743 | ## Remove Query String from Static Resources 744 | 745 | ```php 746 | /** 747 | * Remove query string from static resources 748 | */ 749 | 750 | function remove_cssjs_ver( $src ) { 751 | if ( strpos( $src, '?ver=' ) ) 752 | $src = remove_query_arg( 'ver', $src ); 753 | return $src; 754 | } 755 | add_filter( 'style_loader_src', 'remove_cssjs_ver', 10, 2 ); 756 | add_filter( 'script_loader_src', 'remove_cssjs_ver', 10, 2 ); 757 | ``` 758 | 759 | ## Modify jQuery 760 | 761 | ```php 762 | /** 763 | * Modify jQuery 764 | */ 765 | 766 | function modify_jquery() { 767 | wp_deregister_script( 'jquery' ); 768 | wp_register_script( 'jquery', 'https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js', false, '3.2.1' ); 769 | wp_enqueue_script( 'jquery' ); 770 | } 771 | if (!is_admin()) add_action('wp_enqueue_scripts', 'modify_jquery'); 772 | ``` 773 | 774 | ## Disable Website Field From Comment Form 775 | 776 | ```php 777 | /** 778 | * Disable website field from comment form 779 | */ 780 | 781 | function disable_website_field( $field ) { 782 | if( isset($field['url']) ) { 783 | unset( $field['url'] ); 784 | } 785 | return $field; 786 | } 787 | add_filter('comment_form_default_fields', 'disable_website_field'); 788 | ``` 789 | 790 | ## Disable JSON REST API 791 | 792 | ```php 793 | /** 794 | * Disable JSON REST API 795 | */ 796 | 797 | add_filter('json_enabled', '__return_false'); 798 | add_filter('json_jsonp_enabled', '__return_false'); 799 | ``` 800 | 801 | ## Switch Post Type 802 | 803 | ```php 804 | /** 805 | * Switch post type 806 | */ 807 | 808 | function switch_post_type ( $old_post_type, $new_post_type ) { 809 | global $wpdb; 810 | 811 | // Run the update query 812 | $wpdb->update( 813 | $wpdb->posts, 814 | // Set 815 | array( 'post_type' => $new_post_type), 816 | // Where 817 | array( 'post_type' => $old_post_type ) 818 | ); 819 | } 820 | ``` 821 | 822 | ## PHP Logger 823 | 824 | ```php 825 | /** 826 | * PHP Logger 827 | */ 828 | 829 | function php_logger( $data ) { 830 | $output = $data; 831 | if ( is_array( $output ) ) 832 | $output = implode( ',', $output ); 833 | 834 | // print the result into the JavaScript console 835 | echo "<script>console.log( 'PHP LOG: " . $output . "' );</script>"; 836 | } 837 | ``` 838 | 839 | ## Always Show Second Bar in TinyMCE 840 | 841 | ```php 842 | /** 843 | * Always show second bar in TinyMCE 844 | */ 845 | 846 | function show_tinymce_toolbar( $in ) { 847 | $in['wordpress_adv_hidden'] = false; 848 | return $in; 849 | } 850 | add_filter( 'tiny_mce_before_init', 'show_tinymce_toolbar' ); 851 | ``` 852 | 853 | ## Remove Admin Menu Items Depending on User Role 854 | 855 | ```php 856 | /** 857 | * Clone the administrator user role 858 | */ 859 | 860 | function clone_admin_role() { 861 | global $wp_roles; 862 | if ( ! isset( $wp_roles ) ) 863 | $wp_roles = new WP_Roles(); 864 | 865 | $adm = $wp_roles->get_role( 'administrator' ); 866 | 867 | // Add new "Client" role with all admin capabilities 868 | $wp_roles->add_role( 'client', 'Client', $adm->capabilities ); 869 | } 870 | add_action( 'init', 'clone_admin_role' ); 871 | 872 | /** 873 | * Specify which admin menu items are visible for users with role "Client" 874 | */ 875 | 876 | function remove_dashboard_menus() { 877 | if ( current_user_can( 'client' ) ) { 878 | // Hide Updates under Dashboard menu 879 | remove_submenu_page( 'index.php', 'update-core.php' ); 880 | 881 | // Hide Comments 882 | remove_menu_page( 'edit-comments.php' ); 883 | 884 | // Hide Plugins 885 | remove_menu_page( 'plugins.php' ); 886 | 887 | // Hide Themes, Customizer and Widgets under Appearance menu 888 | remove_submenu_page( 'themes.php', 'themes.php' ); 889 | remove_submenu_page( 'themes.php', 'customize.php?return=' . urlencode( $_SERVER['REQUEST_URI'] ) ); 890 | remove_submenu_page( 'themes.php', 'widgets.php' ); 891 | 892 | // Hide Tools 893 | remove_menu_page( 'tools.php' ); 894 | 895 | // Hide General Settings 896 | remove_menu_page( 'options-general.php' ); 897 | } 898 | } 899 | add_action( 'admin_menu', 'remove_dashboard_menus' ); 900 | ``` 901 | 902 | ## Remove Admin Menu Items Depending on Email Address (domain) 903 | 904 | ```php 905 | /** 906 | * Specify which users can see admin menu items based on their email address 907 | */ 908 | 909 | function remove_dashboard_menus() { 910 | $user_data = get_userdata( get_current_user_id() ); 911 | $user_email = isset( $user_data->user_email ) ? $user_data->user_email : ''; 912 | 913 | if ( ! strpos( $user_email, '@yourcompany.com' ) ) { 914 | // Hide Updates under Dashboard menu 915 | remove_submenu_page( 'index.php', 'update-core.php' ); 916 | 917 | // Hide Comments 918 | remove_menu_page( 'edit-comments.php' ); 919 | 920 | // Hide Plugins 921 | remove_menu_page( 'plugins.php' ); 922 | 923 | // Hide Themes, Customizer and Widgets under Appearance menu 924 | remove_submenu_page( 'themes.php', 'themes.php' ); 925 | remove_submenu_page( 'themes.php', 'customize.php?return=' . urlencode( $_SERVER['REQUEST_URI'] ) ); 926 | remove_submenu_page( 'themes.php', 'widgets.php' ); 927 | 928 | // Hide Tools 929 | remove_menu_page( 'tools.php' ); 930 | 931 | // Hide General Settings 932 | remove_menu_page( 'options-general.php' ); 933 | } 934 | } 935 | add_action( 'admin_menu', 'remove_dashboard_menus' ); 936 | ``` 937 | 938 | ## Reorder Admin Menu Items 939 | 940 | ```php 941 | /** 942 | * Reorder admin menu 943 | */ 944 | 945 | function custom_menu_order( $menu_ord ) { 946 | if ( ! $menu_ord ) { return true; } 947 | return array( 948 | 'index.php', 949 | 'separator1', 950 | 'edit.php?post_type=page', 951 | 'edit.php', 952 | 'edit.php?post_type=[your_post_type_slug]', 953 | 'upload.php', 954 | 'edit-comments.php', 955 | 'separator2', 956 | 'themes.php', 957 | 'plugins.php', 958 | 'users.php', 959 | 'tools.php', 960 | 'options-general.php' 961 | ); 962 | } 963 | } 964 | add_filter( 'custom_menu_order', 'custom_menu_order' ); 965 | add_filter( 'menu_order', 'custom_menu_order' ); 966 | ``` 967 | 968 | ## Exclude a Category From WordPress Loops 969 | 970 | ```php 971 | /** 972 | * Exclude a category from all WordPress loops 973 | */ 974 | 975 | add_action( 'pre_get_posts', function( $query ) { // anonymous callback 976 | 977 | global $wp_query; 978 | 979 | // Hard coded category ID, but can be dynamic: esc_attr(get_option('your-cat-id')); 980 | $excluded_cat_id = 25; 981 | 982 | // add category ID to existing, avoid overwriting it 983 | $cat[] = $query->get( 'cat' ); 984 | $cat[] = "-" . $excluded_cat_id; 985 | 986 | $query->set( 'cat', $cat ); 987 | } 988 | }); 989 | ``` 990 | 991 | ## Disable the message - JQMIGRATE: Migrate is installed, version 1.4.1 992 | 993 | ```php 994 | add_action('wp_default_scripts', function ($scripts) { 995 | if (!empty($scripts->registered['jquery'])) { 996 | $scripts->registered['jquery']->deps = array_diff($scripts->registered['jquery']->deps, ['jquery-migrate']); 997 | } 998 | }); 999 | ``` 1000 | 1001 | ## Load heavy 3rd-party scripts later for better performance 1002 | 1003 | Lighthouse and similar performance analysis tools always complain about render-blocking scripts (and styles), 1004 | short cache TTL etc. Most of these scripts and styles come from 3rd-party sources which we can't control – 1005 | Google's own Tag Manager and Analytics, Facebook Pixel, other trackers and chat scripts etc. However, we 1006 | can load them only when a real user interacts with a page, significantly reducing the Time To Interactive 1007 | metric and scoring much higher performance results. 1008 | 1009 | Depending on where you like these 3rd-party scripts to be, you can either use `wp_footer` action to print the 1010 | code in footer, or put it in your main `app.js` script which, in turn, is enqueued on `wp_enqueue_scripts` action. 1011 | 1012 | ```javascript 1013 | <script> 1014 | var fired = false; 1015 | 1016 | window.addEventListener('scroll', () => { 1017 | if (fired === false) { 1018 | fired = true; 1019 | 1020 | setTimeout(() => { 1021 | 1022 | // Marketing scripts go here. 1023 | 1024 | }, 1000) // 1000ms or 1s works fine, but you can adjust this timeout. 1025 | } 1026 | }); 1027 | </script> 1028 | ``` 1029 | --------------------------------------------------------------------------------