1. Lets start off with what & why

    Before moving forward, you should know that there’s nothing wrong with adding custom code to a theme’s functions.php file, especially if the code is directly related to the theme you’re using. That’s not a problem at all.

    The problem occurs when you add custom functions that aren’t necessarily tied to a theme such as when creating custom post types, taxonomies, or shortcodes. Most of the time, you’d want to keep these types of things separate from your theme because you’d like to retain the functionality when you switch themes.

    Of course, you can transfer one theme’s functions.php code over to another theme, but why not make it even easier, requiring no transfer of code?

     


    Code Examples

    Function One — adding additional styles.
    Function Two — adding a sidebar.
    Function Three — adding a Custom Post Type.

    What belongs Where

    The Table
    Purpose of codeFunctionality pluginfunctions.php
    Creating shortcodesAlwaysNever
    Adding scripts and stylesDependsDepends
    Creating sidebarsNeverAlways
    Creating menusNeverAlways
    Add post types/taxonomiesAlwaysNever
    Add post thumbnailsDependsDepends
    Add Google Analytics to footerAlwaysNever
    Customize WordPress DashboardAlwaysNever
    Change default GravatarAlwaysNever
    Add custom profile fieldsAlwaysNever
    Taken from WPCandy, Thanks Ryan!
    
    <?php
    
    /* Add our function to the *_enqueue_scripts hook. */
    add_action( 'wp_enqueue_scripts', 'wordcamp_vegas_scripts' );
    
    /**
     * Function that registers and enqueues our scripts & styles.
     *
     * @since 1.0.0
     */
    function wordcamp_vegas_scripts() {
    	wp_enqueue_script( 'mytheme-functions', trailingslashit( get_stylesheet_directory_uri() ) . 'library/js/functions.js', array( 'jquery' ), '1.0.1', true );
    	wp_enqueue_style( 'mytheme', trailingslashit( get_stylesheet_directory_uri() ) . 'library/css/screen.css', null, '1.0.1', 'screen' );
    }
    
    ?>
    
    Where Does this function belong?functions.php

    This function should reside in your Theme OR Child Themes functions.php because it correlates to the design of your site.

    There .

    
    <?php
    
    /* Register sidebars. */
    add_action( 'widgets_init', 'wordcamp_vegas_register_sidebars', 12 );
    
    /**
     * Function that registers and enqueues our scripts & styles.
     *
     * @since 1.0.0
     */
    function wordcamp_vegas_register_sidebars() {
    	$utility_bar = array(
    		'name' => __( 'Utility: Bar' ),
    		'id' => 'utilitybar',
    		'description' => __( 'Displayed at the top of the page.' ),
    		'before_widget' => '<div id="%1$s" class="widget %2$s widget-%2$s">',
    		'after_widget' => '</div>',
    		'before_title' => '<h3 class="widget-title">',
    		'after_title' => '</h3>'
    	);
    	register_sidebar( $utility_bar );
    }
    
    ?>
    
    Where Does this function belong?functions.php

    This function should reside in your Theme OR Child Themes functions.php because it creates widget areas for use in your current design.

    This sidebar might not have any use in a future project or the next theme you may use.

    
    <?php
    
    /* Register sidebars. */
    add_action( 'init', 'wordcamp_vegas_register_post_type' );
    
    /**
     * Function that registers our Custom Post Type.
     *
     * @since 1.0.0
     */
    function wordcamp_vegas_register_post_type() {
    	/* Labels. */
        $portfolio_labels = array(
            'menu_name'				=> __( 'Portfolio' ),
            'name' 					=> __( 'Projects' ),
            'singular_name' 		=> __( 'Project' ),
            'add_new' 				=> __( 'Add New' ),
            'add_new_item' 			=> __( 'Add New Project' ),
            'edit' 					=> __( 'Edit' ),
            'edit_item' 			=> __( 'Edit Project' ),
            'new_item' 				=> __( 'New Project' ),
            'view' 					=> __( 'View Project' ),
            'view_item' 			=> __( 'View Project' ),
            'search_items' 			=> __( 'Search Projects' ),
            'not_found' 			=> __( 'No Projects found' ),
            'not_found_in_trash' 	=> __( 'No Projects found in the Trash' ),
        );
    
        /* Arguments. */
        $portfolio_args = array(
            'has_archive' 			=> 'portfolio',
            'show_in_nav_menus'		=> false,
            'description' 			=> 'Here you will find a select few of my WordPress projects. Ranging from custom theme development to minor theme modification. You might also see some custom plugin development. Note, not all of my work is public.',
            'labels' 				=> $portfolio_labels,
            'public' 				=> true,
            'publicly_queryable' 	=> true,
            'query_var' 			=> 'portfolio',
            'rewrite' 				=> array( 'slug' => false, 'with_front' => true ),
            'capability_type' 		=> 'post',
            'hierarchical' 			=> false,
            'taxonomies' 			=> array( 'project_category', 'project_tag', 'project_tools' ),
            'supports' 				=> array( 'title', 'editor', 'excerpt', 'thumbnail', 'custom-fields', "{$prefix}-post-settings", 'entry-views' ),
        );
        
        /* Register. */
        register_post_type( 'portfolio', $portfolio_args );
    }
    
    ?>
    
    Where Does this function belong?you-site-functionallity-plugin/functions.php

    This function should be created in functionallity plugin. If you’re creating Custom Post Types chances are you will want them around when you change themes in the future.

    Example: If your CPT is a portfolio, and your the type of person who changes your theme once a month you don’t want to have to copy and paste code from each theme everytime... This way it always exists as long as the plugin is Active.


    Great reads and notes online:

    Justin Tadlock's Custom Functions for users
    WPCandy teaches how to build a funcsionality plugin.
  2. Development becomes alot easier to inplement when all your code is in one folder OR one functionallity plugin!

    Follow the plugin steps

    Writing a plugin
    Class Example
    The Plugin (Boilerplate)
  3. In order to create a proper plugin we need to follow these steps as demonstrated on the Codex.

    • Name your plugin.
    • Create a name safe folder. my-plugin-folder
    • Add a PHP file. my-plugin.php
    • Write your code!

    First you'll need the proper WordPress plugin information:

    <?php
    /**
     * Plugin Name: PluginName
     * Plugin URI: http://austinpassy.com/wordpress-plugins/
     * Description: Core functionality for __________.
     * Version: 1.0.0
     * Author: Austin Passy
     * Author URI: http://austinpassy.com/
     *
     * (license)
     *
     * @package PluginName
     */
    

    You can add an optional license in there as well..

     *
     * @copyright 2012
     * @author Austin Passy
     * @link http://austinpassy.com/2012
     * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     *
     * 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.
    

    Then get coding...

    Okay, next we'll creat the plugin class that hadles all our functions.

    // TODO: rename this class to a proper name for yuour plugin
    class PluginName {
    	
    	function __construct() {
        	//actions and filter go here
        }
        
        function init() {
        	//does something
        }
        
    }
    

    Now create all your functions and activate your functionality plugin, unless you've chosen to install it in the mu-plugins folder (it's automatically activated).

    Here is the completed functionallity plugin. Alternativly you can download the full plugin zip file.

  4. Go ahead and download this plugin
    WordCamp Vegas Plugability plugin
  5. Let me answer your questions. And show you some examples
    WordPress Plugin Boilerplate
    A great starting point for a WP Plugin.
    WP Plugin Boilerplate
    Another plugin boilerplater on GitHub
    WordPress Plugin Boilerplate
    Not the best code, but has a great example on how to deactivate your plugin if the WordPress version is one you're not supporting.
    WPCandy
    Download WPCandy's functionality plugin. (This is a zip file link)