stop repeating yourself: modularized wordpress development
TRANSCRIPT
Who We AreJIM BARNES
Web Applications Programmer4 years at UCF
https://github.com/jmbarne3
JO DICKSON
Web Applications Programmer4 years at UCF
https://github.com/cjg89
HEW2016 — #DPA5 SLIDE 2
UCF Web Communications• Part of UCF Marketing
• Team of 5 (4 developers, 1 director)
• Responsible for development of top-level websites and applications for the university
• Develop and maintain sites for various departments, organizations, and colleges
HEW2016 — #DPA5 SLIDE 3
Current Theme Development• Most functionality provided for the site is defined in the theme
• New themes are based on a generic theme with helper functions for faster development
• Contains a base set of PHP functions, CSS and JavaScript that is reproduced with each new theme
• Minimal reliance on plugins
• Build sites, not themes
HEW2016 — #DPA5 SLIDE 5
Current Theme Tools• Abstract classes for custom post types, custom taxonomies
and shortcodes
• Support for adding custom meta fields to custom post types
• Support for quickly adding common configuration items
• Useful UI features, like a shortcode WYSIWYG GUI
HEW2016 — #DPA5 SLIDE 6
Custom Post TypesWhat You Need
• Title
• Singular Name
• Plural Name
• Standard Options
• Fields
What You Get
• Registration Logic
• Name Generation
• Automatic ShortcodeRegistration
• Metaboxes and Fields
HEW2016 — #DPA5 SLIDE 7
!News
"Events
#People
$Carousel
%ThemeCode
!News
#People
!News
"Events
#People
%ThemeCode
%ThemeCode
%ThemeCode
%ThemeCode
#People
$Carousel
"Events
$Carousel
HEW2016 — #DPA5 SLIDE 8
& Simplified Deployment
' Maximum Customization
% Centralization of Code Base
( Reduction in client resources (CSS/JS)
) Little to no plugin bloat
AdvantagesHEW2016 — #DPA5 SLIDE 9
Disadvantages
* We Repeat Ourselves
+ Duplication of Features and Styles
, Decentralized Bug Fixes
Data loss on theme change
. Not WordPress best practices
HEW2016 — #DPA5 SLIDE 10
WordPress Best PracticesThemes
• Provide look and feel• Page and post templates
• Stylesheet
• JavaScript necessary for look and feel
Plugins
• Provide functionality• Custom Post Types and
Taxonomies
• Shortcodes
• Widgets
• APIs
HEW2016 — #DPA5 SLIDE 12
Challenges with the “WordPress Way”
• Dependency management
• Heavy per-site customizations, in bulk
• Plugin bloat
• Minified asset delivery
HEW2016 — #DPA5 SLIDE 13
!News
"Events
#People
$Carousel
%ThemeCode
!News
#People
!News
"Events
#People
%ThemeCode
%ThemeCode
%ThemeCode
%ThemeCode
#People
$Carousel
"Events
$Carousel
HEW2016 — #DPA5 SLIDE 21
!News
"Events
#People
$Carousel
%ThemeCode
%ThemeCode
%ThemeCode
%ThemeCode
%ThemeCode
HEW2016 — #DPA5 SLIDE 22
Theme, or Plugin?• Theme: look and feel
• Plugins: content and functionality
If the code were to be placed in a theme, and the theme was then switched out, would you miss its functionality?• Yes: plugin code
• No: theme code
HEW2016 — #DPA5 SLIDE 24
Separation of Concerns(Content vs. Presentation)
Theme• Layout
• Page and Post Templates
• Menu Locations
• Sidebars
• Presentation-related functions
• Styles• Theme specific styles
• Overrides for plugin provided markup, specific to theme
• Presentation Configuration• Theme mods
Plugins• Functionality
• Widgets
• Shortcodes
• Data-related functions
• Data Definition• Custom Post Types
• Taxonomies
• Meta Fields
• API Endpoints
• Data Configuration• Options
HEW2016 — #DPA5 SLIDE 25
Plugin DevelopmentReusability & Portability
• Default Styles and Templates
• Ability to turn off default CSS and JS when more customization is desired
• Customization of look and feel through theme CSS
• Default functionality without programming
Extensibility• Actions and Filters to allow
overriding of default templates
• Sass artifacts available in repository for easy overrides
• Well documented CSS classes for theme specific overrides
HEW2016 — #DPA5 SLIDE 26
CustomizingExample – UCF News in a “Masonry” stacked grid layout
<?php
add_action( 'ucf_news_display_masonry_before', 'news_masonry_template_before', 10, 3 );add_action( 'ucf_news_display_masonry_title', 'news_masonry_template_title', 10, 3 );add_action( 'ucf_news_display_masonry', 'news_masonry_template', 10, 3 );add_action( 'ucf_news_display_masonry_after', 'news_masonry_template_after', 10, 3 );
add_action( 'ucf_news_get_layouts', 'add_masonry_layout', 10, 1 );
?>
HEW2016 — #DPA5 SLIDE 30
Displays news content (prints markup)
Registers the new layout
<?php
add_action( 'ucf_news_display_masonry_before', 'news_masonry_template_before', 10, 3 );add_action( 'ucf_news_display_masonry_title', 'news_masonry_template_title', 10, 3 );add_action( 'ucf_news_display_masonry', 'news_masonry_template', 10, 3 );add_action( 'ucf_news_display_masonry_after', 'news_masonry_template_after', 10, 3 );
add_action( 'ucf_news_get_layouts', 'add_masonry_layout', 10, 1 );
?>
CustomizingExample – UCF News in a “Masonry” stacked grid layout
HEW2016 — #DPA5 SLIDE 31
<?php
function news_masonry_template_before( $items,
$title, $display_type ) {
echo '<div class="news-masonry">';
}
?>
<?php
add_action( 'ucf_news_display_masonry_before', 'news_masonry_template_before', 10, 3 );add_action( 'ucf_news_display_masonry_title', 'news_masonry_template_title', 10, 3 );add_action( 'ucf_news_display_masonry', 'news_masonry_template', 10, 3 );add_action( 'ucf_news_display_masonry_after', 'news_masonry_template_after', 10, 3 );
add_action( 'ucf_news_get_layouts', 'add_masonry_layout', 10, 1 );
?>
CustomizingExample – UCF News in a “Masonry” stacked grid layout
HEW2016 — #DPA5 SLIDE 32
<?php
function news_masonry_template_title( $items,
$title, $display_type ) {
echo '<h2>' . $title . '</h2>';
}
?>
<?php
add_action( 'ucf_news_display_masonry_before', 'news_masonry_template_before', 10, 3 );add_action( 'ucf_news_display_masonry_title', 'news_masonry_template_title', 10, 3 );add_action( 'ucf_news_display_masonry', 'news_masonry_template', 10, 3 );add_action( 'ucf_news_display_masonry_after', 'news_masonry_template_after', 10, 3 );
add_action( 'ucf_news_get_layouts', 'add_masonry_layout', 10, 1 );
?>
CustomizingExample – UCF News in a “Masonry” stacked grid layout
HEW2016 — #DPA5 SLIDE 33
<?php
function news_masonry_template( $items,
$title, $display_type ) {
ob_start();
foreach ( $items as $item ) {
?>
<div class="news-item">
<?php echo $item->title; ?>
<?php // other item content… ?>
</div>
<?php
}
return ob_get_clean();
}
?>
<?php
add_action( 'ucf_news_display_masonry_before', 'news_masonry_template_before', 10, 3 );add_action( 'ucf_news_display_masonry_title', 'news_masonry_template_title', 10, 3 );add_action( 'ucf_news_display_masonry', 'news_masonry_template', 10, 3 );add_action( 'ucf_news_display_masonry_after', 'news_masonry_template_after', 10, 3 );
add_action( 'ucf_news_get_layouts', 'add_masonry_layout', 10, 1 );
?>
CustomizingExample – UCF News in a “Masonry” stacked grid layout
HEW2016 — #DPA5 SLIDE 34
<?php
function news_masonry_template_after( $items,
$title, $display_type ) {
echo '</div>';
}
?>
<?php
add_action( 'ucf_news_display_masonry_before', 'news_masonry_template_before', 10, 3 );add_action( 'ucf_news_display_masonry_title', 'news_masonry_template_title', 10, 3 );add_action( 'ucf_news_display_masonry', 'news_masonry_template', 10, 3 );add_action( 'ucf_news_display_masonry_after', 'news_masonry_template_after', 10, 3 );
add_action( 'ucf_news_get_layouts', 'add_masonry_layout', 10, 1 );
?>
CustomizingExample – UCF News in a “Masonry” stacked grid layout
HEW2016 — #DPA5 SLIDE 35
<?php
function add_masonry_layout( $layouts ) {
$layouts = array_merge(
$layouts,
array(
'masonry' => 'Masonry Layout'
)
);
return $layouts;
}
?>
Plugins We’re BuildingWordPress Features
• Post types and taxonomies
• Shortcode WYSIWYG interface
• Autocomplete search field for lists of posts by type
• Plugin for general utility functions
Plugins for Services• UCF search service
• Weather data
• Map data (map.ucf.edu)
• UCF Header (JavaScript brand widget)
HEW2016 — #DPA5 SLIDE 36
Plugins We’re Not Building• Meta box and meta field management (Advanced Custom
Fields/ACF)
• SEO optimization (WordPress SEO/Yoast)
• Form management (GravityForms)
• And a few others…
HEW2016 — #DPA5 SLIDE 37
Modularization of Plugin FunctionalityExample – Separation of post type and meta field definitions
#Person
custom post type
4Advanced Custom Fields
(or other meta field manager)
%Theme Code
• Email field• Phone number field
• Address field
%Theme Code
HEW2016 — #DPA5 SLIDE 38
Dependency Management• Avoid unnecessary dependencies
• Simple plugin detection
• SemVer plugin detection – In Development
HEW2016 — #DPA5 SLIDE 40
Theme Development• Focused on:• Layout (Templates)• Styling
• Content
• Dependency Management• Fail gracefully• Handle dependencies through deployment process
HEW2016 — #DPA5 SLIDE 41
Yeoman Generators• Allow for quick customization of look and feel
• Pick and Choose:• Page templates
• Adjust SASS Variables
• Create documentation and labels
• Use WP CLI to create site, install theme enable plugins
HEW2016 — #DPA5 SLIDE 42
Looking ForwardAdvantages
• More effective maintenance and upgrade cycles
• More rapid development of new themes
• Distributed functionality and standard styles
• Increased consistency across sites
Challenges• Up front investment of time
• Additional responsibilities for documenting and testing
• Change in culture – being product driven instead of site driven
• Balancing these transitions with the need to get production work done
HEW2016 — #DPA5 SLIDE 43
In Conclusion• D.R.Y. WordPress sites require a different approach to both
code and site development as a whole
• YMMV!
• Code will be available on Github• https://github.com/UCF
HEW2016 — #DPA5 SLIDE 45
Resources• WordPress best practices
• https://codex.wordpress.org/Theme_Development#Functions_File
• https://developer.wordpress.com/themes/
• Dependency Management solutions• https://roots.io/using-composer-with-
wordpress/
• http://tgmpluginactivation.com
• WordPress hooks, actions and filters• https://codex.wordpress.org/Plugin_API
• Separation of Concerns (WP StackExchange)• http://wordpress.stackexchange.com/q/73031
• Theme or Plugin? (WP StackExchange)• http://wordpress.stackexchange.com/a/73038
• Meta field management plugins• https://www.advancedcustomfields.com/
• https://wordpress.org/plugins/cmb2/
• UCF on Github• https://github.com/UCF
HEW2016 — #DPA5 SLIDE 46