Slide 1

Slide 1 text

WordPress For The Win! Juliette Reinders Folmer / @jrf_nl

Slide 2

Slide 2 text

#zendcon

Slide 3

Slide 3 text

#zendcon Who Am I? Self-employed, Independent Consultant Creator PHPCheatsheets phpcheatsheets.com Frequent Contributor to Open Source Projects

Slide 4

Slide 4 text

#zendcon

Slide 5

Slide 5 text

#zendcon  Themes  Plugins  SEO  Ease of use  Scalability  Support community  Regular updates  Learning curve  Setup costs  Maintenance costs  Hacker target

Slide 6

Slide 6 text

#zendcon

Slide 7

Slide 7 text

#zendcon Anatomy of WordPress

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

#zendcon Anatomy of WordPress Functionality  Core  Plugins  Themes  Languages  Js Libraries Content  Post Types  Taxonomies  Widgets  Users  Meta data/custom fields  Options  Shortcodes  OEmbeds

Slide 11

Slide 11 text

#zendcon Hooks

Slide 12

Slide 12 text

#zendcon Hooks See:  WordPress Codex & Developer Reference  Hooks database: http://adambrown.info/p/wp_hooks  Debug Bar – Action & filter hooks plugin

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

#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

Slide 15

Slide 15 text

#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

Slide 16

Slide 16 text

#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

Slide 17

Slide 17 text

#zendcon The Loop

Slide 18

Slide 18 text

#zendcon The Loop

Slide 19

Slide 19 text

#zendcon WordPress in Practice

Slide 20

Slide 20 text

WordPress in Your Language

Slide 21

Slide 21 text

#zendcon Localized  ~60 languages + ~30 > 50%  GlotPress translate.wordpress.org

Slide 22

Slide 22 text

wp-config.php Tips & Tricks

Slide 23

Slide 23 text

#zendcon

Slide 24

Slide 24 text

#zendcon Manage Saved Data

Slide 25

Slide 25 text

#zendcon Performance

Slide 26

Slide 26 text

#zendcon Multisite

Slide 27

Slide 27 text

#zendcon Custom User Tables

Slide 28

Slide 28 text

#zendcon SSL

Slide 29

Slide 29 text

#zendcon PHP Memory Limit

Slide 30

Slide 30 text

#zendcon No File Editing

Slide 31

Slide 31 text

#zendcon Limit External URL Access

Slide 32

Slide 32 text

#zendcon Custom Directory Paths [1]

Slide 33

Slide 33 text

#zendcon Custom Directory Paths [2]

Slide 34

Slide 34 text

#zendcon Adjust Auto-Updating

Slide 35

Slide 35 text

#zendcon

Slide 36

Slide 36 text

#zendcon FTP Credentials

Slide 37

Slide 37 text

#zendcon Debugging

Slide 38

Slide 38 text

#zendcon Basic Query Debugging

Slide 39

Slide 39 text

WP Cron

Slide 40

Slide 40 text

#zendcon WP Cron

Slide 41

Slide 41 text

#zendcon Adjust WP-Cron

Slide 42

Slide 42 text

#zendcon Disable WP-Cron

Slide 43

Slide 43 text

#zendcon

Slide 44

Slide 44 text

#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'

Slide 45

Slide 45 text

Theming Your Site

Slide 46

Slide 46 text

#zendcon

Slide 47

Slide 47 text

#zendcon

Slide 48

Slide 48 text

Child Themes

Slide 49

Slide 49 text

#zendcon Creating a Child Theme

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

#zendcon Template Hierarchy Source: http://wphierarchy.com/

Slide 52

Slide 52 text

#zendcon Example singular.php

Slide 53

Slide 53 text

Functions.php

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

#zendcon Theme Customizer

Slide 57

Slide 57 text

#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 '
' . $content; } add_filter( 'the_content', 'add_qr_code' );

Slide 58

Slide 58 text

#zendcon

Slide 59

Slide 59 text

#zendcon

Slide 60

Slide 60 text

#zendcon functions.php /* Change admin page footer Branding */ function my_admin_footer_text( $left ) { $left = '' . esc_html__( 'Webdevelopment, design and consultancy:', 'text-domain' ) . 'Advies en zo'; return $left; } add_filter( 'admin_footer_text', my_admin_footer_text' );

Slide 61

Slide 61 text

Extending WordPress

Slide 62

Slide 62 text

#zendcon

Slide 63

Slide 63 text

#zendcon

Slide 64

Slide 64 text

#zendcon

Slide 65

Slide 65 text

#zendcon Must-use Plugins

Slide 66

Slide 66 text

#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

Slide 67

Slide 67 text

Create a Plugin

Slide 68

Slide 68 text

#zendcon Starting a Plugin

Slide 69

Slide 69 text

#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  ...

Slide 70

Slide 70 text

#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 = ''; } return $html; } add_shortcode( 'calltoaction', 'display_call_to_action' );

Slide 71

Slide 71 text

#zendcon

Slide 72

Slide 72 text

#zendcon

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

#zendcon

Slide 75

Slide 75 text

#zendcon

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

#zendcon

Slide 78

Slide 78 text

#zendcon

Slide 79

Slide 79 text

#zendcon

Slide 80

Slide 80 text

#zendcon

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

#zendcon

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

#zendcon

Slide 85

Slide 85 text

#zendcon

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

Doing Things the WordPress Way

Slide 89

Slide 89 text

#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

Slide 90

Slide 90 text

#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!)

Slide 91

Slide 91 text

Developing & Debugging

Slide 92

Slide 92 text

#zendcon Useful Plugins Debug Bar + Extensions Developer Pig Latin User Switching Log Deprecated Notices What’s Running Demo Data Theme Check RTL Tester

Slide 93

Slide 93 text

#zendcon Tools

Slide 94

Slide 94 text

#zendcon Helpful Infrastructure WordPress Coding Standards CS WP Unit Testing Framework Varying Vagrant Vagrants WP CLI Generate WP WP Gear WPackagist vs TGMPA

Slide 95

Slide 95 text

Thank You! Slides: http://speakerdeck.com/jrf Feedback: https://joind.in/15565 Contact me: @jrf_nl jrf

Slide 96

Slide 96 text

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