lorenzone
4/6/2018 - 8:37 PM

Useful WordPress Plugins Snippets

A set of useful Snippets for creating WordPress plugins inspirend by : Williams, Brad. Professional WordPress Plugin Development. Wiley.

Integratig your plugin into WordPress

Menus and submenus

add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );

  • $page_title: displayed between <title> tags
  • $menu_title: displayed on the dashboard
  • $capability: minimum capability required to access the menu
  • $function: function called to display page content
  • $icon_url: URL to custom image to use as menu icon
  • $position: order in the menu

Use admin_menu action hook to trigger menu code.

Example:

add_action( 'admin_menu', 'lzp_create_menu' );

function lzp_create_menu() {
  
  // create custom menu
  add_menu_page(
    'My Plugin Settings Page',
    'My Plugin Settings',
    'manage_options', // only administrators can access
    __FILE__,
    'lzp_settings_page',
    plugins_url('/images/wp-icon.png', __FILE__)
  );
}

Do not forget to add where the settings can be accessed in your documentation.

Submenus

add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function );

  • $parent_slug: previously defined $menu_slug of the the top-level menu
  • $page_title: displayed between <title> tags
  • $menu_title: displayed on the dashboard
  • $capability: minimum capability required to access the menu
  • $function: function called to display page content

Example:

add_action( 'admin_menu', 'lzp_create_menu' );

function lzp_create_menu() {
  
  // create custom menu
  add_menu_page(
    'My Plugin Settings Page',
    'My Plugin Settings',
    'manage_options', // only administrators can access
    __FILE__,
    'lzp_settings_page',
    plugins_url('/images/wp-icon.png', __FILE__)
  );
  
  // create custom sub menus
  add_submenu_page( __FILE__, 'About My Plugin', 'About', 'manage_options', __FILE__ . 'about', 'lzp_about_page' );
  add_submenu_page( __FILE__, 'My Plugin Help', 'Help', 'manage_options', __FILE__ . 'help', 'lzp_help_page' );
  add_submenu_page( __FILE__, 'Uninstall My Plugin', 'Uninstall', 'manage_options', __FILE__ . 'uninstall', 'lzp_uninstall_page' );
}

Do not forget to add where the settings can be accessed in your documentation.

Add a menu ton an existing menu

add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function );

  • $page_title: displayed between <title> tags
  • $menu_title: displayed on the dashboard
  • $capability: minimum capability required to access the menu
  • $function: function called to display page content

Example:

add_action( 'admin_menu', 'lzp_create_menu' );

function lzp_create_menu() {
  
  // create submenu under Settings
  add_options_page(
    'My Plugin Settings Page',
    'My Plugin Settings',
    'manage_options', // only administrators can access
    __FILE__,
    'lzp_settings_page'
  );
  
}

Do not forget to add where the settings can be accessed in your documentation.

List of all WordPress submenu functions

  • add_dashboard_page
  • add_posts_page
  • add_media_page
  • add_links_page
  • add_pages_page
  • add_comments_page
  • add_theme_page
  • add_plugins_page
  • add_users_page
  • add_management_page
  • add_options_page

If your plugin only needs a single options page, add it to an existing menu. Otherwise, it's better to create a new top-level menu.

Widgets

The WP_Widget class

  • Extend the WP_Widget class

    
    class lzp_mywidget extends WP_Widget {
      
      function lzp_mywidget() {
        // processes the widget
      }
      
      function form( $instance ) {
        // displays widget form in the admin dashboard
      }
      
      function update( $new_instance, $old_instance ) {
        // processes widget options to save
      }
      
      function widget( $args, $instance ) {
        // displays the widget
      }
      
    }
    
    
  • Create a widget

    add_action( 'widgets_init', 'lzp_mywidget_register_widgets' );
    
    function lzp_mywidget_register_widgets() {
      
      register_widgets( 'lzp_mywidget' );
      
    }
    

    Example: Widget to display favorite Movie and Song

    class lzp_movie_and_song extends WP_Widget {
      
      function lzp_movie_and_song() {
        
        $widget_ops = [
          'classname' => 'lzp_mywidget_widget_class', // class added to the li element of widget
          'description' => 'Display a user\'s favorite movie and song', // description showed on widget screen
        ];
        
        $this->WP_Widget( 'lzp_movie_and_song', 'Movie and Song', $widget_ops );
        
      }
      
      function form( $instance ) {
      
        $defaults = [
          'title' => 'Movie and Song',
          'movie' => '',
          'song' => '',
        ];
        
        $title = $instance['title'];
        $movie = $instance['movie'];
        $song = $instance['song'];
        ?>
        <p>Title: 
      
      }
      
      function update( $new_instance, $old_instance ) {
        // processes widget options to save
      }
      
      function widget( $args, $instance ) {
        // displays the widget
      }
      
    }

Actions and Filters

  • Actions: execute a function at a certain point
  • Filters: manipulate the output passed through the hook

Actions

Create and Remove actions

  • Create custom action hook

    • $tag: name of the action hook to create
    • $args: needed args (optionnal)
do_action( $tag, $arg1, $arg2, ...);
  • Add an function to an action hook

    • $tag: name of the action hook
    • $function: name of called function
    • $priority: lower number, higher priority order
    • $accepted_args: parameters passed to the $function
    add_action( $tag, $function, $priority, $accepted_args );
    
    • Action hook in a class :

      add_action( $tag, array( &$this, $method_to_add ) );
      
  • Remove a function to an action hook

    remove_action( $tag, $function, $priority, $accepted_args );
    

    To remove default WordPress actions, have a look at wp-includes/default-filters.php.

  • Remove all actions of a particular tag (Not advised)

    remove_all_actions( $tag, $priority );
    

Test actions

  • Check if hook has actions

    has_action( $tag, (opt) $function )
    

    Returns true, false or priority

  • Check if action hook has already been executed and number of executions if so:

    did_action( $tag )
    

    Example:

    if ( did_action( 'plugin_loaded' ) ) {
      define( 'LZP_READY', true );
    }
    

Commonly used action hooks

  • plugins_loaded

    A WordPress plugin should do its setup on this hook.

    Example:

    add_action( 'plugins-loaded', 'lzp_setup' );
    
    function lzp_setup() {
      add_action( ... );
      
    }
    

    Creating a setup function and hook it to plugins_loaded is always a good idea

  • init

    Nearly everything is ready after this hook => To use when you need all the information from WordPress to be available.

    Example:

    add_action( 'init', 'lzp_add_excerpts_to_pages' );
    
  • admin_menu

    Called when an admin page loads.

  • template_redirect

    The point where WordPress knows which page a user is viewing. Executed just before the theme template is chosen for the view. A good hook when in need of loading code only for specific page view (loading a specific stylesheet....).

  • wp_head

    Launched by wp_head() function on front end

    Good hook when in need of adding HTML between <head> tags

    Do not add Javascript or CSS - except for specific cases - with this hook !

  • widgets_init

    Execute custom widgets

Filters

Create and remove filters

  • Create custom filter hook

      apply_filters( $tag, $value );
    
  • Add function to a filter hook

    add_filter( $tag, $function, $priority, $accepted_args );
    
    • And in a class :

      add_filter( $tag, array( &$this, $method_to_add ) );
      
  • Remove function from filter hook

    remove_filter( $tag, $function, $priority, $accepted_args );
    
  • Remove all functions from a filter hook

    remove_all_filters( $tag, $priority );
    

Test Filters

has_filter( $tag, $function );

Commonly used filter hooks

  • the_content

    Passes a post's content to any filters registered to the_content.

    Example :

    add_filter( 'the_content', 'lzp_add_related_posts_to_content' );
    
    function lzp_add_related_posts_to_content( $content ) {
      // If not viewing a singular post, just return
      if ( ! is_singular( 'post' ) ) {
        return $content;
      }
      
      // Get the categories of current post
      $terms = get_the_terms( get_the_ID(), 'category' );
      
      // Loop through the categories and put their IDs in an array
      $categories = [];
      foreach ( $terms as $term ) {
        $categories[] = $term->term_id;
      }
      
      // Query posts with the same category
      $loop = new WP_Query ([
        'cat__in'  => $categories,
        'posts_per_page' => 5,
        'post__not_in' => [get_the_ID()],
        'orderby' => 'rand'
      ]);
      
      // Loop through Related posts, if any
      if ( $loop->have_posts() ) {
        
        // Open related posts list
        $content .= '<ul class="related-posts">';
        
        while ( $loop->have_posts() ) {
          $loop->the_post();
          
          // Add related post to the list and format it
          $content .= the_title(
            '<li><a href="' . get_permalink() . '">',
            '</a></li>',
            false
          );
          
        }
        
        // Close related posts list
        $content .= '</ul>';
        
        // Reset Query
        wp_reset_query();
        
      }
      
      return $content;
      
    }
    
  • the_title

  • comment_text

  • template_include

    • front_page_template
    • home_template
    • single_template
    • page_template
    • attachment_template
    • archive_template
    • category_template
    • tag_template
    • author_template
    • date_template
    • archive_template
    • search_template
    • 404_template
    • index_template

Common functions

Current hook

  • Return the name of the current hook (action or filter)

    current_filter();
    

Quick return

__return_false();
__return_true();
__return_empty_array();
__return_zero();

Create a new plugin

Header

<?php
/*
Plugin Name: My Plugin
Plugin URI: https://loren.zone/wordpress-plugins/my-plugin
Description: A brief description of what the plugin does
Version: 1.0
Author: Lorenzo Milesi
Author URI: https://loren.zone
License: GPL
*/

/*  Copyright YEAR  PLUGIN_AUTHOR_NAME  (email : PLUGIN AUTHOR EMAIL)
 
    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 St, Fifth Floor, Boston, MA  02110-1301  USA
*/

Path Functions

Local paths

  • Local Path to Plugin folder

    echo plugin_dir_path(__FILE__);
    
  • Local path to subfolder

    echo plugin_dir_path(__FILE__).'js/scripts.js';
    

URL paths

  • Full plugins directory URL (best friend function)

    • $path - (string) (optional) — Path relative to the plugins URL
    • $plugin -(string) (optional) — Plugin file that you want to be relative (that is, pass in FILE)
    plugins_url( $path, $plugin );
    

    Example:

    echo '<img src="' . plugins_url( 'images/icon.png', __FILE__ ) . '">';
    

    returns

    <img src="http://example.com/wp-content/plugins/my-custom-plugin/images/icon.png">
    
    • supports mu-plugins
    • auto detects ssl
    • uses WP_PLUGIN_URL and WPMU_PLUGIN_URL
  • Full includes directory URL

    https://website.com/wp-includes

    includes_url();

  • Full content directory URL

    https://website.com/wp-content

    content_url();

  • Full admin directory URL

    https://website.com/wp-admin

    admin_url();

  • home and site URL

    /!\ differences are made within wp_options table

    home_url(); // URL to visit website

    site_url(); // URL to WordPress core files

Activation hooks

  • Plugin activation function: triggered when plugin gets activated

    • $file - (string) (required) — Path to the primary plugin file
    • $function - (string) (required) — The function to be executed when the plugin is activated

    Example:

      register_activation_hook(__FILE__,'lzp_install');
    
  • Plugin deactivation function: triggered when plugin gets deactivated

    • $file - (string) (required) — Path to the primary plugin file
    • $function - (string) (required) — The function to be executed when the plugin is deactivated

    Example:

     register_deactivation_hook(__FILE__,'lzp_deactivate');
    

    /!\ DO NOT include uninstall functionnality here (since WP auto update deactivates all plugins)

Uninstall

  • Method 1 (cleanest) user uninstall.php file

      if(!defided('WP_UNISTALL_PLUGIN'))
        exit();
    
      // Delete option from options table
      delete_option('lzp_options');
    
      // Remove any additionnal options and custom tables
    
  • Method 2 (not advised) register_uninstall_hook($file, $function); /!\ must be INSIDE activation hook

      register_activation_hook( __FILE__, 'lzp_activate' );
    
      function lzp_activate() {
    
        //register the uninstall function
        register_uninstall_hook( __FILE__, 'lzp_uninstaller' );
    
      }
    
      function lzp_uninstaller() {
    
        //delete any options, tables, etc the plugin created
        delete_option( 'lzp_options' );
    
      }
    

Some useful WordPress Links

WordPress Coding Standards

https://codex.wordpress.org/WordPress_Coding_Standards