beyond posts & pages - structured content in wordpress
DESCRIPTION
The introduction of Custom Content Types was one of the core tipping points where WordPress went from a solid blogging platform on which you could do some simple CMS-style sites to a full fledged CMS which was capable of driving more complex content-centered web applications. In this talk I’ll briefly cover the “blobs vs chunks” distinction popularized by Karen McGrane and why content modeling matters in the CMS world. Then we’ll cover custom post types, custom meta fields, custom taxonomies, and other ways of doing structured content in WordPress.TRANSCRIPT
#wcbos #chunky @jeckman
Beyond Posts & PagesGetting Chunky with
WordPressWordCamp Boston 2013
#wcbos #chunky @jeckmanhttp://www.isitedesign.com/
#wcbos #chunky @jeckman3http://delight.us/
#wcbos #chunky @jeckmanhttp://www.cmsmyth.com/
#wcbos #chunky @jeckman
Structured Content FTWWordPress Can COPE
What Next
#wcbos #chunky @jeckman
Structured Content
#wcbos #chunky @jeckman
“We don't need more content – we need content that does more”
- Sara Wachter Boettcher
http://www.cmsmyth.com/2013/04/content-that-does-more/
#wcbos #chunky @jeckman
Adaptive Content
1. Reusable content2. Structured content3. Presentation-independent content4. Meaningful metadata5. Usable CMS interfaces
http://www.abookapart.com/products/content-strategy-for-mobile
#wcbos #chunky @jeckman
Web Publishing
Content Management
#wcbos #chunky @jeckman
“WPT’s capture content with the primary purpose of publishing web pages. . . . CMS’s, on the other hand, store the content
cleanly, enabling the presentation layers to worry
about how to display the content.” - Daniel Jacobsonhttp://www.markboulton.co.uk/journal/
adaptive_content_management
#wcbos #chunky @jeckman
WordPress Blobs
#wcbos #chunky @jeckman
#wcbos #chunky @jeckman
Can WordPress COPE?
http://www.slideshare.net/zachbrand/npr-api-create-once-publish-everywhere
#wcbos #chunky @jeckman
We can makeWordPresschunkier.
#wcbos #chunky @jeckmanhttp://www.etsy.com/listing/102633258/custom-made-for-you-furry-monster-feet
#wcbos #chunky @jeckman
Custom Post TypesCustom TaxonomiesCustom Meta Data
#wcbos #chunky @jeckman
Example: Alerts
#wcbos #chunky @jeckman
Example: Alerts
#wcbos #chunky @jeckman
register_post_type()
Arguments passed control:• What to call it (Labels)• Where to show it– Public, Show UI, Searchable, has_archive– Menu position
• Who can use it (capabilities)• What it includes (supports)
#wcbos #chunky @jeckman
add_action( 'init', 'create_post_type' );function create_post_type() {
register_post_type( 'alerts',array('labels' => array(
'name' => __( 'Alerts' ),
'singular_name' => __( 'Alert' )),
'public' => true,'has_archive' => true,));
}
#wcbos #chunky @jeckman
Example: Slides
http://wordpress.org/plugins/meteor-slides/
#wcbos #chunky @jeckman
function meteorslides_register_slides() { $meteor_labels = array(
'name' => __( 'Slides', 'meteor-slides' ),
'singular_name’ => __( 'Slide', 'meteor-slides' ),'add_new' => __( 'Add New', 'meteor-
slides' ),'add_new_item’ => __( 'Add New Slide', 'meteor-
slides' ),'edit_item' => __( 'Edit Slide', 'meteor-
slides' ),'new_item' => __( 'New Slide', 'meteor-
slides' ),'view_item' => __( 'View Slide', 'meteor-
slides' ),'search_items' => __( 'Search Slides', 'meteor-
slides' ),'not_found' => __( 'No slides found', 'meteor-
slides' ),'not_found_in_trash' => __( 'No slides found in
Trash', 'meteor-slides' ),
'parent_item_colon’ => '','menu_name’ => __( 'Slides', 'meteor-slides' )
);
#wcbos #chunky @jeckman
$meteor_args = array('labels' => $meteor_labels,'public' => true,'publicly_queryable' => false,'exclude_from_search' => true,'show_ui' => true,'show_in_menu' => true,'menu_icon' => ''. plugins_url(
'/images/slides-icon-20x20.png', __FILE__ ),
'capability_type' => $meteor_capabilitytype,
'capabilities' => $meteor_capabilities,
'map_meta_cap' => $meteor_mapmetacap,'hierarchical' => false,'supports' => array( 'title',
'thumbnail' ),'taxonomies' =>
array( 'slideshow' ),'has_archive' => false,'rewrite' => false,'query_var' => true,'can_export' => true,'show_in_nav_menus' => false);
#wcbos #chunky @jeckman
Custom Post TypesCustom TaxonomiesCustom Meta Data
#wcbos #chunky @jeckman
Here we have a custom post type for “Stories” with two custom taxonomies: Locations and Topics
Example: Stories
#wcbos #chunky @jeckman
These Meta Boxes enable selection of Location / Topic from a pre-defined set
#wcbos #chunky @jeckman
function gc_taxonomies_story_topic() { $labels = array( 'name =>' _x( 'Topics', 'taxonomy general name' ), 'singular_name’ => _x( 'Topic’,'taxonomy singular name' ), 'search_items' => __( 'Search Topics' ), 'all_items' => __( 'All Topics' ), 'edit_item' => __( 'Edit Topic' ), 'update_item' => __( 'Update Topics' ), 'add_new_item' => __( 'Add New Topic' ), 'new_item_name' => __( 'New Topic' ), 'menu_name' => __( 'Topics' ), 'popular_items' => NULL, ); $args = array( 'labels' => $labels, 'hierarchical' => false,
'show_tagcloud' => false, 'show_admin_column' => true,
); register_taxonomy( 'topic', 'story', $args );}
#wcbos #chunky @jeckman
add_action('admin_menu','remove_my_meta_boxen'); function remove_my_meta_boxen() { remove_meta_box('tagsdiv-locations','story','core'); remove_meta_box('tagsdiv-topic','story','core');} function add_locations_box() { add_meta_box('location_box_ID', __('Location'),
'gc_style_locations','story', 'side', 'core');} function add_topics_box() { add_meta_box('topic_box_ID',__('Topic'), 'gc_style_topics', 'story', 'side', 'core');}
#wcbos #chunky @jeckman
function gc_style_locations($post) { echo '<input type="hidden" name="taxonomy_noncename" id="taxonomy_noncename" value="' . wp_create_nonce( 'taxonomy_location' ) . '" />’; $locations = get_terms('locations', 'hide_empty=0'); ?><select name='story_locations' id='story_location’><?php
$names = wp_get_object_terms($post->ID, 'locations'); print_r($post);?><option class='location-option' value=’’ <?php if (!count($names)) echo "selected";?>>None</option><?php foreach ($locations as $location) { if (!is_wp_error($names) && !empty($names)
&& !strcmp($location->slug, $names[0]->slug)) echo "<option class='location-option' value='" .
$location->term_id . "' selected>" . $location->name . "</option>\n"; else echo "<option class='location-option' value='" . $location->term_id . "'>" . $location->name . "</option>\n"; } ?> </select> <?php }
#wcbos #chunky @jeckman
Custom Post TypesCustom TaxonomiesCustom Meta Data
#wcbos #chunky @jeckman
We’ve also got custom meta data here for:• Pull Quote• School• Teacher• Democracy Coaches
#wcbos #chunky @jeckman
Custom Post Meta Boxes
• add_meta_box() passed a styling function• style function outputs the html needed for
admin screen• save function added to save_post action• update_post_meta to store
#wcbos #chunky @jeckman
function add_meta_boxen() { add_meta_box('pullquote_box_ID',__('Quote'),
'gc_style_pullquote','story','side','core'); add_meta_box('school_box_ID',__('School'),
'gc_style_school','story','side','core'); add_meta_box('teacher_box_ID',__('Teacher'),
'gc_style_teacher','story','side','core'); add_meta_box('coaches_box_ID',__(’Coaches'),
'gc_style_coaches’,'story','side','core');}
#wcbos #chunky @jeckman
function save_taxonomy_data($post_id) { // <snip> $post = get_post($post_id); if ($post->post_type == 'story') { $location = $_POST['story_locations']; wp_set_object_terms( $post_id,(int) $location,
'locations' ); }
if ($post->post_type == 'story') { $topic = $_POST['story_topics'];
wp_set_object_terms( $post_id, (int) $topic, 'topic' ); }
update_post_meta($post_id, 'pullquote',$_POST['pullquote']);update_post_meta($post_id, 'school', $_POST['school'] );update_post_meta($post_id, 'teacher', $_POST['teacher'] );update_post_meta($post_id, 'coaches', $_POST['coaches'] );}
#wcbos #chunky @jeckman
#wcbos #chunky @jeckman
Chunky Via Plugins
• Custom Post Type UI– http://wordpress.org/plugins/custom-post-type-
ui/
• Custom Post Type List Shortcode– http://wordpress.org/plugins/custom-post-type-
list-shortcode/
• Secondary HTML Content– http://wordpress.org/extend/plugins/secondary-
html-content/
• Attachments– http://wordpress.org/extend/plugins/
attachments/
#wcbos #chunky @jeckman
#wcbos #chunky @jeckman
For Further Exploration
• Relationships between Posts
#wcbos #chunky @jeckmanhttp://core.trac.wordpress.org/ticket/10657
#wcbos #chunky @jeckman
For Further Exploration
• Relationships between Posts• Display of Custom Post Types– archive-{post_type}.php– single-{post_type}.php
• Expanding the WordPress presentation tier– Timber ( http://jarednova.github.io/timber/ ) – JavaScript ( see
http://www.kadamwhite.com/archives/2013/video-evolving-your-javascript-with-backbone-js )
– API (http://developer.wordpress.com/docs/api/ )
#wcbos #chunky @jeckman
Thank You!@jeckman