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

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.

Juliette Reinders Folmer

October 28, 2013
Tweet

More Decks by Juliette Reinders Folmer

Other Decks in Programming

Transcript

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

    View Slide

  2. View Slide

  3. Anatomy of WordPress

    View Slide

  4. Page
    footer
    Admin
    Bar
    Page
    content
    (loop)
    Page
    header
    (Invisible) HTML
    Sidebar
    containing
    widgets
    (Main)
    menu

    View Slide

  5. Admin Bar
    (Invisible) HTML
    Admin
    footer
    Admin
    Menu
    1. Post
    types
    2. Custom-
    izations
    3. Extras
    Admin
    page
    (with
    dashboard
    widgets)

    View Slide

  6. Anatomy of WordPress
    • Core
    • Plugins
    • Themes
    • Languages
    • Js Libraries
    Content via:
    • Post Types
    • Taxonomies
    • Sidebars
    • Widgets
    • Users
    Enhanced with
    Meta data / Custom
    fields

    View Slide

  7. Hooks

    View Slide

  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

    View Slide

  9. The Loop

    View Slide

  10. The Loop
    if ( have_posts() ) {
    while ( have_posts() ) {
    the_post();
    //
    // Post Content here
    //
    } // end while
    } // end if
    ?>

    View Slide

  11. WordPress in practice

    View Slide

  12. wp-config.php Tips & Tricks

    View Slide

  13. View Slide

  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 );

    View Slide

  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' );

    View Slide

  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' );

    View Slide

  17. WordPress in your language

    View Slide

  18. View Slide

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

    View Slide

  20. Theming your site

    View Slide

  21. View Slide

  22. View Slide

  23. Child themes

    View Slide

  24. Creating a child theme

    View Slide

  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 */

    View Slide

  26. Functions.php

    View Slide

  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 );

    View Slide

  28. functions.php
    function favicon_link() {
    echo 'href="http://localhost/wp/favicon.ico" />';
    echo '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' );

    View Slide

  29. View Slide

  30. functions.php
    /* Change admin page footer – Branding */
    function my_admin_footer_text( $left ) {
    $left = 'alt="Advies en zo logo" align="left“
    style="margin-top: 0px; margin-right: 5px;" />
    Webdevelopment, design and consultancy:

    Advies en zo
    ';
    return $left;
    }
    add_filter( 'admin_footer_text', ‘my_admin_footer_text' );

    View Slide

  31. Extending WordPress

    View Slide

  32. View Slide

  33. View Slide

  34. View Slide

  35. Must-use plugins

    View Slide

  36. Create a plugin

    View Slide

  37. Starting a plugin
    /*
    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
    */

    View Slide

  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
    • ...

    View Slide

  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.
    );

    View Slide

  40. View Slide

  41. View Slide

  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 );

    View Slide

  43. View Slide

  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" );' )
    );

    View Slide

  45. View Slide

  46. View Slide

  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

    View Slide

  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() );

    View Slide

  49. Best Practices

    View Slide

  50. Be Unique

    View Slide

  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

    View Slide

  52. Don’t reinvent the wheel

    View Slide

  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

    View Slide

  54. Avoid conflict

    View Slide

  55. Avoid conflict
    • function_exists()
    • class_exists()
    • Jquery no conflicts mode
    • Use bundled libraries

    View Slide

  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-

    View Slide

  57. Be lazy, stay lean

    View Slide

  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()

    View Slide

  59. Be safe

    View Slide

  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

    View Slide

  61. Be wordly

    View Slide

  62. Be worldly
    • GetText
    • UTF-8
    • Impact on data validation
    load_plugin_textdomain('my_plugin', false, dirname(
    plugin_basename( __FILE__ ) ) . '/languages/' );
    sprintf(
    __( 'Post updated. View post',
    'my_plugin' ),
    esc_url( get_permalink( $post_ID ) )
    ),
    esc_html__( 'Custom field updated.', 'my_plugin' );

    View Slide

  63. Let others hook in

    View Slide

  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

    View Slide

  65. Make it beautiful

    View Slide

  66. Pay your dues

    View Slide

  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

    View Slide

  68. Get involved

    View Slide

  69. Help someone who’s
    struggling

    View Slide

  70. Find an abandoned project

    View Slide

  71. Have fun!

    View Slide

  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/

    View Slide

  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/

    View Slide

  74. 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 joined.in/9495
    Endorsements and recommendations on
    LinkedIn are much appreciated too!

    View Slide