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

WordPress for the Win! - Zendcon

WordPress for the Win! - Zendcon

Presented on October 21st 2015 at Zendcon, Las Vegas, Nevada, USA.
http://www.zendcon.com/
---------------------------------------------------------------
WordPress nowadays powers more than 20% of all websites and with its extensive plugin infrastructure, is a serious contender on the CMS market. The learning curve for PHP developers to work with WP is very shallow compared to, for instance, Drupal or Typo3.
In this talk, aimed at experienced PHP developers, I will introduce you to essential WordPress concepts and functionality which will allow you to start rapid development using WordPress.
Learn how to develop for WordPress like a pro and take WordPress to the next level.
---------------------------------------------------------------

If you download the slides, the links should be clickable. Unfortunately they don't seem to be in the online deck, so here's a list of relevant & interesting links in semi-random order:

The Basics:
------------------------------
https://codex.wordpress.org/
https://developer.wordpress.org/reference/
http://adambrown.info/p/wp_hooks
https://codex.wordpress.org/Plugin_API
https://codex.wordpress.org/Plugin_API/Action_Reference
https://codex.wordpress.org/Plugin_API/Filter_Reference
https://codex.wordpress.org/The_Loop

WordPress in Your language:
------------------------------
https://make.wordpress.org/polyglots/handbook/tools/glotpress-translate-wordpress-org/
https://translate.wordpress.org/

wp-config.php Tips & Tricks
------------------------------
https://codex.wordpress.org/Editing_wp-config.php

WP Cron
------------------------------
https://developer.wordpress.org/plugins/cron/
https://wordpress.org/plugins/wp-cron-control/

Theming your Site
------------------------------
https://wordpress.org/themes
https://codex.wordpress.org/Child_Themes
http://wphierarchy.com/
https://make.wordpress.org/themes/

Functions.php
------------------------------
https://codex.wordpress.org/Functions_File_Explained
https://codex.wordpress.org/Function_Reference/add_theme_support
https://codex.wordpress.org/Function_Reference/register_nav_menu
https://codex.wordpress.org/Function_Reference/register_sidebar
https://codex.wordpress.org/Theme_Customization_API

Extending WordPress
------------------------------
http://wordpress.org/plugins/
https://codex.wordpress.org/Must_Use_Plugins

Create a Plugin
------------------------------
https://make.wordpress.org/plugins/
https://codex.wordpress.org/Writing_a_Plugin
https://codex.wordpress.org/Shortcode_API
https://codex.wordpress.org/Embeds
https://codex.wordpress.org/Function_Reference/register_post_type
https://codex.wordpress.org/Function_Reference/register_taxonomy
https://codex.wordpress.org/Settings_API
https://codex.wordpress.org/Widgets_API
https://codex.wordpress.org/Function_Reference/wp_enqueue_style
https://codex.wordpress.org/Function_Reference/wp_enqueue_script
https://codex.wordpress.org/Function_Reference/wp_localize_script
https://developer.wordpress.org/plugins/the-basics/activation-deactivation-hooks/
https://developer.wordpress.org/plugins/the-basics/uninstall-methods/

Doing Things the WordPress Way
------------------------------
https://codex.wordpress.org/WordPress_APIs
http://codex.wordpress.org/Function_Reference

Developing & Debugging
------------------------------
https://wordpress.org/plugins/search.php?q=debug+bar
https://wordpress.org/plugins/developer/
https://wordpress.org/plugins/piglatin/
https://wordpress.org/plugins/user-switching/
https://wordpress.org/plugins/log-deprecated-notices/
https://wordpress.org/plugins/whats-running/
https://wordpress.org/plugins/demo-data-creator/
https://wordpress.org/plugins/theme-check/
https://wordpress.org/plugins/rtl-tester/

https://make.wordpress.org/core/handbook/best-practices/coding-standards/
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
https://make.wordpress.org/core/handbook/testing/automated-testing/phpunit/
https://github.com/Varying-Vagrant-Vagrants/VVV
http://wp-cli.org/
http://wpcligui.com/
https://generatewp.com/
http://wpgear.org/
http://wpackagist.org/
http://tgmpluginactivation.com/

Closing
------------------------------
http://twitter.com/jrf_nl
http://profiles.wordpress.org/jrf

Bonus (re: question from the audience)
------------------------------
Moving WP - DB search & replace tool:
https://interconnectit.com/products/search-and-replace-for-wordpress-databases/

Juliette Reinders Folmer

October 21, 2015
Tweet

More Decks by Juliette Reinders Folmer

Other Decks in Programming

Transcript

  1. #zendcon  Themes  Plugins  SEO  Ease of

    use  Scalability  Support community  Regular updates  Learning curve  Setup costs  Maintenance costs  Hacker target
  2. #zendcon Page footer Admin Bar Page content (loop) Page header

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

    1. Post types 2. Custom- izations 3. Extras Admin page (with dashboard widgets)
  4. #zendcon Anatomy of WordPress Functionality  Core  Plugins 

    Themes  Languages  Js Libraries Content  Post Types  Taxonomies  Widgets  Users  Meta data/custom fields  Options  Shortcodes  OEmbeds
  5. #zendcon Hooks See:  WordPress Codex & Developer Reference 

    Hooks database: http://adambrown.info/p/wp_hooks  Debug Bar – Action & filter hooks plugin
  6. #zendcon Hooking into WP apply_filter( 'hook_name', 'function_name', $priority = 10,

    $accepted_args = 1 ); 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 );
  7. #zendcon Action Hooks Front-end muplugins _loaded plugins _loaded setup _theme

    set_current _user after_setup _theme init wp_loaded parse _request posts _selection wp wp_head the_post wp_meta wp_footer admin_bar_ menu
  8. #zendcon Action Hooks Back-end muplugins _loaded plugins _loaded setup _theme

    set_current _user after_setup _theme init wp_loaded admin _menu admin_init current _screen load- {page} posts_select ion wp admin_head admin_bar _menu admin _notices the_post admin _footer
  9. #zendcon Action Hooks Back-end muplugins _loaded plugins _loaded setup _theme

    set_current _user after_setup _theme init wp_loaded admin _menu admin_init current _screen load- {page} posts_select ion wp admin_head admin_bar _menu admin _notices the_post admin _footer
  10. #zendcon The Loop <?php if ( have_posts() ) : while

    ( have_posts() ) : the_post(); // // Post Content here // the_title() // the_content() // the_permalink() // ... endwhile; endif;
  11. #zendcon Localized  ~60 languages + ~30 > 50% 

    GlotPress translate.wordpress.org
  12. #zendcon Manage Saved Data <?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', 30 ); // days define( 'MEDIA_TRASH', true );
  13. #zendcon Performance <?php /* 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 );
  14. #zendcon Multisite <?php /* Set up WordPress as Multi-site */

    define( 'WP_ALLOW_MULTISITE', true ); define( 'NOBLOGREDIRECT', 'http://mywp.com' ); /* After setup - will be provided by WP */ define( 'MULTISITE', true ); define( 'SUBDOMAIN_INSTALL', true ); define( 'DOMAIN_CURRENT_SITE', 'mywp.com' ); define( 'PATH_CURRENT_SITE', '/' ); define( 'SITE_ID_CURRENT_SITE', 1 ); define( 'BLOG_ID_CURRENT_SITE', 1 );
  15. #zendcon Custom User Tables <?php /* Overrule the WP User

    tables */ define( 'CUSTOM_USER_TABLE', $table_prefix . 'my_users' ); define( 'CUSTOM_USER_META_TABLE', $table_prefix . 'my_usermeta' );
  16. #zendcon SSL <?php /* Force secure logins and admin sessions

    */ define( 'FORCE_SSL_LOGIN', true ); define( 'FORCE_SSL_ADMIN', true );
  17. #zendcon PHP Memory Limit <?php /* Try to increase PHP

    Memory */ define( 'WP_MEMORY_LIMIT', '128M' ); /* Potentially increase it even more in the admin area */ define( 'WP_MAX_MEMORY_LIMIT', '256M' );
  18. #zendcon No File Editing <?php /* Disable Plugin and Theme

    Update and Installation and/or plugin/theme editor */ define( 'DISALLOW_FILE_EDIT', true ); define( 'DISALLOW_FILE_MODS', true );
  19. #zendcon Limit External URL Access <?php /* Block WP from

    making external calls */ define( 'WP_HTTP_BLOCK_EXTERNAL', true ); /* Limit allowed external hosts */ define( 'WP_ACCESSIBLE_HOSTS', 'api.wordpress.org,*.github.com' );
  20. #zendcon Custom Directory Paths [1] <?php /* Overrule some directory

    and url paths. Mind: no traling slashes! */ define( 'WP_CONTENT_DIR', dirname( __FILE__ ) . '/blog/wp-content' ); define( 'WP_CONTENT_URL', 'http://mywp.com/blog/wp-content' ); define( 'UPLOADS', 'blog/wp-content/uploads' ); // Relative to ABSPATH
  21. #zendcon Custom Directory Paths [2] <?php /* Overrule some directory

    and url paths. Mind: no traling slashes! */ define( 'WP_PLUGIN_DIR', dirname( __FILE__ ) . '/blog/wp-content/plugins' ); define( 'WP_PLUGIN_URL', 'http://mywp.com/blog/wp-content/plugins' ); define( 'WPMU_PLUGIN_DIR', dirname( __FILE__ ) . '/blog/wp-content/mu-plugins' ); define( 'WPMU_PLUGIN_URL', 'http://mywp.com/blog/wp-content/mu-plugins');
  22. #zendcon Adjust Auto-Updating <?php /* Disable the auto-updater (WP 3.7+)

    */ define( 'AUTOMATIC_UPDATER_DISABLED', true ); /* Use true/false to change the default behavior */ define( 'WP_AUTO_UPDATE_CORE', 'minor' ); /* Prevent the table upgrade function being run in favor of manually running it */ define( 'DO_NOT_UPGRADE_GLOBAL_TABLES', true );
  23. #zendcon FTP Credentials <?php /* FTP settings */ define( 'FTP_HOST',

    'hostname:port' ); define( 'FTP_USER', 'username' ); define( 'FTP_PASS', 'password' ); define( 'FTP_SSL', true );
  24. #zendcon Debugging <?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 non-minified versions of all scripts, css, disables compression and concatenation */ define( 'SCRIPT_DEBUG', true);
  25. #zendcon Basic Query Debugging <?php /* Remember the DB queries

    run for the current page. */ define( 'SAVEQUERIES', true );
  26. #zendcon Adjust WP-Cron <?php /* Prevent Cron running too often

    (plugins) */ define( 'WP_CRON_LOCK_TIMEOUT', 60 ); // seconds /* Run wp-cron with a redirect */ define('ALTERNATE_WP_CRON', true);
  27. #zendcon Disable WP-Cron <?php /* Disable WP-cron in favor of

    real cron */ define( 'DISABLE_WP_CRON', true );
  28. #zendcon Real Cron with Cron Control */5 * * *

    * /usr/local/bin/php -q /path/to/wp/wp- content/plugins/wp-cron-control/wp-cron- control.php http://mywp.com 38a37a2d5b94bc02ce0472a238d493df wget -q 'http://mywp.com/wp- cron.php?doing_wp_cron&38a37a2d5b94bc02ce0472a238 d493df'
  29. #zendcon Child Theme – style.css /* Theme Name: Twenty Fifteen

    Child Theme URI: http://localhost/ Template: twentyfifteen Author: Advies en zo Author URI: http://adviesenzo.nl/ Description: My Child theme Text Domain: twentyfifteen-child Version: 1.0.0 */
  30. #zendcon Example singular.php <?php get_header(); ?> <div id="primary" class="content-area"> <?php

    while ( have_posts() ) : the_post(); if ( is_singular( array( 'employee' ) ) ) { get_template_part( 'template-parts/content', 'employee' ); } else { get_template_part( 'template-parts/content', 'singular' ); } endwhile; ?> </div><!-- #primary --> <?php get_footer(); ?>
  31. #zendcon Typical Theme Setup Functions // Hook 'after_setup_theme' add_theme_support( 'post-formats',

    $formats ); add_theme_support( 'post-thumbnails', $post_types ); add_theme_support( 'custom-background', $defaults ); add_theme_support( 'custom-header', $defaults ); add_theme_support( 'automatic-feed-links' ); // RSS add_theme_support( 'html5', $locations ); add_theme_support( 'title-tag' ); // WP 4.1+ // Hook 'init' register_nav_menus(); // Hook 'widget_init' register_sidebars();
  32. #zendcon Theme Customizer class MyTheme_Customizer { public static function register(

    $customizer ) { $customizer->add_section( 'my_section', $args ); $customizer->add_setting( 'my_setting', $args ); $customizer->add_control( $id, $args ); } public static function header_output() { // Customizer CSS } } add_action( 'customize_register', array( 'MyTheme_Customizer', 'register' ) ); add_action( 'wp_head', array( 'MyTheme_Customizer', 'header_output' ) );
  33. #zendcon functions.php function add_qr_code( $content ) { $url = 'http://api.qrserver.com/v1/create-

    qr-code/?size=100x100&data=' . urlencode( get_the_permalink() ); $esc_alt = the_title_attribute( array( 'before' => 'QR Code for', 'echo' => false ) ); return '<div class="qr-code"> <img src="' . esc_url( $url ) . '“ alt="' . $esc_alt . '"/> </div>' . $content; } add_filter( 'the_content', 'add_qr_code' );
  34. #zendcon functions.php /* Change admin page footer Branding */ function

    my_admin_footer_text( $left ) { $left = '<img src="' . esc_url( get_stylesheet_directory_uri() . '/images/AEZ_logobw- 32x32.png' ) . '" width="32" height="32" align="left" />' . esc_html__( 'Webdevelopment, design and consultancy:', 'text-domain' ) . '<a href="http://adviesenzo.nl/">Advies en zo</a>'; return $left; } add_filter( 'admin_footer_text', my_admin_footer_text' );
  35. #zendcon Loading Order wp-config.php Must-use plugins Plugins • [MS] Network-activated

    plugins • Site-activated plugins Theme • Child-theme functions.php • Parent-theme functions.php
  36. #zendcon 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 */
  37. #zendcon What Every Plugin Needs  Hook your functionality onto

    actions and filters  Loading your localization files  Do something  Load CSS  Load JS  Add admin page or add to another admin page  Help information  Activation/ Upgrade routines  Uninstall routines  ...
  38. #zendcon Add a shortcode function display_call_to_action( $atts ) { $atts

    = shortcode_atts( array( 'user' => 'office', // Default ), $atts, 'calltoaction' ); $user = get_user_by( 'login', $atts['user'] ); $html = ''; if( $user ) { $html = '<!-- Here goes the actual box html -->'; } return $html; } add_shortcode( 'calltoaction', 'display_call_to_action' );
  39. #zendcon Add Oembed Provider // Register Speakerdeck as an oembed

    provider. function add_speakerdeck_oembed() { wp_oembed_add_provider( // URL format '`http[s]?://(www\.)?speakerdeck\.com/[^/]*/.*`i', // Endpoint 'https://speakerdeck.com/oembed.json', true // Is format a regex ? ); } add_action( 'init', 'add_speakerdeck_oembed' );
  40. #zendcon Add Custom Content Types & Taxonomies register_post_type( $post_type_name, //

    Post type name. Max of 20 chars. Uppercase and spaces not allowed. $args // Arguments for post type. ); register_taxonomy( $taxonomy_name, // Taxonomy internal name. Max 32 chars. Uppercase and spaces not allowed. array( $post_type_name ), // Post types to register this taxonomy for. $args // Arguments for taxonomy. );
  41. #zendcon 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 );
  42. #zendcon 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" );' ) );
  43. #zendcon 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() );
  44. #zendcon (De-)Activation, Upgrade, Uninstall  (De-)Activation:  Upgrading -> save

    plugin version nr & compare  Uninstall -> uninstall.php file /* Set up the (de-)activation actions */ register_activation_hook( __FILE__, array( 'Plugin_Class', 'activate' ) ); register_deactivation_hook( __FILE__, array( 'Plugin_Class', 'deactivate' ) );
  45. #zendcon 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 REST API * Rewrite API Settings API Shortcode API Theme modification API Theme customization API Transients API Widgets API XML-RPC WordPress API * Expected in WP 4.4
  46. #zendcon Use WP Functions PHP  mysqli_...()  file_put_contents() 

    json_encode()  mail()  unserialize()  htmlspecialchars()  add/stripslashes()  strtotime() / date()  http_build_query()  $_SERVER['HTTPS'] ... WP  $wpdb->....()  $wp_filesystem->put_contents()  wp_json_encode()  wp_mail()  maybe_unserialize()  esc_html()  wp_unslash()  mysql2date() / current_time()  add_query_arg()  is_ssl() ... (I mean it!)
  47. #zendcon Useful Plugins Debug Bar + Extensions Developer Pig Latin

    User Switching Log Deprecated Notices What’s Running Demo Data Theme Check RTL Tester
  48. #zendcon Helpful Infrastructure WordPress Coding Standards CS WP Unit Testing

    Framework Varying Vagrant Vagrants WP CLI Generate WP WP Gear WPackagist vs TGMPA
  49. #zendcon Photo Credits  WordPress - mkhmarketing (crayons) http://www.flickr.com/photos/mkhmarketing/8469030267/ 

    Bridge - Glenn Euloth http://www.flickr.com/photos/eulothg/4956082108/  WordPress - Jenn Vargas http://www.flickr.com/photos/foreverdigital/2768397344/  Billie Holiday – William P. Gottlieb http://lcweb2.loc.gov/diglib/ihas/loc.natlib.gottlieb.04251/default.html  Anatomy - Eva di Martino http://www.pureblacklove.com  Hooks - Raul Lieberwirth http://www.flickr.com/photos/lanier67/185311136/  Loop - Gabe Kinsman http://www.flickr.com/photos/auguris/5286612308/  WordPress - Saad Irfan (core, plugins, themes) http://www.flickr.com/photos/saadirfan/5722057280/