33
#complexwp | wplib.org | @mikeschinkel Developing Complex WordPress Sites* *Without Fear of Failure Presenter: Mike Schinkel WordCamp Raleigh 2015

Developing Complex WordPress Sites without Fear of Failure (with MVC)

Embed Size (px)

Citation preview

Page 1: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Developing Complex WordPress Sites**Without Fear of Failure

Presenter: Mike SchinkelWordCamp Raleigh 2015

Page 2: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

What to Expect• Target Audience for the Talk• Overview of Professional Workflow• Use of Object Orientation• Demo of code from a real-world project• How to make it easy by using WPLib

Page 3: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Prerequisites• Experience building WordPress websites

• Comfortable developing in PHP

Page 4: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

About Me

• Self-Styled WordPress Architect• Typical Work: $100k+ Agency Projects • Many WordCamps, LoopConf• WordPress is my 4th developer ecosystem

2006-2009: Drupal1993-2006: Visual Basic 1986-1993: Clipper - a dBase Compiler

• Yada, yada

Page 5: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Avoiding a WordPressHouse of Cards

A.K.A. AvoidingKevin Spacey

Page 6: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Best For Large Budget Projects

Where clients just expect

us to:

Page 7: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

This approach NOT for "Tinkerers"

Who want to fiddle with it after

you leave.

(And then yell at you and ask for support when they break it.)

Page 8: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Disallow Adding of Plugins and Themes in the Admin Consule

• Use a Custom Theme

• Minimize 3rd Party Plugins

Page 9: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Use a Professional Workflow● A Professional IDE

o PhpStorm+XDebug● Version Control/Branching

o For Features, and o For Bug Fixes

● A Deployment Processo Development (Local)o Test Servero Staging Servero Production Server

● See "Advanced WordPress Workflow” o That is Micah Wood's talk, next session...

Page 10: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Use an Intelligent Process• Focus on Requirements

• Create clickable mockups using moqups.com

• Then Architecture• Decide on Post Types, Taxonomies, etc

• Separate Theming from Architecture & Backend Coding• Best if people with the different skills

are in the different roles

• Maximize “Deployable” Code• User-entered Configuration Sux

Page 11: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Use an Object Oriented Architecture•Heard of MVC?

• Embrace Models and Views.

• And Items,• And Lists,• And Applications.

• And Helpers, • And Templates, • And Modules.

• More on those in a bit…

Page 12: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Wherest thou Objects?• Post Types• Taxonomies• User Roles• And more!

Page 13: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

• Controllers = the "C" in MVC

• But Objects/Classes for Routing != WordPress

• But you can usually hack it:

URL Routing In WordPresshttp://tinyurl.com/wp-url-routing

WordPress handles the Controller (mostly)

Page 14: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

DEMO

Reviewing the Code of a Real World Client Project

Warts and All

(see http://github/wplib for online examples)

Page 15: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Make it easy with WPLib• Designed for PHP Developers• Assumes Persistent Cache• Great for Building Reusable Code

Page 16: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

•It is Small• Does not try to do that much

•Highly Consistent!•Presents Structured Constraints•Compatible with (all?) other Frameworks

• WPLib provides incremental value• Can be used a little, or a lot• Solves a problem no one else(?) is addressing

WPLib's Positive Attributes

Page 17: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

• One Application per site

• Provides root class for a site/app.

• Provides global but site-specific functionality, i.e.

$list = MyApp::get_featured_slide_list([$query]);

MyAPP::the_current_campaign_html();

$url = MyAPP::get_asset_url( 'images/visa-logo.png' );

if ( MyApp::is_featured_slider_enabled() ) {

//...

}

The Application Class

Page 18: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Theme Class• One Theme Class per theme

• Put your theme hooks here, e.g.'wp_head''wp_enqueue_scripts'

• Location for theme global functionality, e.g.$theme->the_ad_html();$theme->the_slider_html();

• Lots of functionality in parent class, e.g.$theme->the_header_html(); // same as get_header()$theme->the_site_name();$page_id = $theme->front_page_id();

Page 19: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Model Classes• Most of the “business logic" goes here.

• All the “facts” about a type of Item

• One per Item type

class MyApp_Story_Model extends WPLib_Post_Model {

function has_sponsor() {

$has = get_post_meta( $this->ID(), '_myapp_has_sponsor', true ); return 1 == intval( $has );

}

}

Page 20: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

View Classes• Specific methods for outputting Item info

• One or more Views per Item type

• Maybe one View for HTML, one for JSON, etc.

• Most functionality needed in parent class

class MyApp_Featured_Slide_View extends WPLib_Post_View_Base {

function the_embed_code_html() {echo $this->embed_code();

}

function the_embed_code_textarea() {echo htmlspecialchars( $this->embed_code() );

}

}

Page 21: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Item Classes• Container for a Model and a View.• ONLY class of Model+View+Item you actually use• Most functionality in the parent class• Rarely has much if any code

class MyApp_Campaign extends WPLib_Post_Base {

const POST_TYPE = MyApp_Campaigns::POST_TYPE; const VAR_NAME = 'campaign';

}

Page 22: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

List Classes• Smart arrays of Items• Can be custom classes with use-case specific methods• But usually you only need the Default List Class

foreach( MyApp_Featured_Slides::get_list() as $slide ) {$slide->the_template( 'slide-card' );

}

// OR JUST:

MyApp_Featured_Slides::get_list()->the_template( 'slide-card' );

Page 23: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Helper Classes•Think of a Helper as "A List of Related Functions"

•Contributes Static Methods •To your Application class•We do the same for the WPLib class

•Enables making small, easy to learn APIs•The Application class is the method "router"•Helper Method names must be unique across an Application

•Better approach than a single "God" Class•Allows for many smaller files •Clearer source code organization •Better source file management

Page 24: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Helper Classes (cont'd)class MyApp_Date_Range extends WPLib_Module_Base { static $_post_types = array(); static function on_load() { self::register_helper( __CLASS__, 'MyApp' ); } static function register_date_range_post_type( $post_type ) { self::$_post_types[ $post_type ] = $post_type; } static function date_range_post_types() { return self::$_post_types; }}MyApp_Date_Range::on_load();

//----------MyApp::register_date_range_post_type( MyApp_Story::POST_TYPE );print_r( MyApp::date_range_post_types() );

Page 25: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Module Classes• Provides Functionality

• Like a Plugin

• Designed for Developers• Unlike a Plugin

• Designed to be small • If one grows too big, split it up!

• Should be highly cohesive• Group related functionality together

Page 26: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

• A Main "Entry Point" file• Contains a main class• Should hook all hooks needed on page load• Optimized to load efficiently

• Zero or more /includes/ files• One class per file• Include files are autoloaded

• Architected to be Composible• Reusability: Yeah Baby!

Module Classes (cont'd)

Page 27: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

WPLib Templates• Like Template Parts

• Not template files like single.php, home.php, et. al.

• Typically scoped to an Item • Or scoped to the Theme class ($theme) • Or with no scope (called using MyApp::)

• Loaded by $item->the_template('part') method• Templates in {theme}/templates/{part}.php

Page 28: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Constraints are your Friends• Templates should contain NO

implementation details

•Should contain ONLY site-specific HTML or CSS and method calls.

•No WP_Query, no get_post_meta(), etc.

Page 29: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

• Contains NO site-specific HTML or CSS•Auto-generate "the_" methods

•For rendering output•Conventions for escaping output

•"_url"•"_attr"•"_html" •suffix, etc.

View Methods

Page 30: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

A Few Well-Known Constants•POST_TYPE

•Use to specify the post type in a Post Type Module.

•TAXONOMY•Use to specify the taxonomy in a Taxonomy Module.

•ROLE•Use to specify the user role in a User Role Module.

•VAR_NAME•Use to specify an $item's auto assigned variable name in a template.

•INSTANCE_CLASS•Use to specify the $item's class name in an MVI module class.

Page 31: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

To Learn More about WPLib•Clone from GitHub, Review sample apps:

•github.com/wplib

•Visit wplib.org •For Quick Start and other Docs

•Submit issues on GitHub:•github.com/wplib/wplib/issues

•Ask questions on Twitter:•@mikeschinkel / @wpscholar

•Discuss on Slack•Ok: wordpress.slack.com (mikeschinkel/wpscholar)•Best: thecodersguild.slack.com#wplib

•Email [email protected] for access

Page 32: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

Questions?

Page 33: Developing Complex WordPress Sites without Fear of Failure (with MVC)

#complexwp | wplib.org | @mikeschinkel

THANK YOU

Mike [email protected]

about.me/mikeschinkel

See also: www.slideshare.net/mikeschinkel