Share
Embed
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 PRO
October 28, 2013
Transcript
74 slides
-
Page footer Admin Bar Page content (loop) Page header (Invisible)
HTML <head> Sidebar containing widgets (Main) menu -
Admin Bar (Invisible) HTML <head> Admin footer Admin Menu 1.
Post types 2. Custom- izations 3. Extras Admin page (with dashboard widgets) -
Anatomy of WordPress • Core • Plugins • Themes •
Languages • Js Libraries Content via: • Post Types • Taxonomies • Sidebars • Widgets • Users Enhanced with Meta data / Custom fields -
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 -
The Loop <?php if ( have_posts() ) { while (
have_posts() ) { the_post(); // // Post Content here // } // end while } // end if ?> -
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 ); -
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' ); -
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' ); -
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 */ -
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 ); -
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' ); -
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' ); -
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 */ -
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 • ... -
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. ); -
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 ); -
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" );' ) ); -
(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 -
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() ); -
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 -
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 -
Avoid conflict • function_exists() • class_exists() • Jquery no conflicts
mode • Use bundled libraries -
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- -
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() -
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 -
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' ); -
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 -
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 -
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/ -
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/ -
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!