The document provides an overview of building potent WordPress websites. It discusses themes, plugins, and tips for WordPress development. The document is divided into three parts: the appearance (themes), plugins, and tips/tricks. Under themes, it covers starting points, child themes, frameworks, modular design, goals, potential paths like shortcodes and custom fields, stylesheets, scripts, and content section types. The plugins section discusses hooks, actions, and filters. The tips/tricks section was not included in the summary.
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.
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/
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
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 ); ?>
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' ); ?>
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
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
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()
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()
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.
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
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' );
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 del editor
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.
Here we go. You signed up for the whole seat this evening, but you’re only going to need the edge.
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.
From scratch you’ve got the theme started already if you follow the previous slide.
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.
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.
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' );
Use get_post_meta() function to display the values.
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.
acf-json folder in themes
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.
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.
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()
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()
Banner section uses wp_localize_script to define the image since we’re using the backstretch plugin in that section.
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.
$slug for the generic template, $name for the specialized template
Add content sections as needed
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?
Why bother with hooks? If modifying plugin/core behavior your changes are preserved, don’t have to worry about breaking randomly in the future.
Events like publishing a post, changing themes, activating/deactivating plugins
Now tags or content can be inserted before and after content section content
Now tags or content can be inserted before and after content section content
Region is custom taxonomy
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.
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.
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?
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
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?
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
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?
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.
Use 0 to only allow decimal encoding ({) and 1 to also allow hex encoding (&x7B;). Default: 0