SlideShare uma empresa Scribd logo
1 de 87
WordPress 
Building Potent Websites 
By: Kyle Cearley @ractoon
Who’s this guy? 
+ = 
Corgi illustration http://oliviawhen.blogspot.com/
What we’ll be looking at: 
Part 1: The Appearance 
Creating modern, modular designs that are easy to use and maintain. 
Part 2: Plugins 
Things to be aware of when building plugins. 
Part 3: Tips and Tricks 
WordPress is vast, things happen (or don’t), some fixes for common issues.
Part 1 
The Appearance (Themes)
A WordPress Theme 
Ta-da… 
wp-content 
themes 
my-theme 
index.php 
style.css
Theme Starting Points 
• From scratch 
• Existing theme (child theme) 
• Framework / Boilerplate
Building from an Existing Theme 
• Always create a child theme 
my-theme 
my-theme-child 
functions.php 
style.css (required)
Child Theme Setup 
/* 
Theme Name: My Child Theme 
Template: my-theme 
… 
*/ 
my-theme-child 
style.css functions.php 
<?php 
add_action( 'wp_enqueue_scripts', 
'enqueue_child_theme_styles', 
PHP_INT_MAX ); 
function enqueue_child_theme_styles() { 
wp_enqueue_style( 'parent-style', 
get_template_directory_uri().'/style.css 
' ); 
wp_enqueue_style( 'child-style', 
get_stylesheet_directory_uri() . 
'/style.css', array('parent-style') ); 
}
Theme Frameworks / Boilerplates 
• Bones 
http://themble.com/bones/ 
• Underscores 
http://underscores.me/ 
• FoundationPress 
https://github.com/olefredrik/foundationpress 
• Roots 
http://roots.io/starter-theme/ 
• Genesis 
http://my.studiopress.com/themes/genesis/
Typical Modular Design 
header.php 
Client defined section nav 
Standard content section with animation shortcode 
Tabbed content 
section Content slider 
Standard content section with custom background 
footer.php 
Banner 
Widget with custom background
The Goal 
• An easy to use theme that nestles users in the 
design 
• Don’t make them think too hard 
• Reduce support requests (save yourself time)
Potential Paths to The Goal 
• Shortcodes 
• Custom meta boxes/fields 
https://github.com/WebDevStudios/Custom-Metaboxes-and- 
Fields-for-WordPress 
• Visual Composer 
http://codecanyon.net/item/visual-composer-page-builder-for- 
wordpress/242431 
• Advanced Custom Fields (ACF) PRO 
http://www.advancedcustomfields.com/pro/
Shortcodes 
[button]Button Text[/button] 
[button link="http://www.example.com" popup="yes"] 
Output: 
<a class="button" href="#">Button Text</a> 
<a class="button" href="http://www.example.com" target="_blank">Default Text</a>
Shortcodes 
• Good for small manipulations of content or 
inserting special content 
• Tricky to remember 
• Attributes lack selection/validation
Adding Shortcodes 
functions.php (or separate plugin) 
function button_func( $atts, $content ) { 
$atts = shortcode_atts( 
array( 
'link' => '#', 
'popup' => '' 
), $atts ); 
$html = '<a href="' . $atts['link'] . '"'; 
if ( !empty( $atts['popup'] ) ) $html .= ' target="_blank"'; 
$html .= '>'; 
$html .= do_shortcode( $content ); 
$html .= '</a>'; 
return $html; 
} 
add_shortcode( 'button', 'button_func' );
Shortcode Cleanup 
functions.php (or separate plugin) 
function cleanup_shortcode_fix( $content ) { 
$array = array ( 
'<p>[' => '[', 
']</p>' => ']', 
']<br />' => ']', 
']<br>' => ']' 
); 
$content = strtr( $content, $array ); 
return $content; 
} 
add_filter( 'the_content', 'cleanup_shortcode_fix' ); 
add_filter( 'acf_the_content', 'cleanup_shortcode_fix' ); 
Or (the nuclear option): 
remove_filter( 'the_content', 'wpautop' ); 
remove_filter( 'the_excerpt', 'wpautop' );
Meta Boxes
Custom Meta Boxes / Fields 
• Good variety of field types 
• Extensible 
• Tightly coupled with the theme 
• Need to define each field/group with code
Adding Meta Boxes / Fields 
<?php 
add_filter( 'cmb_meta_boxes', 'cmb_sample_metaboxes' ); 
function cmb_sample_metaboxes( array $meta_boxes ) { 
$prefix = '_cmb_'; 
$meta_boxes['test_metabox'] = array( 
'id' => 'test_metabox', 
'title' => __( 'Test Metabox', 'cmb' ), 
'pages' => array( 'page', ), 
'context' => 'normal', 
'priority' => 'high', 
'show_names' => true, 
'fields' => array( 
array( 
'name' => __( 'Test Text', 'cmb' ), 
'desc' => __( 'field description (optional)', 'cmb' ), 
'id' => $prefix . 'test_text', 
'type' => 'text', 
'show_on_cb' => 'cmb_test_text_show_on_cb' 
), 
... 
) 
); 
} 
functions.php
Displaying Meta Fields 
page.php / post.php 
Uses native WordPress get_post_meta function: 
<?php 
$meta_values = get_post_meta( $post_id, $key, $single ); 
Example: 
<?php 
global $post; 
$text = get_post_meta( $post->ID, '_cmb_test_text', true ); 
echo $text;
Meta Fields Cleanup 
Start meta field keys with _ to hide from custom fields 
To display the Custom Fields metabox activate it in Screen Options: 
Shows:
Visual Composer
Visual Composer 
• Visual page builder with drag/drop interface 
• Pre-configured templates for layouts 
• Over 40 content blocks (element types) 
• Visual query builder 
• Extensible 
• Content stored as post meta in serialized array
Advanced Custom Fields PRO 
• Wide variety of field types 
• Visual field setup and configuration 
• Easy to sync fields between installs 
• Extensible 
• Users given only the controls you define
Using Advanced Custom Fields PRO 
• Repeater 
• Image 
• Gallery 
• Flexible 
Content 
• Relationship 
• Post Object 
• Date Picker 
• Checkbox 
• Select 
• Text 
• True / False 
• File 
• Page Link 
• Wysiwyg Editor 
• Google Map 
• Textarea 
• Color Picker 
• Taxonomy 
• oEmbed
Defining ACF PRO Field Groups
Defining ACF PRO Fields
Populating ACF PRO Fields
Displaying ACF Pro Fields 
page.php / post.php 
<?php the_field( 'my_field_name' ); ?>
(Bones) Theme File Structure 
(Automatically saves your ACF fields) 
my-theme 
acf-json 
library 
css 
scss 
style.css 
style.css 
_base.scss, _481up.scss, _768up.scss…
CSS Preprocessors 
• Prepros (Mac, Windows) 
http://alphapixels.com/prepros/ 
• CodeKit (Mac) 
https://incident57.com/codekit/
Including Stylesheets 
Option 1: 
wp_register_style( $handle, $src, $deps, $ver, $media ); 
wp_enqueue_style( $handle ); 
Option 2: 
wp_enqueue_style( $handle, $src, $deps, $ver, $media ); 
functions.php 
function mytheme_enqueue_styles() { 
$style_file = get_template_directory_uri() . 
'/library/css/style.css'; 
wp_enqueue_style( 'my-styles', $style_file, array(), filemtime( 
$style_file ), 'all' ); 
} 
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_styles' );
Stylesheet Output 
functions.php 
… 
wp_enqueue_style( 'my-styles', $style_file, array(), filemtime( 
$style_file ), 'all' ); 
… 
Output: 
<link rel='stylesheet' id='my-styles-css' 
href='http://mysite.local/wp-content/themes/my-theme/ 
library/css/style.css?ver=1414191171' type='text/css' 
media='all' />
Including Scripts 
Option 1: 
wp_register_script( $handle, $src, $deps, $ver, $in_footer ); 
wp_enqueue_script( $handle ); 
Option 2: 
wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer ); 
functions.php 
function mytheme_enqueue_scripts() { 
$script_file = get_template_directory_uri() . 
'/library/js/scripts.js'; 
wp_enqueue_script( 'my-scripts', $script_file, array( 'jquery' ), 
filemtime( $script_file ), true ); 
} 
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_scripts' );
Scripts Output 
<script type='text/javascript' src='http://mysite.local/wp-content/ 
themes/my-theme/ 
library/js/min/scripts.js?ver=1413837351'></script> 
… 
wp_enqueue_script( 'my-scripts', $script_file, array( 'jquery' ), 
filemtime( $script_file ), true ); 
… 
functions.php 
Output:
The Power of Enqueue 
• Allows other devs/plugins to modify styles/scripts 
as needed 
• Allows you to tack things on to scripts/styles: 
– Inline styles 
wp_add_inline_style( 'my-styles', $custom_css ); 
– Style data (such as conditional IE wrappers) 
global $wp_styles; 
$wp_styles->add_data( 'my-ie-styles', 'conditional', 'lt IE 
9' ); 
– Localize scripts 
wp_localize_script( 'my-scripts', 'greeting', 'Bonjour!' );
Content Section Types 
• Standard Content 
• Sliders 
• Tabbed content 
• Testimonials 
• Custom post type displays (news, resources, 
etc.) 
• Other sections the design calls for
Flexible Sections for Clients 
• Add, remove, and change order 
• Modify background color/image, headlines, 
description text, etc. 
• Keep clients focused on their content 
– Useful defaults 
– Only show relevant items (conditional toggles) 
– Expect weird content (longer/shorter, 
larger/smaller than mockup) 
– Fill in the gaps for clients
Creating Content Sections 
Each section type is a Flexible Content field set 
up in Advanced Custom Fields
Template Parts 
Allow you to reuse chunks of code, and for child 
themes to replace sections as needed 
<?php get_template_part ( $slug, $name ); ?>
Creating Template Parts 
page.php / post.php 
<?php get_template_part ( 'chunk' ); ?> 
my-theme 
chunk.php (2) 
my-theme-child 
chunk.php (1)
Creating Template Parts 
page.php / post.php 
<?php get_template_part ( 'chunk', 'adunk' ); ?> 
my-theme 
chunk-adunk.php (2) 
chunk.php (4) 
my-theme-child 
chunk-adunk.php (1) 
chunk.php (3)
Template Part for the Content Sections 
Content sections are contained in a template part: 
content-sections.php 
content-sections.php 
my-theme 
The content sections template part is included on desired page/post templates: 
page.php / post.php 
<?php get_template_part ('content-sections' ); ?>
Displaying the Content Sections 
content-sections.php 
<?php 
if ( have_rows( 'sections' ) ): 
$section_id = 1; 
?> 
<?php while ( have_rows('sections') ) : the_row(); ?> 
<?php $layout = get_row_layout(); ?> 
<section id="content-section-<?php echo $section_id; ?>" class="<?php echo $layout; ?>"> 
<?php if ( 'content' == $layout ): // default content section ?> 
<?php the_sub_field( 'content' ); ?> 
<?php endif; ?> 
</section> 
<?php 
$section_id++; 
endwhile; 
endif; 
?>
Customizing Content Sections 
Default 
Custom Background Color 
Custom Background Image
Applying Custom Styles to Sections 
<?php 
if ( have_rows( 'sections' ) ): 
$content_sections_css = ''; 
$section_id = 1; 
while ( have_rows('sections') ) : the_row(); ?> 
$content_sections_css .= "#content-section-{$section_id} {"; 
$background = get_sub_field( 'background' ); 
if ( 'color' == $background ) { 
$background_color = get_sub_field( 'background_color' ); 
$content_sections_css .= "background-color: {$background_color};"; 
} 
$content_sections_css .= "}"; 
$section_id++; 
endwhile; 
wp_add_inline_style( 'my-styles', $content_sections_css ); 
endif; 
Loop through sections 
Content section selector 
Set styles 
Attach inline styles 
functions.php (in wp_enqueue_scripts function)
Custom Section Styles Output 
The enqueued stylesheet from earlier that the inline styles are attached to 
<link rel='stylesheet' id='my-styles-css' 
href='http://mysite.local/wp-content/themes/my-theme/ 
library/css/style.css?ver=1414191171' type='text/css' 
media='all' /> 
<style type='text/css'> 
#content-section-1 { 
background-color: #cc0000; 
} 
</style> 
Inline styles output right after 
the attached stylesheet
Part 1.1 
The Appearance (Widgets)
Widgets 
• Use to display content that should appear on 
multiple posts/pages 
• Can conditionally display widgets with plugins 
such as Display Widgets: 
https://wordpress.org/plugins/display-widgets/ 
• Widget Boilerplate: 
https://github.com/tommcfarlin/WordPress- 
Widget-Boilerplate
<?php 
add_action( 'widgets_init', 'my_register_sidebars' ); 
function my_register_sidebars() { 
register_sidebar( array( 
'id' => 'sidebar', 
'name' => __( 'Sidebar', 'bonestheme' ), 
'description' => __( 'The main sidebar.', 'bonestheme' ), 
'before_widget' => '<div id="%1$s" class="widget %2$s">', 
'after_widget' => '</div>', 
'before_title' => '<h4 class="widgettitle">', 
'after_title' => '</h4>', 
)); 
... 
} 
Creating Widget Areas (Sidebars) 
functions.php
Displaying Widget Areas (Sidebars) 
sidebar.php 
<div id="sidebar" class="sidebar cf" role="complementary"> 
<?php if ( is_active_sidebar( 'sidebar' ) ) : ?> 
<?php dynamic_sidebar( 'sidebar' ); ?> 
<?php endif; ?> 
</div>
Advanced Custom Fields in Widgets 
After creating your widget using the Widget Boilerplate:
public function widget( $args, $instance ) { 
extract( $args ); 
echo $before_widget; 
?> 
<section> 
<?php 
$content = get_field( 'content', 'widget_' . $widget_id ); 
echo do_shortcode( $content ); 
?> 
</section> 
<?php 
echo $after_widget; 
} 
Displaying ACF Fields in Widgets 
Accessed through second argument which is the widget_id prefixed by "widget_"
// widget sections 
$sidebars_widgets = wp_get_sidebars_widgets(); 
$widget_ids = array_merge( $sidebars_widgets['sidebar'] ); 
$widget_sections_css = ''; 
foreach( $widget_ids as $id ) { 
if ( $background_color = get_field( 'background_color', 'widget_' . $id ) ) { 
$widget_sections_css .= " 
#{$id} section { 
background-color: {$background_color}; 
}"; 
} 
} 
if ( !empty( $widget_sections_css ) ) { 
wp_add_inline_style( 'my-styles', $widget_sections_css ); 
} 
Custom Styles for Widget Fields 
functions.php (in wp_enqueue_scripts function)
Part 2 
Plugins
Hooks 
Hooks allow you to modify, extend, and enhance 
WordPress through an API in your themes and 
plugins. 
There are two flavors: 
• Actions 
• Filters
Actions 
Triggered by specific events, typically used for 
executing functions. 
• do_action() 
– Defines a hookable location 
• add_action() 
– Attaches a function to a hook defined with do_action() 
• has_action() 
– Checks if action exists 
• remove_action()
Default WordPress Actions 
• wp_enqueue_scripts 
• register_sidebar 
• dynamic_sidebar 
• wp_head 
• get_header 
• get_footer 
• plugins_loaded 
• And many more… 
http://codex.wordpress.org/Plugin_API/Action_Reference
<?php 
... 
<section id="content-section-<?php echo $section_id; ?>" class="<?php echo $layout; ?>"> 
<?php do_action( 'my_content_section_before', $layout ); ?> 
<?php if ( 'content' == $layout ): // default content section ?> 
<?php the_sub_field( 'content' ); ?> 
<?php endif; ?> 
<?php do_action('my_content_section_after', $layout ); ?> 
</section> 
... 
Custom Action Setup 
content-sections.php
Custom Action Usage 
functions.php 
<?php 
function my_extra_content( $layout ) { 
echo 'This Content Section uses the layout: ' . $layout; 
} 
add_action( 'my_content_section_before', 'my_extra_content' ); 
Output: 
This Content Section uses the layout: content 
{ section content fields displayed here… }
Filters 
Functions that data passes through, typically used 
to manipulate data. 
• apply_filters() 
– Defines a hookable location 
• add_filter() 
– Attaches a filter to a hook defined with apply_filters() 
• has_filter() 
– Checks if filter exists 
• Remove_filter()
Default WordPress Filters 
• the_excerpt 
• the_content 
• the_title 
• wp_list_pages 
• sanitize_title 
• menu_order 
• image_resize_dimensions 
• And many more… 
http://codex.wordpress.org/Plugin_API/Filter_Reference
Custom Filter Setup and Usage 
functions.php (or separate plugin) 
<?php 
$args = array( 
'post_type' => 'locations', 
'region' => 'USA', 
'posts_per_page' => 5 
); 
$locations = new WP_Query( apply_filters( 'my_locations_query', $args ) ); 
Usage: 
<?php 
function my_new_locations_query( $args ) { 
$args['region'] = 'Canada'; 
return $args; 
} 
add_filter( 'my_locations_query', 'my_new_locations_query' );
A WordPress Plugin 
wp-content 
plugins 
my-plugin 
plugin.php 
Ta-da…
Plugin Setup 
plugin.php 
<?php 
/* 
* Plugin Name: My Plugin 
* Plugin URI: http://myplugin.mysite.com 
* Description: It’s my plugin, and I do what I want. 
* Version: 1.0 
* Author: Me 
* Author URI: http://www.mysite.com 
* License: GPL2 
* Text Domain: my-plugin 
*/ 
Plugin Boilerplate: 
https://github.com/tommcfarlin/WordPress-Plugin-Boilerplate
Plugin Using Classes 
plugin.php 
<?php 
/* 
* Plugin Name: My Plugin 
* Plugin URI: http://myplugin.mysite.com 
* Description: It’s my plugin, and I do what I want. 
* Version: 1.0 
* ... 
*/ 
class MyPostType { 
public function __construct() { 
// custom post type 
add_action( 'init', array( $this, 'my_custom_post_type' ) ); 
} 
public function my_custom_post_type() { 
// my custom post type defined here 
} 
} 
$myPostType = new MyPostType();
What theme components should be 
plugins? 
• Shortcodes 
• Custom Post Types 
• Custom Taxonomies 
• Custom Widgets 
Nestle users in the design, don’t trap them.
Part 2.1 
I18n (Internationalization)
I18n (Internationalization) 
Making your themes / plugins translatable 
Standard strings: 
$hello = __( 'Hello there', 'my-text-domain' ); 
_e( 'This is echoed', 'my-text-domain' ); 
Singular / plural strings: 
_n( 'One potato', 'Many potatoes', $count, 'my-text-domain' ); 
Differentiating strings with similar names (setting the context): 
_x( 'Name', 'my context', 'my-text-domain' ); 
_ex( 'Echo name', 'my context', 'my-text-domain' );
I18n with Variables 
Standard strings with a variable: 
$hello = sprintf( __( 'Hello there, %s', 'my-text-domain' ), 
'Bob' ); // store in variable 
printf( __( 'Hello there, %s', 'my-text-domain' ), 'Bob' ); // or 
just output 
Singlular / plural strings with a variable: 
$potato = sprintf( _n('A lonely potato', 'Here are %d potatoes', 
$count, 'my-text-domain' ), $count ); // store in variable 
printf( _n('A lonely potato', 'Here are %d potatoes', $count, 
'my-text-domain' ), $count ); // or just output
Part 2.2 
Security with Nonces
Nonces 
• Protect your themes/plugins against CSRF 
(Cross-Site Request Forgery), multiple/invalid 
submissions 
• A.K.A. CSRF Tokens
Adding Nonces to URLs 
wp_nonce_url( $actionurl, $action, $name ); 
Usage: 
$bare_url = 'http://example.com/wp-admin/ 
post.php?post=123&action=trash'; 
$complete_url = wp_nonce_url( $bare_url, 'trash-post_' . 
$post->ID, '_wpnonce' ); 
http://example.com/wp-admin/ 
post.php?post=123&action=trash&_wpnonce=b192fc4204 
Output:
Adding Nonces to Forms 
wp_nonce_field( $action, $name, $referer, $echo ); 
Usage: 
wp_nonce_field( 'delete-user_' . $user_id, '_wpnonce', 
true, true ); 
<input type="hidden" id="_wpnonce" name="_wpnonce" 
value="796c7766b1"> 
<input type="hidden" name="_wp_http_referer" value="/wp-admin/ 
edit-user.php"> 
Output:
Adding Nonces Anywhere 
wp_create_nonce( $action ); 
Usage: 
wp_create_nonce( 'my-nonce' ); 
Value: 
295a686963
Verifying Nonces 
From Form / URL: 
check_admin_referer( 'delete-user_' . $user_id ); 
From some other context: 
wp_verify_nonce( 'delete-user_' . $user_id ); 
From AJAX: 
check_ajax_referer( 'get-users' );
Part 2.3 
Using AJAX in Plugins
add_action( 'wp_ajax_myfunc', 'prefix_ajax_myfunc' ); 
add_action( 'wp_ajax_nopriv_myfunc', 'prefix_ajax_myfunc' ); 
function prefix_ajax_myfunc() { 
check_ajax_referer( 'my-nonce', 'security' ); 
echo $_POST['foo']; 
die(); 
} 
AJAX: The Setup 
functions.php (or separate plugin)
AJAX: The Nonce 
functions.php (or separate plugin, in wp_enqueue_scripts function) 
<?php 
// Set Your Nonce 
$ajax_nonce = wp_create_nonce( "my-nonce" ); 
wp_localize_script( 'my-scripts', 'ajaxNonce', $ajax_nonce );
AJAX: The Usage 
scripts.js 
jQuery(document).ready(function($) { 
var data = { 
action: 'myfunc', 
security: ajaxNonce, 
foo: 'Hello World!' 
}; 
$.post(ajaxurl, data, function(response) { 
alert("Response: " + response); 
}); 
});
Part 3 
Tips and Tricks
Protecting Email Addresses 
<?php antispambot( $emailaddy, $hex_encoding ) ?> 
Usage: 
<?php echo antispambot( 'test.mctest@mysite.com' ); ?> 
Result: 
&#106;&#111;h&#110;&#46;&#100;&#111;&#101;&#64;mysit&#101;.&#99;&#111;&#109; 
Browser sees: 
test.mctest@mysite.com
Quickstarts for Custom Components 
http://generatewp.com/
Custom ACF Color Picker Swatches 
Customize swatches based on design / theme colors: 
These things
Custom ACF Color Picker Swatches 
functions.php 
function acf_custom_config() { 
global $parent_file; 
if ( 
strpos($parent_file, 'post-new.php') !== FALSE || 
strpos($parent_file, 'edit.php') !== FALSE ) { 
echo " 
<script> 
jQuery(document).ready(function($){ 
if ($('.acf-color_picker').length) { 
$('.acf-color_picker').iris({ 
palettes: ['#f60', '#ffa839', '#3078bf', '#e0ebf5', '#58585a', '#2e3137'], 
change: function(event, ui) { 
$(this).parents('.wp-picker-container').find('.wp-color-result'). 
css('background-color', ui.color.toString()); 
} 
}); 
} 
}); 
</script> 
"; 
} 
} 
add_action( 'in_admin_footer', 'acf_custom_config' );
Make Admin Listings Relevant 
Use the Admin Columns Pro plugin to clean up the post listing pages: 
• Show relevant columns for post types, hide unnecessary columns 
• Allow client to edit items in the listing (inline edits) 
• Display ACF PRO fields as well
Thank You! 
If you ever had any questions or wanted to chat: 
kyle@ractoon.com

Mais conteúdo relacionado

Mais procurados

jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
WordPress Developers Israel Meetup #1
WordPress Developers Israel Meetup #1WordPress Developers Israel Meetup #1
WordPress Developers Israel Meetup #1
Yoav Farhi
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
Yi-Ting Cheng
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
Aaronius
 

Mais procurados (20)

Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
WordPress theme development from scratch : ICT MeetUp 2013 Nepal
WordPress theme development from scratch : ICT MeetUp 2013 NepalWordPress theme development from scratch : ICT MeetUp 2013 Nepal
WordPress theme development from scratch : ICT MeetUp 2013 Nepal
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
 
Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2
Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2
Сергей Иващенко - Meet Magento Ukraine - Цены в Magento 2
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
 
Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019
 
WordPress Theme Development: Part 2
WordPress Theme Development: Part 2WordPress Theme Development: Part 2
WordPress Theme Development: Part 2
 
Drupal 8: Routing & More
Drupal 8: Routing & MoreDrupal 8: Routing & More
Drupal 8: Routing & More
 
Working with the django admin
Working with the django admin Working with the django admin
Working with the django admin
 
Introduction to Plugin Programming, WordCamp Miami 2011
Introduction to Plugin Programming, WordCamp Miami 2011Introduction to Plugin Programming, WordCamp Miami 2011
Introduction to Plugin Programming, WordCamp Miami 2011
 
WordPress Developers Israel Meetup #1
WordPress Developers Israel Meetup #1WordPress Developers Israel Meetup #1
WordPress Developers Israel Meetup #1
 
WordPress Theming 101
WordPress Theming 101WordPress Theming 101
WordPress Theming 101
 
Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019
 
Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019
 
Creating GUI Component APIs in Angular and Web Components
Creating GUI Component APIs in Angular and Web ComponentsCreating GUI Component APIs in Angular and Web Components
Creating GUI Component APIs in Angular and Web Components
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
 
WordPress Plugin development
WordPress Plugin developmentWordPress Plugin development
WordPress Plugin development
 
Learning the basics of the Drupal API
Learning the basics of the Drupal APILearning the basics of the Drupal API
Learning the basics of the Drupal API
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
 

Semelhante a Building Potent WordPress Websites

Gail villanueva add muscle to your wordpress site
Gail villanueva   add muscle to your wordpress siteGail villanueva   add muscle to your wordpress site
Gail villanueva add muscle to your wordpress site
references
 
Building a Portfolio With Custom Post Types
Building a Portfolio With Custom Post TypesBuilding a Portfolio With Custom Post Types
Building a Portfolio With Custom Post Types
Alex Blackie
 
Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress
Maurizio Pelizzone
 

Semelhante a Building Potent WordPress Websites (20)

The Way to Theme Enlightenment
The Way to Theme EnlightenmentThe Way to Theme Enlightenment
The Way to Theme Enlightenment
 
Gail villanueva add muscle to your wordpress site
Gail villanueva   add muscle to your wordpress siteGail villanueva   add muscle to your wordpress site
Gail villanueva add muscle to your wordpress site
 
Build WordPress themes like a heavyweight - WordCamp Lancaster 2013
Build WordPress themes like a heavyweight - WordCamp Lancaster 2013Build WordPress themes like a heavyweight - WordCamp Lancaster 2013
Build WordPress themes like a heavyweight - WordCamp Lancaster 2013
 
PSD to WordPress
PSD to WordPressPSD to WordPress
PSD to WordPress
 
Seven deadly theming sins
Seven deadly theming sinsSeven deadly theming sins
Seven deadly theming sins
 
How to make a WordPress theme
How to make a WordPress themeHow to make a WordPress theme
How to make a WordPress theme
 
Drupal 7 — Circle theme
Drupal 7 — Circle themeDrupal 7 — Circle theme
Drupal 7 — Circle theme
 
WordPress Structure and Best Practices
WordPress Structure and Best PracticesWordPress Structure and Best Practices
WordPress Structure and Best Practices
 
Design Systems, Pattern Libraries & WordPress
Design Systems, Pattern Libraries & WordPressDesign Systems, Pattern Libraries & WordPress
Design Systems, Pattern Libraries & WordPress
 
Writing your own WordPress themes and plugins
Writing your own WordPress themes and pluginsWriting your own WordPress themes and plugins
Writing your own WordPress themes and plugins
 
Don't Fear the Custom Theme: How to build a custom WordPress theme with only ...
Don't Fear the Custom Theme: How to build a custom WordPress theme with only ...Don't Fear the Custom Theme: How to build a custom WordPress theme with only ...
Don't Fear the Custom Theme: How to build a custom WordPress theme with only ...
 
May the core be with you - JandBeyond 2014
May the core be with you - JandBeyond 2014May the core be with you - JandBeyond 2014
May the core be with you - JandBeyond 2014
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
Building a Portfolio With Custom Post Types
Building a Portfolio With Custom Post TypesBuilding a Portfolio With Custom Post Types
Building a Portfolio With Custom Post Types
 
WordPress Theme Design and Development Workshop - Day 3
WordPress Theme Design and Development Workshop - Day 3WordPress Theme Design and Development Workshop - Day 3
WordPress Theme Design and Development Workshop - Day 3
 
Implement rich snippets in your webshop
Implement rich snippets in your webshopImplement rich snippets in your webshop
Implement rich snippets in your webshop
 
Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress
 
Django workshop : let's make a blog
Django workshop : let's make a blogDjango workshop : let's make a blog
Django workshop : let's make a blog
 
WordPress Theme Workshop: Part 3
WordPress Theme Workshop: Part 3WordPress Theme Workshop: Part 3
WordPress Theme Workshop: Part 3
 

Último

➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men 🔝mehsana🔝 Escorts...
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men  🔝mehsana🔝   Escorts...➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men  🔝mehsana🔝   Escorts...
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men 🔝mehsana🔝 Escorts...
nirzagarg
 
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Chandigarh Call girls 9053900678 Call girls in Chandigarh
 
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
nirzagarg
 
6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...
6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...
6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...
@Chandigarh #call #Girls 9053900678 @Call #Girls in @Punjab 9053900678
 

Último (20)

Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableCall Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
 
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
 
(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7
(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7
(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7
 
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
 
Wagholi & High Class Call Girls Pune Neha 8005736733 | 100% Gennuine High Cla...
Wagholi & High Class Call Girls Pune Neha 8005736733 | 100% Gennuine High Cla...Wagholi & High Class Call Girls Pune Neha 8005736733 | 100% Gennuine High Cla...
Wagholi & High Class Call Girls Pune Neha 8005736733 | 100% Gennuine High Cla...
 
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
 
Sarola * Female Escorts Service in Pune | 8005736733 Independent Escorts & Da...
Sarola * Female Escorts Service in Pune | 8005736733 Independent Escorts & Da...Sarola * Female Escorts Service in Pune | 8005736733 Independent Escorts & Da...
Sarola * Female Escorts Service in Pune | 8005736733 Independent Escorts & Da...
 
Dubai=Desi Dubai Call Girls O525547819 Outdoor Call Girls Dubai
Dubai=Desi Dubai Call Girls O525547819 Outdoor Call Girls DubaiDubai=Desi Dubai Call Girls O525547819 Outdoor Call Girls Dubai
Dubai=Desi Dubai Call Girls O525547819 Outdoor Call Girls Dubai
 
20240508 QFM014 Elixir Reading List April 2024.pdf
20240508 QFM014 Elixir Reading List April 2024.pdf20240508 QFM014 Elixir Reading List April 2024.pdf
20240508 QFM014 Elixir Reading List April 2024.pdf
 
Shikrapur - Call Girls in Pune Neha 8005736733 | 100% Gennuine High Class Ind...
Shikrapur - Call Girls in Pune Neha 8005736733 | 100% Gennuine High Class Ind...Shikrapur - Call Girls in Pune Neha 8005736733 | 100% Gennuine High Class Ind...
Shikrapur - Call Girls in Pune Neha 8005736733 | 100% Gennuine High Class Ind...
 
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men 🔝mehsana🔝 Escorts...
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men  🔝mehsana🔝   Escorts...➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men  🔝mehsana🔝   Escorts...
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men 🔝mehsana🔝 Escorts...
 
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
 
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
 
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
 
best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...
best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...
best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...
 
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
 
20240507 QFM013 Machine Intelligence Reading List April 2024.pdf
20240507 QFM013 Machine Intelligence Reading List April 2024.pdf20240507 QFM013 Machine Intelligence Reading List April 2024.pdf
20240507 QFM013 Machine Intelligence Reading List April 2024.pdf
 
APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...
APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...
APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...
 
All Time Service Available Call Girls Mg Road 👌 ⏭️ 6378878445
All Time Service Available Call Girls Mg Road 👌 ⏭️ 6378878445All Time Service Available Call Girls Mg Road 👌 ⏭️ 6378878445
All Time Service Available Call Girls Mg Road 👌 ⏭️ 6378878445
 
6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...
6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...
6.High Profile Call Girls In Punjab +919053900678 Punjab Call GirlHigh Profil...
 

Building Potent WordPress Websites

  • 1. WordPress Building Potent Websites By: Kyle Cearley @ractoon
  • 2. Who’s this guy? + = Corgi illustration http://oliviawhen.blogspot.com/
  • 3. What we’ll be looking at: Part 1: The Appearance Creating modern, modular designs that are easy to use and maintain. Part 2: Plugins Things to be aware of when building plugins. Part 3: Tips and Tricks WordPress is vast, things happen (or don’t), some fixes for common issues.
  • 4. Part 1 The Appearance (Themes)
  • 5. A WordPress Theme Ta-da… wp-content themes my-theme index.php style.css
  • 6. Theme Starting Points • From scratch • Existing theme (child theme) • Framework / Boilerplate
  • 7. Building from an Existing Theme • Always create a child theme my-theme my-theme-child functions.php style.css (required)
  • 8. Child Theme Setup /* Theme Name: My Child Theme Template: my-theme … */ my-theme-child style.css functions.php <?php add_action( 'wp_enqueue_scripts', 'enqueue_child_theme_styles', PHP_INT_MAX ); function enqueue_child_theme_styles() { wp_enqueue_style( 'parent-style', get_template_directory_uri().'/style.css ' ); wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style') ); }
  • 9. Theme Frameworks / Boilerplates • Bones http://themble.com/bones/ • Underscores http://underscores.me/ • FoundationPress https://github.com/olefredrik/foundationpress • Roots http://roots.io/starter-theme/ • Genesis http://my.studiopress.com/themes/genesis/
  • 10. Typical Modular Design header.php Client defined section nav Standard content section with animation shortcode Tabbed content section Content slider Standard content section with custom background footer.php Banner Widget with custom background
  • 11. The Goal • An easy to use theme that nestles users in the design • Don’t make them think too hard • Reduce support requests (save yourself time)
  • 12. Potential Paths to The Goal • Shortcodes • Custom meta boxes/fields https://github.com/WebDevStudios/Custom-Metaboxes-and- Fields-for-WordPress • Visual Composer http://codecanyon.net/item/visual-composer-page-builder-for- wordpress/242431 • Advanced Custom Fields (ACF) PRO http://www.advancedcustomfields.com/pro/
  • 13. Shortcodes [button]Button Text[/button] [button link="http://www.example.com" popup="yes"] Output: <a class="button" href="#">Button Text</a> <a class="button" href="http://www.example.com" target="_blank">Default Text</a>
  • 14. Shortcodes • Good for small manipulations of content or inserting special content • Tricky to remember • Attributes lack selection/validation
  • 15. Adding Shortcodes functions.php (or separate plugin) function button_func( $atts, $content ) { $atts = shortcode_atts( array( 'link' => '#', 'popup' => '' ), $atts ); $html = '<a href="' . $atts['link'] . '"'; if ( !empty( $atts['popup'] ) ) $html .= ' target="_blank"'; $html .= '>'; $html .= do_shortcode( $content ); $html .= '</a>'; return $html; } add_shortcode( 'button', 'button_func' );
  • 16. Shortcode Cleanup functions.php (or separate plugin) function cleanup_shortcode_fix( $content ) { $array = array ( '<p>[' => '[', ']</p>' => ']', ']<br />' => ']', ']<br>' => ']' ); $content = strtr( $content, $array ); return $content; } add_filter( 'the_content', 'cleanup_shortcode_fix' ); add_filter( 'acf_the_content', 'cleanup_shortcode_fix' ); Or (the nuclear option): remove_filter( 'the_content', 'wpautop' ); remove_filter( 'the_excerpt', 'wpautop' );
  • 18. Custom Meta Boxes / Fields • Good variety of field types • Extensible • Tightly coupled with the theme • Need to define each field/group with code
  • 19. Adding Meta Boxes / Fields <?php add_filter( 'cmb_meta_boxes', 'cmb_sample_metaboxes' ); function cmb_sample_metaboxes( array $meta_boxes ) { $prefix = '_cmb_'; $meta_boxes['test_metabox'] = array( 'id' => 'test_metabox', 'title' => __( 'Test Metabox', 'cmb' ), 'pages' => array( 'page', ), 'context' => 'normal', 'priority' => 'high', 'show_names' => true, 'fields' => array( array( 'name' => __( 'Test Text', 'cmb' ), 'desc' => __( 'field description (optional)', 'cmb' ), 'id' => $prefix . 'test_text', 'type' => 'text', 'show_on_cb' => 'cmb_test_text_show_on_cb' ), ... ) ); } functions.php
  • 20. Displaying Meta Fields page.php / post.php Uses native WordPress get_post_meta function: <?php $meta_values = get_post_meta( $post_id, $key, $single ); Example: <?php global $post; $text = get_post_meta( $post->ID, '_cmb_test_text', true ); echo $text;
  • 21. Meta Fields Cleanup Start meta field keys with _ to hide from custom fields To display the Custom Fields metabox activate it in Screen Options: Shows:
  • 23. Visual Composer • Visual page builder with drag/drop interface • Pre-configured templates for layouts • Over 40 content blocks (element types) • Visual query builder • Extensible • Content stored as post meta in serialized array
  • 24. Advanced Custom Fields PRO • Wide variety of field types • Visual field setup and configuration • Easy to sync fields between installs • Extensible • Users given only the controls you define
  • 25. Using Advanced Custom Fields PRO • Repeater • Image • Gallery • Flexible Content • Relationship • Post Object • Date Picker • Checkbox • Select • Text • True / False • File • Page Link • Wysiwyg Editor • Google Map • Textarea • Color Picker • Taxonomy • oEmbed
  • 26. Defining ACF PRO Field Groups
  • 29. Displaying ACF Pro Fields page.php / post.php <?php the_field( 'my_field_name' ); ?>
  • 30. (Bones) Theme File Structure (Automatically saves your ACF fields) my-theme acf-json library css scss style.css style.css _base.scss, _481up.scss, _768up.scss…
  • 31. CSS Preprocessors • Prepros (Mac, Windows) http://alphapixels.com/prepros/ • CodeKit (Mac) https://incident57.com/codekit/
  • 32. Including Stylesheets Option 1: wp_register_style( $handle, $src, $deps, $ver, $media ); wp_enqueue_style( $handle ); Option 2: wp_enqueue_style( $handle, $src, $deps, $ver, $media ); functions.php function mytheme_enqueue_styles() { $style_file = get_template_directory_uri() . '/library/css/style.css'; wp_enqueue_style( 'my-styles', $style_file, array(), filemtime( $style_file ), 'all' ); } add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_styles' );
  • 33. Stylesheet Output functions.php … wp_enqueue_style( 'my-styles', $style_file, array(), filemtime( $style_file ), 'all' ); … Output: <link rel='stylesheet' id='my-styles-css' href='http://mysite.local/wp-content/themes/my-theme/ library/css/style.css?ver=1414191171' type='text/css' media='all' />
  • 34. Including Scripts Option 1: wp_register_script( $handle, $src, $deps, $ver, $in_footer ); wp_enqueue_script( $handle ); Option 2: wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer ); functions.php function mytheme_enqueue_scripts() { $script_file = get_template_directory_uri() . '/library/js/scripts.js'; wp_enqueue_script( 'my-scripts', $script_file, array( 'jquery' ), filemtime( $script_file ), true ); } add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_scripts' );
  • 35. Scripts Output <script type='text/javascript' src='http://mysite.local/wp-content/ themes/my-theme/ library/js/min/scripts.js?ver=1413837351'></script> … wp_enqueue_script( 'my-scripts', $script_file, array( 'jquery' ), filemtime( $script_file ), true ); … functions.php Output:
  • 36. The Power of Enqueue • Allows other devs/plugins to modify styles/scripts as needed • Allows you to tack things on to scripts/styles: – Inline styles wp_add_inline_style( 'my-styles', $custom_css ); – Style data (such as conditional IE wrappers) global $wp_styles; $wp_styles->add_data( 'my-ie-styles', 'conditional', 'lt IE 9' ); – Localize scripts wp_localize_script( 'my-scripts', 'greeting', 'Bonjour!' );
  • 37. Content Section Types • Standard Content • Sliders • Tabbed content • Testimonials • Custom post type displays (news, resources, etc.) • Other sections the design calls for
  • 38. Flexible Sections for Clients • Add, remove, and change order • Modify background color/image, headlines, description text, etc. • Keep clients focused on their content – Useful defaults – Only show relevant items (conditional toggles) – Expect weird content (longer/shorter, larger/smaller than mockup) – Fill in the gaps for clients
  • 39. Creating Content Sections Each section type is a Flexible Content field set up in Advanced Custom Fields
  • 40. Template Parts Allow you to reuse chunks of code, and for child themes to replace sections as needed <?php get_template_part ( $slug, $name ); ?>
  • 41. Creating Template Parts page.php / post.php <?php get_template_part ( 'chunk' ); ?> my-theme chunk.php (2) my-theme-child chunk.php (1)
  • 42. Creating Template Parts page.php / post.php <?php get_template_part ( 'chunk', 'adunk' ); ?> my-theme chunk-adunk.php (2) chunk.php (4) my-theme-child chunk-adunk.php (1) chunk.php (3)
  • 43. Template Part for the Content Sections Content sections are contained in a template part: content-sections.php content-sections.php my-theme The content sections template part is included on desired page/post templates: page.php / post.php <?php get_template_part ('content-sections' ); ?>
  • 44. Displaying the Content Sections content-sections.php <?php if ( have_rows( 'sections' ) ): $section_id = 1; ?> <?php while ( have_rows('sections') ) : the_row(); ?> <?php $layout = get_row_layout(); ?> <section id="content-section-<?php echo $section_id; ?>" class="<?php echo $layout; ?>"> <?php if ( 'content' == $layout ): // default content section ?> <?php the_sub_field( 'content' ); ?> <?php endif; ?> </section> <?php $section_id++; endwhile; endif; ?>
  • 45. Customizing Content Sections Default Custom Background Color Custom Background Image
  • 46. Applying Custom Styles to Sections <?php if ( have_rows( 'sections' ) ): $content_sections_css = ''; $section_id = 1; while ( have_rows('sections') ) : the_row(); ?> $content_sections_css .= "#content-section-{$section_id} {"; $background = get_sub_field( 'background' ); if ( 'color' == $background ) { $background_color = get_sub_field( 'background_color' ); $content_sections_css .= "background-color: {$background_color};"; } $content_sections_css .= "}"; $section_id++; endwhile; wp_add_inline_style( 'my-styles', $content_sections_css ); endif; Loop through sections Content section selector Set styles Attach inline styles functions.php (in wp_enqueue_scripts function)
  • 47. Custom Section Styles Output The enqueued stylesheet from earlier that the inline styles are attached to <link rel='stylesheet' id='my-styles-css' href='http://mysite.local/wp-content/themes/my-theme/ library/css/style.css?ver=1414191171' type='text/css' media='all' /> <style type='text/css'> #content-section-1 { background-color: #cc0000; } </style> Inline styles output right after the attached stylesheet
  • 48. Part 1.1 The Appearance (Widgets)
  • 49. Widgets • Use to display content that should appear on multiple posts/pages • Can conditionally display widgets with plugins such as Display Widgets: https://wordpress.org/plugins/display-widgets/ • Widget Boilerplate: https://github.com/tommcfarlin/WordPress- Widget-Boilerplate
  • 50. <?php add_action( 'widgets_init', 'my_register_sidebars' ); function my_register_sidebars() { register_sidebar( array( 'id' => 'sidebar', 'name' => __( 'Sidebar', 'bonestheme' ), 'description' => __( 'The main sidebar.', 'bonestheme' ), 'before_widget' => '<div id="%1$s" class="widget %2$s">', 'after_widget' => '</div>', 'before_title' => '<h4 class="widgettitle">', 'after_title' => '</h4>', )); ... } Creating Widget Areas (Sidebars) functions.php
  • 51. Displaying Widget Areas (Sidebars) sidebar.php <div id="sidebar" class="sidebar cf" role="complementary"> <?php if ( is_active_sidebar( 'sidebar' ) ) : ?> <?php dynamic_sidebar( 'sidebar' ); ?> <?php endif; ?> </div>
  • 52. Advanced Custom Fields in Widgets After creating your widget using the Widget Boilerplate:
  • 53. public function widget( $args, $instance ) { extract( $args ); echo $before_widget; ?> <section> <?php $content = get_field( 'content', 'widget_' . $widget_id ); echo do_shortcode( $content ); ?> </section> <?php echo $after_widget; } Displaying ACF Fields in Widgets Accessed through second argument which is the widget_id prefixed by "widget_"
  • 54. // widget sections $sidebars_widgets = wp_get_sidebars_widgets(); $widget_ids = array_merge( $sidebars_widgets['sidebar'] ); $widget_sections_css = ''; foreach( $widget_ids as $id ) { if ( $background_color = get_field( 'background_color', 'widget_' . $id ) ) { $widget_sections_css .= " #{$id} section { background-color: {$background_color}; }"; } } if ( !empty( $widget_sections_css ) ) { wp_add_inline_style( 'my-styles', $widget_sections_css ); } Custom Styles for Widget Fields functions.php (in wp_enqueue_scripts function)
  • 56. Hooks Hooks allow you to modify, extend, and enhance WordPress through an API in your themes and plugins. There are two flavors: • Actions • Filters
  • 57. Actions Triggered by specific events, typically used for executing functions. • do_action() – Defines a hookable location • add_action() – Attaches a function to a hook defined with do_action() • has_action() – Checks if action exists • remove_action()
  • 58. Default WordPress Actions • wp_enqueue_scripts • register_sidebar • dynamic_sidebar • wp_head • get_header • get_footer • plugins_loaded • And many more… http://codex.wordpress.org/Plugin_API/Action_Reference
  • 59. <?php ... <section id="content-section-<?php echo $section_id; ?>" class="<?php echo $layout; ?>"> <?php do_action( 'my_content_section_before', $layout ); ?> <?php if ( 'content' == $layout ): // default content section ?> <?php the_sub_field( 'content' ); ?> <?php endif; ?> <?php do_action('my_content_section_after', $layout ); ?> </section> ... Custom Action Setup content-sections.php
  • 60. Custom Action Usage functions.php <?php function my_extra_content( $layout ) { echo 'This Content Section uses the layout: ' . $layout; } add_action( 'my_content_section_before', 'my_extra_content' ); Output: This Content Section uses the layout: content { section content fields displayed here… }
  • 61. Filters Functions that data passes through, typically used to manipulate data. • apply_filters() – Defines a hookable location • add_filter() – Attaches a filter to a hook defined with apply_filters() • has_filter() – Checks if filter exists • Remove_filter()
  • 62. Default WordPress Filters • the_excerpt • the_content • the_title • wp_list_pages • sanitize_title • menu_order • image_resize_dimensions • And many more… http://codex.wordpress.org/Plugin_API/Filter_Reference
  • 63. Custom Filter Setup and Usage functions.php (or separate plugin) <?php $args = array( 'post_type' => 'locations', 'region' => 'USA', 'posts_per_page' => 5 ); $locations = new WP_Query( apply_filters( 'my_locations_query', $args ) ); Usage: <?php function my_new_locations_query( $args ) { $args['region'] = 'Canada'; return $args; } add_filter( 'my_locations_query', 'my_new_locations_query' );
  • 64. A WordPress Plugin wp-content plugins my-plugin plugin.php Ta-da…
  • 65. Plugin Setup plugin.php <?php /* * Plugin Name: My Plugin * Plugin URI: http://myplugin.mysite.com * Description: It’s my plugin, and I do what I want. * Version: 1.0 * Author: Me * Author URI: http://www.mysite.com * License: GPL2 * Text Domain: my-plugin */ Plugin Boilerplate: https://github.com/tommcfarlin/WordPress-Plugin-Boilerplate
  • 66. Plugin Using Classes plugin.php <?php /* * Plugin Name: My Plugin * Plugin URI: http://myplugin.mysite.com * Description: It’s my plugin, and I do what I want. * Version: 1.0 * ... */ class MyPostType { public function __construct() { // custom post type add_action( 'init', array( $this, 'my_custom_post_type' ) ); } public function my_custom_post_type() { // my custom post type defined here } } $myPostType = new MyPostType();
  • 67. What theme components should be plugins? • Shortcodes • Custom Post Types • Custom Taxonomies • Custom Widgets Nestle users in the design, don’t trap them.
  • 68. Part 2.1 I18n (Internationalization)
  • 69. I18n (Internationalization) Making your themes / plugins translatable Standard strings: $hello = __( 'Hello there', 'my-text-domain' ); _e( 'This is echoed', 'my-text-domain' ); Singular / plural strings: _n( 'One potato', 'Many potatoes', $count, 'my-text-domain' ); Differentiating strings with similar names (setting the context): _x( 'Name', 'my context', 'my-text-domain' ); _ex( 'Echo name', 'my context', 'my-text-domain' );
  • 70. I18n with Variables Standard strings with a variable: $hello = sprintf( __( 'Hello there, %s', 'my-text-domain' ), 'Bob' ); // store in variable printf( __( 'Hello there, %s', 'my-text-domain' ), 'Bob' ); // or just output Singlular / plural strings with a variable: $potato = sprintf( _n('A lonely potato', 'Here are %d potatoes', $count, 'my-text-domain' ), $count ); // store in variable printf( _n('A lonely potato', 'Here are %d potatoes', $count, 'my-text-domain' ), $count ); // or just output
  • 71. Part 2.2 Security with Nonces
  • 72. Nonces • Protect your themes/plugins against CSRF (Cross-Site Request Forgery), multiple/invalid submissions • A.K.A. CSRF Tokens
  • 73. Adding Nonces to URLs wp_nonce_url( $actionurl, $action, $name ); Usage: $bare_url = 'http://example.com/wp-admin/ post.php?post=123&action=trash'; $complete_url = wp_nonce_url( $bare_url, 'trash-post_' . $post->ID, '_wpnonce' ); http://example.com/wp-admin/ post.php?post=123&action=trash&_wpnonce=b192fc4204 Output:
  • 74. Adding Nonces to Forms wp_nonce_field( $action, $name, $referer, $echo ); Usage: wp_nonce_field( 'delete-user_' . $user_id, '_wpnonce', true, true ); <input type="hidden" id="_wpnonce" name="_wpnonce" value="796c7766b1"> <input type="hidden" name="_wp_http_referer" value="/wp-admin/ edit-user.php"> Output:
  • 75. Adding Nonces Anywhere wp_create_nonce( $action ); Usage: wp_create_nonce( 'my-nonce' ); Value: 295a686963
  • 76. Verifying Nonces From Form / URL: check_admin_referer( 'delete-user_' . $user_id ); From some other context: wp_verify_nonce( 'delete-user_' . $user_id ); From AJAX: check_ajax_referer( 'get-users' );
  • 77. Part 2.3 Using AJAX in Plugins
  • 78. add_action( 'wp_ajax_myfunc', 'prefix_ajax_myfunc' ); add_action( 'wp_ajax_nopriv_myfunc', 'prefix_ajax_myfunc' ); function prefix_ajax_myfunc() { check_ajax_referer( 'my-nonce', 'security' ); echo $_POST['foo']; die(); } AJAX: The Setup functions.php (or separate plugin)
  • 79. AJAX: The Nonce functions.php (or separate plugin, in wp_enqueue_scripts function) <?php // Set Your Nonce $ajax_nonce = wp_create_nonce( "my-nonce" ); wp_localize_script( 'my-scripts', 'ajaxNonce', $ajax_nonce );
  • 80. AJAX: The Usage scripts.js jQuery(document).ready(function($) { var data = { action: 'myfunc', security: ajaxNonce, foo: 'Hello World!' }; $.post(ajaxurl, data, function(response) { alert("Response: " + response); }); });
  • 81. Part 3 Tips and Tricks
  • 82. Protecting Email Addresses <?php antispambot( $emailaddy, $hex_encoding ) ?> Usage: <?php echo antispambot( 'test.mctest@mysite.com' ); ?> Result: &#106;&#111;h&#110;&#46;&#100;&#111;&#101;&#64;mysit&#101;.&#99;&#111;&#109; Browser sees: test.mctest@mysite.com
  • 83. Quickstarts for Custom Components http://generatewp.com/
  • 84. Custom ACF Color Picker Swatches Customize swatches based on design / theme colors: These things
  • 85. Custom ACF Color Picker Swatches functions.php function acf_custom_config() { global $parent_file; if ( strpos($parent_file, 'post-new.php') !== FALSE || strpos($parent_file, 'edit.php') !== FALSE ) { echo " <script> jQuery(document).ready(function($){ if ($('.acf-color_picker').length) { $('.acf-color_picker').iris({ palettes: ['#f60', '#ffa839', '#3078bf', '#e0ebf5', '#58585a', '#2e3137'], change: function(event, ui) { $(this).parents('.wp-picker-container').find('.wp-color-result'). css('background-color', ui.color.toString()); } }); } }); </script> "; } } add_action( 'in_admin_footer', 'acf_custom_config' );
  • 86. Make Admin Listings Relevant Use the Admin Columns Pro plugin to clean up the post listing pages: • Show relevant columns for post types, hide unnecessary columns • Allow client to edit items in the listing (inline edits) • Display ACF PRO fields as well
  • 87. Thank You! If you ever had any questions or wanted to chat: kyle@ractoon.com

Notas do Editor

  1. In 2002 I thought I’d finally found something compact and lightweight that made sense to me. The popularity wasn’t as high as it is now, but that wasn’t a big deal to me. Then in 2007 I started working with WordPress and had similar feelings.
  2. Here we go. You signed up for the whole seat this evening, but you’re only going to need the edge.
  3. Now you’re probably going to need the rest of your seat. Go ahead and get comfortable, and please ask any questions that come to mind.
  4. From scratch you’ve got the theme started already if you follow the previous slide.
  5. Typically files in the child theme will override those of the parent, but functions.php is a special case – it does not override. The benefit of using wp_enqueue_style() over @import is that enqueued stylesheets are all referenced from the HTML output to the browser, whereas an @import statement is referenced from the main stylesheet, which is an extra step before the browser knows where to look next.
  6. Not well suited for layouts, easy to mistype a tag, forget a closing tag, or lose track especially if a large amount of shortcodes are used.
  7. This is due to wpautop( $foo, $br ) which adds paragraphs for double line breaks, an <br> for single (second argument). Can disable the filter entirely remove_filter( 'the_content', 'wpautop' ); remove_filter( 'the_excerpt', 'wpautop' );
  8. Use get_post_meta() function to display the values.
  9. What’s up with setting that $prefix? Attempts to ensure the fields are unique, and the underscore hides it from display in the Custom Fields metabox.
  10. acf-json folder in themes
  11. Duplicate style.css? The default theme style.css is a placeholder to make WordPress happy and list the theme. Bones uses enqueueing to load styles, which allows us to do cool stuff later with inline styles.
  12. If you haven’t had the pleasure of working with CSS preprocessors I’d highly recommend it, they are quite choice as Ferris Bueller would say.
  13. Register can be used in any hook, enqueue should only be used on wp_enqueue_scripts or admin_enqueue_scripts hook. Filemtime to automatically version stylesheet. get_template_directory_uri() vs. get_stylesheet_directory_uri()
  14. Register can be used in any hook, enqueue should only be used on wp_enqueue_scripts or admin_enqueue_scripts hook. Filemtime to automatically version stylesheet. get_template_directory_uri() vs. get_stylesheet_directory_uri()
  15. Banner section uses wp_localize_script to define the image since we’re using the backstretch plugin in that section.
  16. Example of slideshow, if only one image is set, centering content within containers, sizing images appropriately in containers (using custom WordPress thumbnail sizes), etc. Goldilocks syndrome, they’ll upload things that are too big or small, your job to make them just right.
  17. $slug for the generic template, $name for the specialized template
  18. Add content sections as needed
  19. We covered quite a bit so I’m going to let that marinate for a minute while I get a quick drink. Were there any questions at all?
  20. Why bother with hooks? If modifying plugin/core behavior your changes are preserved, don’t have to worry about breaking randomly in the future.
  21. Events like publishing a post, changing themes, activating/deactivating plugins
  22. Now tags or content can be inserted before and after content section content
  23. Now tags or content can be inserted before and after content section content
  24. Region is custom taxonomy
  25. Common myth – a lot of plugins slows down your site. More a factor of what the plugins do: loading lots of scripts/styles, extra database queries, expensive operations (fulltext searches), remote requests, etc.
  26. Use classes to avoid naming collisions, requires some slight tweaks to hooks though. Need to pass and array where the first item references the object, second item is method name within the class.
  27. We covered quite a bit so I’m going to let that marinate for a minute while I get a quick drink. Were there any questions at all?
  28. You can then run your files through a service such as http://www.icanlocalize.com/tools/php_scanner to create translation files (.po). Then can run through something like Poedit to translate individual strings and compile into .mo files
  29. We covered quite a bit so I’m going to let that marinate for a minute while I get a quick drink. Were there any questions at all?
  30. If anyone attempts to modify the URL or data with a nonce it fails with a 403 Forbidden response. https://www.getpantheon.com/blog/nonce-upon-time-wordpress
  31. $action – nonce action name (optional), $name – nonce name, default ‘_wpnonce’
  32. We covered quite a bit so I’m going to let that marinate for a minute while I get a quick drink. Were there any questions at all?
  33. Need _nopriv if it needs to be accessible on the front-end. By adding exit() or die() after returning your desired content prevents the default response from admin-ajax.php - usually zero (0) - being returned as well. Can also use the WP_Ajax_Response class to generate XML responses.
  34. Use 0 to only allow decimal encoding (&#123;) and 1 to also allow hex encoding (&x7B;). Default: 0