Save 37% off PRO during our Black Friday Sale! »

WordPress for the Win!

WordPress for the Win!

Presented on October 28th 2013 at the International PHP Conference, Munich, Germany.
http://phpconference.com/2013/en
---------------------------------------------------------------
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.

2776198ea9584b6c0d4b494293b8d635?s=128

Juliette Reinders Folmer

October 28, 2013
Tweet

Transcript

  1. Juliette Reinders Folmer | Advies en zo WordPress for the

    Win!
  2. None
  3. Anatomy of WordPress

  4. Page footer Admin Bar Page content (loop) Page header (Invisible)

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

    Post types 2. Custom- izations 3. Extras Admin page (with dashboard widgets)
  6. Anatomy of WordPress • Core • Plugins • Themes •

    Languages • Js Libraries Content via: • Post Types • Taxonomies • Sidebars • Widgets • Users Enhanced with Meta data / Custom fields
  7. Hooks

  8. 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
  9. The Loop

  10. The Loop <?php if ( have_posts() ) { while (

    have_posts() ) { the_post(); // // Post Content here // } // end while } // end if ?>
  11. WordPress in practice

  12. wp-config.php Tips & Tricks

  13. None
  14. 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 );
  15. 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' );
  16. 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' );
  17. WordPress in your language

  18. None
  19. Make WP speak your language • define( 'WPLANG', 'de_DE' );

  20. Theming your site

  21. None
  22. None
  23. Child themes

  24. Creating a child theme

  25. 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 */
  26. Functions.php

  27. 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 );
  28. 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' );
  29. None
  30. 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' );
  31. Extending WordPress

  32. None
  33. None
  34. None
  35. Must-use plugins

  36. Create a plugin

  37. 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 */
  38. 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 • ...
  39. 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. );
  40. None
  41. None
  42. 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 );
  43. None
  44. 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" );' ) );
  45. None
  46. None
  47. (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
  48. 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() );
  49. Best Practices

  50. Be Unique

  51. Be Unique • PHP: – Classes – Functions – global

    vars – (global) constants • WP: – shortcodes – option(s) / meta fields – nonces – settings pages – custom post types / taxonomies – hooks • Filenames • HTML/CSS: – classes, ids • Javascript: – I18n object – functions • Multi-lingual – I18n text domain Choose your plugin name carefully & implement consistently
  52. Don’t reinvent the wheel

  53. 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
  54. Avoid conflict

  55. Avoid conflict • function_exists() • class_exists() • Jquery no conflicts

    mode • Use bundled libraries
  56. 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 • 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-
  57. Be lazy, stay lean

  58. 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()
  59. Be safe

  60. 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
  61. Be wordly

  62. 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' );
  63. Let others hook in

  64. 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
  65. Make it beautiful

  66. Pay your dues

  67. 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
  68. Get involved

  69. Help someone who’s struggling

  70. Find an abandoned project

  71. Have fun!

  72. Image Credits • Anatomy - Eva di Martino http://www.pureblacklove.com •

    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/
  73. Image Credits • Security – kismihok http://www.flickr.com/photos/kismihok/9686252463/ • Unique -

    Luca Volpi (leafs) http://www.flickr.com/photos/luca_volpi/2974346674/ • Wheel - Pauline Mak http://www.flickr.com/photos/__my__photos/5025541044/ • WordPress - mkhmarketing (crayons) http://www.flickr.com/photos/mkhmarketing/8469030267/ • 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/
  74. Keep in touch! (I’m self-employed, you can hire me ;-)

    ) Juliette Reinders Folmer Email: juliette@adviesenzo.nl 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 joined.in/9495 Endorsements and recommendations on LinkedIn are much appreciated too!