Upgrade to Pro — share decks privately, control downloads, hide ads and more …

WordPress for the Win!

WordPress for the Win!

Presented on February 7th 2015 at the SunshinePHP Unconference, Miami, Florida and February 10th 2015 at the JAXWeb/JAXPHP usergroup at Jacksonville, Florida.
---------------------------------------------------------------
With the release of WP3, WordPress has become a serious contender on the CMS market. The WordPress plugin system allows you to add functionality to WordPress in a snap and turn it into much more than 'just a blogging platform'.
Learn how to develop for WordPress like a pro and take WordPress to the next level.

Juliette Reinders Folmer

February 07, 2015
Tweet

More Decks by Juliette Reinders Folmer

Other Decks in Programming

Transcript

  1. Who am I? Self- employed independent consultant 15+ years in

    IT and web development Contributor to LimeSurvey, phpBB, WordPress, AdoDB and more
  2. Page footer Admin Bar Page content (loop) Page header (Invisible)

    HTML <head> Sidebar containing widgets (Main) menu
  3. Admin Bar (Invisible) HTML <head> Admin footer Admin Menu 1.

    Post types 2. Custom- izations 3. Extras Admin page (with dashboard widgets)
  4. Anatomy of WordPress Core Plugins Themes Languages Js Libraries Content

    via: Post Types Taxonomies Sidebars Widgets Users Enhanced with Meta data / Custom fields
  5. Hooks Actions – do something Filters – filter someting and

    return the result See: WordPress Codex Hooks database: http://adambrown.info/p/wp_hooks Debug Bar - Action& filter hooks plugin
  6. The Loop <?php if ( have_posts() ) { while (

    have_posts() ) { the_post(); // // Post Content here // } // end while } // end if ?>
  7. wp-config.php /* Change how WP deals with post revisions, trash

    and auto-saves */ define( 'WP_POST_REVISIONS', 20 ); define( 'AUTOSAVE_INTERVAL', 60 ); // seconds define( 'EMPTY_TRASH_DAYS', 7 ); // days (30) define( 'MEDIA_TRASH', true ); /* Enable Compression en concatenation and cache */ define( 'COMPRESS_CSS', true ); define( 'COMPRESS_SCRIPTS', true ); define( 'CONCATENATE_SCRIPTS', true ); define( 'ENFORCE_GZIP', true ); define( 'WP_CACHE', true ); /* Set up WordPress as Multi-site */ define( 'WP_ALLOW_MULTISITE', true );
  8. wp-config.php /* Force secure logins and admin sessions */ define(

    'FORCE_SSL_LOGIN', true ); define( 'FORCE_SSL_ADMIN', true ); /* Disable Plugin and Theme Update and Installation and/or plugin/theme editor */ define( 'DISALLOW_FILE_EDIT', true ); define( 'DISALLOW_FILE_MODS', true ); /* Disable the new WP 3.7+ auto-updater */ define( 'AUTOMATIC_UPDATER_DISABLED', true ); /* FTP settings */ define( 'FTP_HOST', 'hostname:port' ); define( 'FTP_USER', 'username' ); define( 'FTP_PASS', 'password' );
  9. wp-config.php /* Enable debugging */ define( 'WP_DEBUG', true); define( 'WP_DEBUG_DISPLAY‘,

    true); /* Error logging to wp-content/debug.log */ define( 'WP_DEBUG_LOG', true); /* Load the development (non-minified) versions of all scripts, css, disables compression and concatenation */ define( 'SCRIPT_DEBUG', true); /* Try to increase PHP Memory */ define( 'WP_MEMORY_LIMIT', '128M' );
  10. Child theme – style.css /* Theme Name: Twenty Twelve Child

    Theme URI: http://localhost/ Template: twentytwelve Author: Advies en zo Author URI: http://adviesenzo.nl/ Description: My Child theme Text Domain: twentytwelve Version: 1.0.0 */ @import url("../twentytwelve/style.css"); /* =Theme customization starts here */
  11. Hooking into WP add_action( 'hook_name', 'function_name', $priority = 10, $accepted_args

    = 1 ); add_action( 'hook_name', array( $this, 'method_name' ), $priority = 10, $accepted_args = 1 ); add_action( 'hook_name', array( __CLASS__, 'static_method_name' ), $priority = 10, $accepted_args = 1 ); apply_filter( 'hook_name', 'function_name', $priority = 10, $accepted_args = 1 );
  12. functions.php function favicon_link() { echo '<link rel="shortcut icon" type="image/x-icon" href="http://localhost/wp/favicon.ico"

    />'; echo '<link rel="icon" type="image/ico" href="http://localhost/wp/favicon.ico" />'; } add_action('wp_head', 'favicon_link'); add_action('admin_head', 'favicon_link'); function hide_profile_fields( $contactmethods ) { unset( $contactmethods['aim'] ); unset( $contactmethods['jabber'] ); unset( $contactmethods['yim'] ); return $contactmethods; } add_filter( 'user_contactmethods', 'hide_profile_fields' );
  13. functions.php /* Change admin page footer – Branding */ function

    my_admin_footer_text( $left ) { $left = '<img src="' . get_stylesheet_directory_uri() . '/images/AEZ_logobw-32x32.png" width="32" height="32" alt="Advies en zo logo" align="left“ style="margin-top: 0px; margin-right: 5px;" /> Webdevelopment, design and consultancy: <a href="http://adviesenzo.nl/" title="Advies en zo"> Advies en zo </a>'; return $left; } add_filter( 'admin_footer_text', ‘my_admin_footer_text' );
  14. Starting a plugin <?php /* Plugin Name: Demo Quotes Plugin

    Plugin URI: https://github.com/jrfnl/wp-plugin-best- practices-demo Description: Demo plugin - Best Practices Tutorial Version: 1.0 Author: Juliette Reinders Folmer Author URI: http://adviesenzo.nl/ Text Domain: demo-quotes-plugin Domain Path: /languages/ License: GPL v3 */
  15. What every plugin needs Hook your functionality onto actions and

    filters Loading your localization files Load CSS Load JS Do something Add admin page or add to another admin page Help information Activation/ Upgrade routines Uninstall routines ...
  16. Add custom content types & taxonomies register_post_type( $post_type_name, // Post

    type name. Max of 20 characters. Uppercase and spaces not allowed. $args // Arguments for post type. ); register_taxonomy( $taxonomy_name, // Taxonomy internal name. Max 32 characters. Uppercase and spaces not allowed. array( $post_type_name, ), // Post types to register this taxonomy for $args // Arguments for taxonomy. );
  17. Add a settings page register_setting( $option_group, $option_name, $sanitize_callback ); get/update/delete_option(

    $option_name ); add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $page_slug, $call_back ); add_settings_section( $section_id, $title, $callback, $page_slug ); add_settings_field( $id, $title, $callback, $page_slug, $section_id, $args ); settings_fields( $option_group ) do_settings_sections( $page_slug ); do_settings_fields( $page_slug, $section_id );
  18. Add a widget class My_Widget extends WP_Widget { // widget

    actual processes public function __construct() {} // outputs the content of the widget public function widget( $args, $instance ) {} // outputs the options form on admin public function form( $instance ) {} // processes widget options to be saved public function update( $new_instance, $old_instance ) {} } add_action('widgets_init', create_function( '', 'return register_widget( "My_Widget" );' ) );
  19. (De-)Activation, upgrade, uninstall (De-)Activation: Can’t be added from within a

    class Can use methods within a class Upgrading: No upgrade hook Save plugin version nr to option & compare /* Set up the (de-)activation actions */ register_activation_hook( __FILE__, array( ‘Plugin_Class', 'activate' ) ); register_deactivation_hook( __FILE__, array( ' Plugin_Class ', 'deactivate' ) ); • Uninstall via uninstall.php file
  20. Enqueue scripts & styles wp_register_style( 'handle', plugins_url( 'css/style' . $suffix

    . '.css', __FILE__ ), array(), VERSION, 'all' ); wp_enqueue_style( 'handle' ); wp_register_script( 'handle', plugins_url( 'js/file' . $suffix . '.js', __FILE__ ), array( 'jquery', 'wp-ajax-response' ), VERSION, true // load in footer ); wp_enqueue_script( 'handle' ); wp_localize_script( 'handle', 'i18n_js_objectname', array() );
  21. Be Unique PHP: Classes Functions global vars (global) constants WP:

    shortcodes option(s) / meta fields nonces settings pages custom post types hooks Filenames HTML/CSS: classes, ids Javascript: I18n object functions Multi-lingual I18n text domain Choose your plugin name carefully & implement consistently
  22. Don’t reinvent the wheel Dashboard Widgets API Database API HTTP

    API File Header API Filesystem API Heartbeat API Metadata API Options API Plugin API Quicktags API Rewrite API Settings API Shortcode API Theme modification API Theme customization API Transients API Widgets API XML-RPC WordPress API
  23. Libraries shipped with WP common /wp-admin/js/common.js sack /wp-includes/js/tw-sack.js quicktags /wp-includes/js/quicktags.js

    colorpicker /wp-includes/js/colorpicker.js editor /wp-admin/js/editor.js wp-fullscreen /wp-admin/js/wp-fullscreen.js prototype /wp-includes/js/prototype.js wp-ajax-response /wp-includes/js/wp-ajax-response.js wp-pointer /wp-includes/js/wp-pointer.js autosave /wp-includes/js/autosave.js wp-lists /wp-includes/js/wp-lists.js scriptaculous-root /wp-includes/js/scriptaculous/wp- scriptaculous.js scriptaculous-builder /wp-includes/js/scriptaculous/builder.js scriptaculous-dragdrop /wp-includes/js/scriptaculous/dragdrop.js scriptaculous-effects /wp-includes/js/scriptaculous/effects.js scriptaculous-slider /wp-includes/js/scriptaculous/slider.js scriptaculous-sound /wp-includes/js/scriptaculous/sound.js scriptaculous-controls /wp-includes/js/scriptaculous/controls.js scriptaculous scriptaculous-dragdrop, scriptaculous- slider, scriptaculous-controls, scriptaculous-root cropper /wp-includes/js/crop/cropper.js thickbox /wp-includes/js/thickbox/thickbox.js jcrop /wp-includes/js/jcrop/jquery.Jcrop.js swfobject /wp-includes/js/swfobject.js plupload /wp-includes/js/plupload/plupload.js plupload-html5 wp-includes/js/plupload/plupload.html5.js plupload-flash /wp- includes/js/plupload/plupload.flash.js" plupload-silverlight /wp- includes/js/plupload/plupload.silverlight.js plupload-html4 /wp- includes/js/plupload/plupload.html4.js plupload-full plupload, plupload-html5, plupload-flash, plupload-silverlight, plupload-html4 plupload-handlers /wp-includes/js/plupload/handlers.js swfupload /wp-includes/js/swfupload/swfupload.js swfupload-swfobject /wp- includes/js/swfupload/plugins/swfupload.swfobject.js swfupload-queue /wp- includes/js/swfupload/plugins/swfupload.queue.js jquery /wp-includes/js/jquery/jquery.js (v1.7.2 as of WP 3.3, v1.8.3 as of WP 3.5) jquery-ui-core /wp- includes/js/jquery/ui/jquery.ui.core.min.js jquery-effects-core /wp- includes/js/jquery/ui/jquery.effects.core.min.js jquery-effects-blind /wp- includes/js/jquery/ui/jquery.effects.blind.min.js jquery-effects-bounce /wp- includes/js/jquery/ui/jquery.effects.bounce.min.js jquery-effects-clip /wp- includes/js/jquery/ui/jquery.effects.clip.min.js jquery-effects-drop /wp- includes/js/jquery/ui/jquery.effects.drop.min.js jquery-effects-explode /wp- includes/js/jquery/ui/jquery.effects.explode.min.js jquery-effects-fade /wp- includes/js/jquery/ui/jquery.effects.fade.min.js jquery-effects-fold /wp- includes/js/jquery/ui/jquery.effects.fold.min.js jquery-effects-highlight /wp- includes/js/jquery/ui/jquery.effects.highlight.min.js jquery-effects-pulsate /wp- includes/js/jquery/ui/jquery.effects.pulsate.min.js jquery-effects-scale /wp- includes/js/jquery/ui/jquery.effects.scale.min.js jquery-effects-shake /wp- includes/js/jquery/ui/jquery.effects.shake.min.js jquery-effects-slide /wp- includes/js/jquery/ui/jquery.effects.slide.min.js jquery-effects-transfer /wp- includes/js/jquery/ui/jquery.effects.transfer.min.js jquery-ui-accordion /wp- includes/js/jquery/ui/jquery.ui.accordion.min.js jquery-ui-autocomplete /wp- includes/js/jquery/ui/jquery.ui.autocomplete.min.js jquery-ui-button /wp- includes/js/jquery/ui/jquery.ui.button.min.js jquery-ui-datepicker /wp- includes/js/jquery/ui/jquery.ui.datepicker.min.js jquery-ui-dialog /wp- includes/js/jquery/ui/jquery.ui.dialog.min.js jquery-ui-draggable /wp- includes/js/jquery/ui/jquery.ui.draggable.min.js jquery-ui-droppable /wp- includes/js/jquery/ui/jquery.ui.droppable.min.js jquery-ui-mouse /wp- includes/js/jquery/ui/jquery.ui.mouse.min.js
  24. Be lazy, be lean Use the available is_...() functions Conditional

    loading of include files Conditional loading of css / js both on admin as well as frontend! Minify js and css New in WP3.6: has_shortcode()
  25. Be safe Check early & check often Validation all input

    sanitize_text_field(), sanitize_title(), sanitize_meta() etc Escape all output esc_html(), esc_attr(), esc_url(), esc_textarea(), esc_js() etc Use wp_nonce
  26. Be worldly GetText UTF-8 Impact on data validation load_plugin_textdomain('my_plugin', false,

    dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); sprintf( __( 'Post updated. <a href="%s">View post</a>', 'my_plugin' ), esc_url( get_permalink( $post_ID ) ) ), esc_html__( 'Custom field updated.', 'my_plugin' );
  27. Let others hook in Offer your own action hooks Offer

    your own filter hooks do_action( 'my_unique_action_hook', $var_to_pass ); $filtered_var = apply_filters( 'my_unique_filter_hook', $var_to_pass ); Document using the @api tag
  28. Pay your dues Keep the WP requirements in mind Document

    your code Use the coding standards WordPress coding standards: http://make.wordpress.org/core/handbook/coding- standards/php/ CodeSniffs available: https://github.com/WordPress-Coding-Standards/WordPress- Coding-Standards
  29. Don’t get discouraged WP_DEBUG constants Enable error logging! wp_config.php: @ini_set()

    set_error_handling() to a backtrace function Debug bar to the rescue JS console logging + plugin set_transient() Beware: Lots of templates which do not comply to the WP standards!
  30. Credits Anatomy - Eva di Martino http://www.pureblacklove.com Bridge - Glenn

    Euloth http://www.flickr.com/photos/eulothg/4956082108/ Conflict - Asaf Antman http://www.flickr.com/photos/asafantman/5134136997/ Help - Green Kozi http://www.flickr.com/photos/themacinator/3445776069/ Hooks - Raul Lieberwirth http://www.flickr.com/photos/lanier67/185311136/ Hooks – Macroman (red background) http://www.flickr.com/photos/macroman/34644959/ Alone – Jon http://www.flickr.com/photos/jb-london/3594171841/ Fun - Justin Beckley http://www.flickr.com/photos/justinbeckleyphotography/8452437969/ Lazy - Kevin Cauchi http://www.flickr.com/photos/kpcauchi/5376768095/ Loop - Gabe Kinsman http://www.flickr.com/photos/auguris/5286612308/ Security – kismihok http://www.flickr.com/photos/kismihok/9686252463/
  31. Credits Unique - Luca Volpi (leafs) http://www.flickr.com/photos/luca_volpi/2974346674/ Unique - David

    Sprinks (birds) http://www.flickr.com/photos/davidspinks/4211976336/ Wheel - Pauline Mak http://www.flickr.com/photos/__my__photos/5025541044/ WordPress - mkhmarketing (crayons) http://www.flickr.com/photos/mkhmarketing/8469030267/ WordPress - Tom Woodward (revolution) http://www.flickr.com/photos/bionicteaching/3048825267/ WordPress - Saad Irfan (core, plugins, themes) http://www.flickr.com/photos/saadirfan/5722057280/ CMS Landscape - Philippe Martin http://www.flickr.com/photos/lafabriquedeblogs/5997969999/ World - Kenneth Lu http://www.flickr.com/photos/toasty/1540997910/ Bike - Pauline Mak http://www.flickr.com/photos/__my__photos/6399028713/ Daisies - Steve Wall http://www.flickr.com/photos/stevewall/4780035332/
  32. Keep in touch! (I’m self-employed, you can hire me ;-)

    ) Juliette Reinders Folmer Email: [email protected] Web: http://www.adviesenzo.nl/ LinkedIn: http://nl.linkedin.com/in/julietterf Twitter: http://twitter.com/jrf_nl GitHub: http://github.com/jrfnl/ WordPress: http://profiles.wordpress.org/jrf Please rate this talk on ... ? Endorsements and recommendations on LinkedIn are much appreciated too!