ݺߣ

ݺߣShare a Scribd company logo
Laying the Proper
Foundation for Plugin &
Theme Development
WORDCAMP LOUISVILLE 2012
Tammy Hart
Designer, front-end developer, and
programmer... I make all the things

Unabashed WordPress addict

Design Engineer at 10up, a premium
WordPress Engineering provider
BUILDING BLOCKS

Setting a Standard
Structure
Theme and plugins can quickly grow   /theme-name
unwieldy. Be prepared with an easy   --/css
to understand and simple to use      --/fonts
directory structure.
                                     --/images
                                     --/includes
                                     --/js
                                     index.php
                                     functions.php
                                     style.css
Commenting
/**
  * Returns an unordered list of recent posts
  * @param int $numposts Default is 3, can be any integer.
  * @param null $author restrict the return to an author
  * @param null $tag restrict the return to a tag.
  * @param string|array $post_type Default is 'post', define the posts type(s) to return
  *
  * @return string HTML unordered list
  */
function tcnmy_recent_posts( $numposts = 3, $author = null, $tag = null, $post_type = 'post' ) {
       $posts = new WP_Query( array(
             'post_type' => $post_type,
             'no_found_posts' => true,
             'posts_per_page' => intval( $numposts ),
             'author' => $author,
             'tag' => $tag
       ) );
...
}
Nomenclature
Avoid naming conflicts by   // used by core
using unique namespaces.    function add_meta_box() { ... }
                            // too common
                            function add_a_meta_box() { ... }
                            // just right!
                            function themename_add_post_meta_box() { ... }


                            // class names use Title Case
Follow WordPress core       class WP_Query { ... }
standards for class         class WP_Rewrite { ... }
naming.                     class Theme_Name_Do_Stuff { ... }
Constants
Save important, static strings in a constant by defining them.



// Set the path constants
define( 'BB_PATH', trailingslashit( dirname( $this->bbconfig ) ) );
define( 'BACKPRESS_PATH' , BB_PATH . 'bb-includes/backpress/' );
define( 'BB_INC', 'bb-includes/' );

// use them
require_once ( BB_PATH . BB_INC . 'class.bb-query.php' );
ENQUEUEUEUEUEUE ... UE

Javascript & Stylesheets
Why Enqueue?
Can't you just call them in the header.php of a theme or add them there with
actions in a plugin?


NO!

Using enqueue functions makes it easier to
manage scripts, stylesheets, their dependants,
and where they show up.
Enqueue Scripts
wp_enqueue_script(
    $handle, // name of the script
    $src, //where to find it
    $deps, // what it depends on to work
    $ver, // version number of the script
    $in_footer // whether to load it in the footer or not
);

// remove an enqueued script
wp_dequeue_script( $handle );
Enqueue Styles
wp_enqueue_style(
    $handle, // name
    $src, //where to find it
    $deps, // what it depends on to work
    $ver, // version number of the script
    $in_footer // whether to load it in the footer or not
);

// remove an enqueued style
wp_dequeue_style( $handle );
Registering
wp_deregister_script( $handle );

wp_register_script(
    $handle, // name of the script
    $src, //where to find it
    $deps, // what it depends on to work
    $ver, // version number of the script
    $in_footer // whether to load it in the footer or not
);

// now you can just...
wp_enqueue_script( $handle );
// or use it in $deps
Put Them in Their Place
ADMIN                                   FRONT END
add_action( 'admin_enqueue_scripts' ,   add_action( 'wp_enqueue_scripts' ,
'themename_admin_enqueue' );            'themename_wp_enqueue' );

function themename_admin_enqueue() {    function themename_wp_enqueue() {
     wp_register_script( ... );              wp_register_script( ... );
     wp_register_style( ... );               wp_register_style( ... );
     wp_enqueue_script( ... );               wp_enqueue_script( ... );
     wp_enqueue_style( ... );                wp_enqueue_style( ... );

     if ( get_post_type() == 'page' )        if ( get_post_type() == 'page' )
          wp_enqueue_script( ... );               wp_enqueue_script( ... );
}                                       }


More Info: http://bit.ly/enqueue
Plugin Example
// Styles and Scripts
add_action( 'admin_enqueue_scripts' , 'recipress_admin_enqueue' );

function recipress_admin_enqueue() {
     wp_enqueue_script( 'recipress_back' , RECIPRESS_URL . 'js/back.js' , array( 'jquery',
'jquery-ui-sortable' ) );
     wp_enqueue_style( 'recipress_back' , RECIPRESS_URL . 'css/back.css' );
}

add_action( 'wp_enqueue_scripts' , 'recipress_wp_enqueue' );

function recipress_wp_enqueue() {
     wp_enqueue_style( 'recipress_front' , RECIPRESS_URL . 'css/front.css' );
}
KEEP IT CLEAN

Using Separate Code Files
Why Include?
Can't you just dump all your code into functions.php of a theme or the main
plugin file?


Yes, but...

Large amounts of code are easier to read and
edit if they are separated into their own files.
Include
// files for themes
include( get_template_directory_uri() . '/includes/some_function.php'
);

// in a plugin
include( CONSTANT_BASE . '/includes/some_function.php' );
Include, Require, _once
// Puts the contents of the file directly where it is called
include()

// Only lets the script call the file once
include_once()

// Same as include() but will stop the script if error occurs
require()

// Same as include_once() with the rules of require()
require_once()
Plugin Example
// Load plugin files
include_once( RECIPRESS_DIR   .   'php/functions.php' );
include_once( RECIPRESS_DIR   .   'php/options.php' );
include_once( RECIPRESS_DIR   .   'php/meta_box.php' );
include_once( RECIPRESS_DIR   .   'php/taxonomies.php' );
include_once( RECIPRESS_DIR   .   'php/output.php' );
include_once( RECIPRESS_DIR   .   'php/widgets.php' );
REMEMBER ALL THE THINGS!

Miscellaneous Memos
Theme/Plugin Header
Theme: style.css              Plugin: plugin_file.php

/*                            /*
Theme Name: 10up.com          Plugin Name: ReciPress
Author: 10up                  Plugin URI: http://recipress.com
Author URI: http://10up.com   Version: 1.8
*/                            */
Readme.txt
Used automatically in the WordPress.org repository for things like:
       Stable Tag
       Description
       Installation
       FAQ
       Screenshots
       Changelog
       Update Notice
       Arbitrary Sections

Check your readme: http://wordpress.org/extend/plugins/about/validator
Localization
// text strings
__( 'String of Text' , 'text-domain' );

// Echoing text
_e( 'String of Text' , 'text-domain' );

// Explaining text
_x( 'String of Text' , 'A string of text' , 'text-domain' );

// Load the text domain
add_action( 'init', 'plugin_text_domain' );
function plugin_text_domain() {
    load_plugin_textdomain( 'text-domain' , false, DEFINED_BASE .
'/lang/' );
}
Controls
class WP_Hotfix_Controller {
     function init() {
          add_action( 'init', 'wp_hotfix_init' );
          register_activation_hook( __FILE__, array( __CLASS__, 'activate' ) );
          register_deactivation_hook( __FILE__, array( __CLASS__, 'deactivate' ) );
     }
     function activate() {
          add_option( 'hotfix_version' , '1' );
          register_uninstall_hook( __FILE__, array( __CLASS__, 'uninstall' ) );
     }
     function deactivate() {
          delete_option( 'hotfix_version' );
     }
     function uninstall() {
          self::deactivate(); // The same, for now
     }
}
THANK YOU!

Questions?
@tammyhart

10up.com
@10up

More Related Content

What's hot (20)

PDF
Drupal 8: Routing & More
drubb
?
PDF
PhpBB meets Symfony2
Fabien Potencier
?
DOC
Creating a Simple PHP and MySQL-Based Login System
Azharul Haque Shohan
?
PDF
Dependency injection - phpday 2010
Fabien Potencier
?
PDF
The Enterprise Wor/d/thy/Press
Jeroen van Dijk
?
PDF
SPL: The Missing Link in Development
jsmith92
?
PDF
Dependency injection in PHP 5.3/5.4
Fabien Potencier
?
PDF
The state of Symfony2 - SymfonyDay 2010
Fabien Potencier
?
PDF
You Don't Know Query (WordCamp Netherlands 2012)
andrewnacin
?
PPT
New: Two Methods of Installing Drupal on Windows XP with XAMPP
Rupesh Kumar
?
PPTX
Speed up your developments with Symfony2
Hugo Hamon
?
PPT
Creating Custom Drupal Modules
tanoshimi
?
PDF
Unit and Functional Testing with Symfony2
Fabien Potencier
?
PDF
WordPress REST API hacking
Jeroen van Dijk
?
PDF
Frameworks da nova Era PHP FuelPHP
Dan Jesus
?
PPT
Short Intro to PHP and MySQL
Jussi Pohjolainen
?
PDF
Curso Symfony - Clase 4
Javier Eguiluz
?
PDF
Keeping it Small: Getting to know the Slim Micro Framework
Jeremy Kendall
?
PDF
Symfony2 - WebExpo 2010
Fabien Potencier
?
Drupal 8: Routing & More
drubb
?
PhpBB meets Symfony2
Fabien Potencier
?
Creating a Simple PHP and MySQL-Based Login System
Azharul Haque Shohan
?
Dependency injection - phpday 2010
Fabien Potencier
?
The Enterprise Wor/d/thy/Press
Jeroen van Dijk
?
SPL: The Missing Link in Development
jsmith92
?
Dependency injection in PHP 5.3/5.4
Fabien Potencier
?
The state of Symfony2 - SymfonyDay 2010
Fabien Potencier
?
You Don't Know Query (WordCamp Netherlands 2012)
andrewnacin
?
New: Two Methods of Installing Drupal on Windows XP with XAMPP
Rupesh Kumar
?
Speed up your developments with Symfony2
Hugo Hamon
?
Creating Custom Drupal Modules
tanoshimi
?
Unit and Functional Testing with Symfony2
Fabien Potencier
?
WordPress REST API hacking
Jeroen van Dijk
?
Frameworks da nova Era PHP FuelPHP
Dan Jesus
?
Short Intro to PHP and MySQL
Jussi Pohjolainen
?
Curso Symfony - Clase 4
Javier Eguiluz
?
Keeping it Small: Getting to know the Slim Micro Framework
Jeremy Kendall
?
Symfony2 - WebExpo 2010
Fabien Potencier
?

Viewers also liked (13)

PDF
Traversing Search Results
Tammy Hart
?
PDF
Responsify! 5 Things You Should Know About Responsive Web Design
Tammy Hart
?
PPT
Word Press And Multimedia
Tammy Hart
?
PDF
WordPress Transients
Tammy Hart
?
PDF
Responsify!
Tammy Hart
?
PPTX
Dont Forget the Milk
Tammy Hart
?
PPT
Professioanl Blogging
Tammy Hart
?
PPTX
Designing for WordPress
Tammy Hart
?
PPTX
Freelancing with WordPress
Tammy Hart
?
PPT
Word Press & Working With Clients
Tammy Hart
?
ODP
Food Blog Design
Tammy Hart
?
PPTX
Custom WordPress theme development
Tammy Hart
?
PDF
In Browser Design with WordPress
Tammy Hart
?
Traversing Search Results
Tammy Hart
?
Responsify! 5 Things You Should Know About Responsive Web Design
Tammy Hart
?
Word Press And Multimedia
Tammy Hart
?
WordPress Transients
Tammy Hart
?
Responsify!
Tammy Hart
?
Dont Forget the Milk
Tammy Hart
?
Professioanl Blogging
Tammy Hart
?
Designing for WordPress
Tammy Hart
?
Freelancing with WordPress
Tammy Hart
?
Word Press & Working With Clients
Tammy Hart
?
Food Blog Design
Tammy Hart
?
Custom WordPress theme development
Tammy Hart
?
In Browser Design with WordPress
Tammy Hart
?
Ad

Similar to Laying the proper foundation for plugin and theme development (20)

PDF
Seven deadly theming sins
George Stephanis
?
PPTX
The Way to Theme Enlightenment 2017
Amanda Giles
?
PPTX
WordPress Structure and Best Practices
markparolisi
?
PDF
Keep Your Code Organized! WordCamp Montreal 2013 Presentation slides
Jer Clarke
?
PDF
WordPress Theming 101
Zero Point Development
?
PPTX
The Way to Theme Enlightenment
Amanda Giles
?
PDF
Wordpress Questions & Answers
Nicole Dion
?
PDF
Creating Your First WordPress Plugin
Brad Williams
?
KEY
How To Write a WordPress Plugin
Andy Stratton
?
PPTX
WordPress Themes 101 - dotEduGuru Summit 2013
Curtiss Grymala
?
PDF
Bending word press to your will
Tom Jenkins
?
PDF
My first WordPress Plugin
Abbas Siddiqi
?
PPTX
WordPress Themes 101 - HighEdWeb New England 2013
Curtiss Grymala
?
PDF
Stop Hacking WordPress, Start Working with it - Charly Leetham - WordCamp Syd...
WordCamp Sydney
?
PPTX
Building Potent WordPress Websites
Kyle Cearley
?
PPT
WordPress Plugin Basics
Amanda Giles
?
PDF
Newbies guide to customizing word press themes 25
New Tricks
?
PPTX
Introduction to Plugin Programming, WordCamp Miami 2011
David Carr
?
PPTX
Writing your own WordPress themes and plugins
Stephanie Wells
?
PPT
WordPress development paradigms, idiosyncrasies and other big words
TomAuger
?
Seven deadly theming sins
George Stephanis
?
The Way to Theme Enlightenment 2017
Amanda Giles
?
WordPress Structure and Best Practices
markparolisi
?
Keep Your Code Organized! WordCamp Montreal 2013 Presentation slides
Jer Clarke
?
WordPress Theming 101
Zero Point Development
?
The Way to Theme Enlightenment
Amanda Giles
?
Wordpress Questions & Answers
Nicole Dion
?
Creating Your First WordPress Plugin
Brad Williams
?
How To Write a WordPress Plugin
Andy Stratton
?
WordPress Themes 101 - dotEduGuru Summit 2013
Curtiss Grymala
?
Bending word press to your will
Tom Jenkins
?
My first WordPress Plugin
Abbas Siddiqi
?
WordPress Themes 101 - HighEdWeb New England 2013
Curtiss Grymala
?
Stop Hacking WordPress, Start Working with it - Charly Leetham - WordCamp Syd...
WordCamp Sydney
?
Building Potent WordPress Websites
Kyle Cearley
?
WordPress Plugin Basics
Amanda Giles
?
Newbies guide to customizing word press themes 25
New Tricks
?
Introduction to Plugin Programming, WordCamp Miami 2011
David Carr
?
Writing your own WordPress themes and plugins
Stephanie Wells
?
WordPress development paradigms, idiosyncrasies and other big words
TomAuger
?
Ad

Laying the proper foundation for plugin and theme development

  • 1. Laying the Proper Foundation for Plugin & Theme Development WORDCAMP LOUISVILLE 2012
  • 2. Tammy Hart Designer, front-end developer, and programmer... I make all the things Unabashed WordPress addict Design Engineer at 10up, a premium WordPress Engineering provider
  • 4. Structure Theme and plugins can quickly grow /theme-name unwieldy. Be prepared with an easy --/css to understand and simple to use --/fonts directory structure. --/images --/includes --/js index.php functions.php style.css
  • 5. Commenting /** * Returns an unordered list of recent posts * @param int $numposts Default is 3, can be any integer. * @param null $author restrict the return to an author * @param null $tag restrict the return to a tag. * @param string|array $post_type Default is 'post', define the posts type(s) to return * * @return string HTML unordered list */ function tcnmy_recent_posts( $numposts = 3, $author = null, $tag = null, $post_type = 'post' ) { $posts = new WP_Query( array( 'post_type' => $post_type, 'no_found_posts' => true, 'posts_per_page' => intval( $numposts ), 'author' => $author, 'tag' => $tag ) ); ... }
  • 6. Nomenclature Avoid naming conflicts by // used by core using unique namespaces. function add_meta_box() { ... } // too common function add_a_meta_box() { ... } // just right! function themename_add_post_meta_box() { ... } // class names use Title Case Follow WordPress core class WP_Query { ... } standards for class class WP_Rewrite { ... } naming. class Theme_Name_Do_Stuff { ... }
  • 7. Constants Save important, static strings in a constant by defining them. // Set the path constants define( 'BB_PATH', trailingslashit( dirname( $this->bbconfig ) ) ); define( 'BACKPRESS_PATH' , BB_PATH . 'bb-includes/backpress/' ); define( 'BB_INC', 'bb-includes/' ); // use them require_once ( BB_PATH . BB_INC . 'class.bb-query.php' );
  • 9. Why Enqueue? Can't you just call them in the header.php of a theme or add them there with actions in a plugin? NO! Using enqueue functions makes it easier to manage scripts, stylesheets, their dependants, and where they show up.
  • 10. Enqueue Scripts wp_enqueue_script( $handle, // name of the script $src, //where to find it $deps, // what it depends on to work $ver, // version number of the script $in_footer // whether to load it in the footer or not ); // remove an enqueued script wp_dequeue_script( $handle );
  • 11. Enqueue Styles wp_enqueue_style( $handle, // name $src, //where to find it $deps, // what it depends on to work $ver, // version number of the script $in_footer // whether to load it in the footer or not ); // remove an enqueued style wp_dequeue_style( $handle );
  • 12. Registering wp_deregister_script( $handle ); wp_register_script( $handle, // name of the script $src, //where to find it $deps, // what it depends on to work $ver, // version number of the script $in_footer // whether to load it in the footer or not ); // now you can just... wp_enqueue_script( $handle ); // or use it in $deps
  • 13. Put Them in Their Place ADMIN FRONT END add_action( 'admin_enqueue_scripts' , add_action( 'wp_enqueue_scripts' , 'themename_admin_enqueue' ); 'themename_wp_enqueue' ); function themename_admin_enqueue() { function themename_wp_enqueue() { wp_register_script( ... ); wp_register_script( ... ); wp_register_style( ... ); wp_register_style( ... ); wp_enqueue_script( ... ); wp_enqueue_script( ... ); wp_enqueue_style( ... ); wp_enqueue_style( ... ); if ( get_post_type() == 'page' ) if ( get_post_type() == 'page' ) wp_enqueue_script( ... ); wp_enqueue_script( ... ); } } More Info: http://bit.ly/enqueue
  • 14. Plugin Example // Styles and Scripts add_action( 'admin_enqueue_scripts' , 'recipress_admin_enqueue' ); function recipress_admin_enqueue() { wp_enqueue_script( 'recipress_back' , RECIPRESS_URL . 'js/back.js' , array( 'jquery', 'jquery-ui-sortable' ) ); wp_enqueue_style( 'recipress_back' , RECIPRESS_URL . 'css/back.css' ); } add_action( 'wp_enqueue_scripts' , 'recipress_wp_enqueue' ); function recipress_wp_enqueue() { wp_enqueue_style( 'recipress_front' , RECIPRESS_URL . 'css/front.css' ); }
  • 15. KEEP IT CLEAN Using Separate Code Files
  • 16. Why Include? Can't you just dump all your code into functions.php of a theme or the main plugin file? Yes, but... Large amounts of code are easier to read and edit if they are separated into their own files.
  • 17. Include // files for themes include( get_template_directory_uri() . '/includes/some_function.php' ); // in a plugin include( CONSTANT_BASE . '/includes/some_function.php' );
  • 18. Include, Require, _once // Puts the contents of the file directly where it is called include() // Only lets the script call the file once include_once() // Same as include() but will stop the script if error occurs require() // Same as include_once() with the rules of require() require_once()
  • 19. Plugin Example // Load plugin files include_once( RECIPRESS_DIR . 'php/functions.php' ); include_once( RECIPRESS_DIR . 'php/options.php' ); include_once( RECIPRESS_DIR . 'php/meta_box.php' ); include_once( RECIPRESS_DIR . 'php/taxonomies.php' ); include_once( RECIPRESS_DIR . 'php/output.php' ); include_once( RECIPRESS_DIR . 'php/widgets.php' );
  • 20. REMEMBER ALL THE THINGS! Miscellaneous Memos
  • 21. Theme/Plugin Header Theme: style.css Plugin: plugin_file.php /* /* Theme Name: 10up.com Plugin Name: ReciPress Author: 10up Plugin URI: http://recipress.com Author URI: http://10up.com Version: 1.8 */ */
  • 22. Readme.txt Used automatically in the WordPress.org repository for things like: Stable Tag Description Installation FAQ Screenshots Changelog Update Notice Arbitrary Sections Check your readme: http://wordpress.org/extend/plugins/about/validator
  • 23. Localization // text strings __( 'String of Text' , 'text-domain' ); // Echoing text _e( 'String of Text' , 'text-domain' ); // Explaining text _x( 'String of Text' , 'A string of text' , 'text-domain' ); // Load the text domain add_action( 'init', 'plugin_text_domain' ); function plugin_text_domain() { load_plugin_textdomain( 'text-domain' , false, DEFINED_BASE . '/lang/' ); }
  • 24. Controls class WP_Hotfix_Controller { function init() { add_action( 'init', 'wp_hotfix_init' ); register_activation_hook( __FILE__, array( __CLASS__, 'activate' ) ); register_deactivation_hook( __FILE__, array( __CLASS__, 'deactivate' ) ); } function activate() { add_option( 'hotfix_version' , '1' ); register_uninstall_hook( __FILE__, array( __CLASS__, 'uninstall' ) ); } function deactivate() { delete_option( 'hotfix_version' ); } function uninstall() { self::deactivate(); // The same, for now } }