DevTeam-Admin
3/26/2020 - 11:06 PM

WordPress Functionality Plugin Starter

This provides a basic structure of a functionality plugin.

The functionality plugin should include functionality that should not be stored in the custom theme's functions.php such as custom post types and custom taxonomies.

Custom post types and custom taxonomies should be stored in a functionality plugin to prevent these pieces of functionality of disappreaing if the custom theme is deactivated. For example, if you create a products custom post type, the client will probably wants products available even if they haven to change the theme.

More about this can be found here: https://css-tricks.com/wordpress-functionality-plugins/

Structure of the files are like so: Theme Functionality/

  • theme-functionality.php lib/ functions/
    • general.php
    • post-types.php
    • taxonomies.php
<?php
/**
 * TAXONOMIES
 *
 * @link  http://codex.wordpress.org/Function_Reference/register_taxonomy
 */


// Register Product Type Taxonomy
// Below is just an example

function product_type_taxonomy() {

	$labels = array(
		'name'                       => 'Product Types',
		'singular_name'              => 'Product Type',
		'menu_name'                  => 'Product Type',
		'all_items'                  => 'All Product Types',
		'parent_item'                => 'Parent Product Type',
		'parent_item_colon'          => 'Parent Product Type:',
		'new_item_name'              => 'New Product Type',
		'add_new_item'               => 'Add New Product Type',
		'edit_item'                  => 'Edit Product Type',
		'update_item'                => 'Update Product Type',
		'view_item'                  => 'View Product Type',
		'separate_items_with_commas' => 'Separate items with commas',
		'add_or_remove_items'        => 'Add or remove product type',
		'choose_from_most_used'      => 'Choose from the most used',
		'popular_items'              => 'Popular Product Types',
		'search_items'               => 'Search Product Types',
		'not_found'                  => 'Not Found',
		'no_terms'                   => 'No items',
		'items_list'                 => 'Items list',
		'items_list_navigation'      => 'Items list navigation',
	);
	$args = array(
		'labels'                     => $labels,
		'hierarchical'               => true,
		'public'                     => true,
		'show_ui'                    => true,
		'show_admin_column'          => true,
		'show_in_nav_menus'          => true,
		'show_tagcloud'              => true,
	);
	register_taxonomy( 'product_type', array( 'products' ), $args );

}
add_action( 'init', 'product_type_taxonomy', 0 );
<?php
/**
 * POST TYPES
 *
 * @link  http://codex.wordpress.org/Function_Reference/register_post_type
 */

// Register Product Custom Post Type
// Below is just an example

function product_post_type() {

	$labels = array(
		'name'                  => 'Products',
		'singular_name'         => 'Product',
		'menu_name'             => 'Products',
		'name_admin_bar'        => 'Products',
		'archives'              => 'Product Archives',
		'attributes'            => 'Product Attributes',
		'parent_item_colon'     => 'Product Parent Item:',
		'all_items'             => 'All Products',
		'add_new_item'          => 'Add New Product',
		'add_new'               => 'Add New',
		'new_item'              => 'New Item',
		'edit_item'             => 'Edit Item',
		'update_item'           => 'Update Item',
		'view_item'             => 'View Item',
		'view_items'            => 'View Items',
		'search_items'          => 'Search Item',
		'not_found'             => 'Not found',
		'not_found_in_trash'    => 'Not found in Trash',
		'featured_image'        => 'Featured Image',
		'set_featured_image'    => 'Set featured image',
		'remove_featured_image' => 'Remove featured image',
		'use_featured_image'    => 'Use as featured image',
		'insert_into_item'      => 'Insert into item',
		'uploaded_to_this_item' => 'Uploaded to this item',
		'items_list'            => 'Items list',
		'items_list_navigation' => 'Items list navigation',
		'filter_items_list'     => 'Filter items list',
	);
	$args = array(
		'label'                 => 'Product',
		'description'           => 'Shop items',
		'labels'                => $labels,
		'supports'              => array( 'title', 'editor', 'thumbnail' ),
		'taxonomies'            => array( 'product_type' ),
		'hierarchical'          => false,
		'public'                => true,
		'show_ui'               => true,
		'show_in_menu'          => true,
		'menu_position'         => 5,
		'menu_icon'             => 'dashicons-cart',
		'show_in_admin_bar'     => true,
		'show_in_nav_menus'     => true,
		'can_export'            => true,
		'has_archive'           => true,
		'exclude_from_search'   => false,
		'publicly_queryable'    => true,
		'capability_type'       => 'post',
	);
	register_post_type( 'products', $args );

}
add_action( 'init', 'product_post_type', 0 );
<?php
/**
 * GENERAL HOUSEKEEPING
 *
 */

class RF_General {

   /**
    * Add actions and filters
    *
    * @since 1.0.0
    */
   public function __construct() {

      // General housekeeping
      add_filter( 'http_request_args', array( $this, 'hide_plugin_from_updates' ), 5, 2 );
      add_action( 'admin_notices', array( $this, 'hide_update_notice_nonadmins' ), 1 );

      // Admin bar and menus customization
      add_action( 'admin_menu', array( $this, 'remove_menus' ) );
      add_action( 'admin_menu', array( $this, 'remove_submenus' ), 110 );

      // Customize post type UI
      add_filter( 'post_updated_messages', array( $this, 'set_updated_messages' ) );

   }

   /**
    * Activation tasks
    *
    * @since 1.0.0
    */
   public static function plugin_activation() {
      if ( ! current_user_can( 'activate_plugins' ) )
         return;

      $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
      check_admin_referer( "activate-plugin_{$plugin}" );

      // Flush permalink rewrite rules
      flush_rewrite_rules();

      // Do other activation things here...
   }

   /**
    * Don't update plugin
    *
    * @since 1.0.0
    *
    * This prevents you being prompted to update if there's a public plugin
    * with the same name.
    *
    * @author Mark Jaquith
    * @link http://markjaquith.wordpress.com/2009/12/14/excluding-your-plugin-or-theme-from-update-checks/
    *
    * @param  array  $r   Request arguments
    * @param  string $url Request url
    * @return array       Request arguments
    */

   public function hide_plugin_from_updates( $r, $url ) {
   	if ( 0 !== strpos( $url, 'http://api.wordpress.org/plugins/update-check' ) )
   		return $r; // Not a plugin update request. Bail immediately.

      $plugins = unserialize( $r['body']['plugins'] );
   	unset( $plugins->plugins[ plugin_basename( __FILE__ ) ] );
   	unset( $plugins->active[ array_search( plugin_basename( __FILE__ ), $plugins->active ) ] );
   	$r['body']['plugins'] = serialize( $plugins );
   	return $r;
   }

   /**
    * Hide core update notice for all but Admins
    *
    * @since 1.1.0
    */
   public function hide_update_notice_nonadmins() {
   	if ( ! current_user_can( 'update_core' ) ) {
   		remove_action( 'admin_notices', 'update_nag', 3 );
   	}
   }

   /**
    * Remove unused menu items by adding them to the array
    *
    * @since 1.0.0
    */
   public function remove_menus() {
   	global $menu;
   	$restricted = array();
   	// Example:
   	//$restricted = array( __('Dashboard'), __('Posts'), __('Media'), __('Pages'), __('Appearance'), __('Tools'), __('Users'), __('Settings'), __('Comments'), __('Plugins') );
   	end ($menu);
   	while ( prev( $menu ) ){
   		$value = explode( ' ',$menu[key($menu)][0] );
   		if( in_array( $value[0] != NULL?$value[0]:"" , $restricted ) ){ unset($menu[key($menu)] ); }
   	}
   }

   /**
    * Remove unnecesary sub-menu links
    *
    * @since 1.0.0
    */
   public function remove_submenus() {
   	remove_submenu_page( 'themes.php', 'theme-editor.php' );
   	remove_submenu_page( 'plugins.php', 'plugin-editor.php' );
   }

   /**
    * Change post update messages to be post type-specific
    *
    * @since 1.0.0
    */
   public function set_updated_messages( $messages ) {
      global $post, $post_ID;

      $post_type = get_post_type( $post_ID );
      $obj = get_post_type_object( $post_type );
      $singular = $obj->labels->singular_name;

      $messages[$post_type] = array(
         0 => '', // Unused. Messages start at index 1.
         1 => sprintf( __( $singular.' updated. <a href="%s">View '.strtolower( $singular ).'</a>' ), esc_url( get_permalink( $post_ID ) ) ),
         2 => __( 'Custom field updated.' ),
         3 => __( 'Custom field deleted.' ),
         4 => __( $singular.' updated.' ),
         5 => isset( $_GET['revision'] ) ? sprintf( __( $singular.' restored to revision from %s' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
         6 => sprintf( __( $singular.' published. <a href="%s">View '.strtolower( $singular ).'</a>' ), esc_url( get_permalink( $post_ID ) ) ),
         7 => __( $singular.' saved.' ),
         8 => sprintf( __( $singular.' submitted. <a target="_blank" href="%s">Preview '.strtolower( $singular ).'</a>' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ),
         9 => sprintf( __( $singular.' scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview '.strtolower( $singular ).'</a>' ), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ) ),
         10 => sprintf( __( $singular.' draft updated. <a target="_blank" href="%s">Preview '.strtolower( $singular ).'</a>' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ),
      );

      return $messages;
   }

}

new RF_General();
<?php
 /**
 *
 * @package   Theme Functionality
 * @author    Rose Cass <rose.cass@redstamp.ca>
 * @license   GPL-2.0+
 * @copyright 2018 RedStamp
 *
 * @wordpress-plugin
 * Plugin Name: Theme Functionality
 * Description: This very important plugin contains all of the core functionality for this website so that it remains theme-independent.
 * Version:     1.0.0
 * Author:      Rose Cass
 * License:     GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 */

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * Define plugin directory
 *
 * @since 1.0.0
 */
define( 'RF_DIR', dirname( __FILE__ ) );

/**
 * General housekeeping and plugin activation tasks
 *
 * @since 1.0.0
 */
include_once( RF_DIR . '/lib/functions/general.php' );
register_activation_hook( __FILE__, array( 'RF_General', 'plugin_activation' ) );

/**
 * Post types
 *
 * @since 1.0.0
 */
include_once( RF_DIR . '/lib/functions/post-types.php' );

/**
 * Taxonomies
 *
 * @since 1.0.0
 */
include_once( RF_DIR . '/lib/functions/taxonomies.php' );