developing complex wordpress sites without fear of failure (with mvc)

Post on 13-Apr-2017

1.349 Views

Category:

Internet

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

#complexwp | wplib.org | @mikeschinkel

Developing Complex WordPress Sites**Without Fear of Failure

Presenter: Mike SchinkelWordCamp Raleigh 2015

#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

#complexwp | wplib.org | @mikeschinkel

Prerequisites• Experience building WordPress websites

• Comfortable developing in PHP

#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

#complexwp | wplib.org | @mikeschinkel

Avoiding a WordPressHouse of Cards

A.K.A. AvoidingKevin Spacey

#complexwp | wplib.org | @mikeschinkel

Best For Large Budget Projects

Where clients just expect

us to:

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

#complexwp | wplib.org | @mikeschinkel

Disallow Adding of Plugins and Themes in the Admin Consule

• Use a Custom Theme

• Minimize 3rd Party Plugins

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

#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

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

#complexwp | wplib.org | @mikeschinkel

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

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

#complexwp | wplib.org | @mikeschinkel

DEMO

Reviewing the Code of a Real World Client Project

Warts and All

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

#complexwp | wplib.org | @mikeschinkel

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

#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

#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

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

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

}

}

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

}

}

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

}

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

#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

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

#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

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

#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

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

#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

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

#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 mike@newclarity.net for access

#complexwp | wplib.org | @mikeschinkel

Questions?

#complexwp | wplib.org | @mikeschinkel

THANK YOU

Mike Schinkelmike@newclarity.net

about.me/mikeschinkel

See also: www.slideshare.net/mikeschinkel

top related