Beyond Posts & Pages - Structured Content in WordPress
Upcoming SlideShare
Loading in...5

Beyond Posts & Pages - Structured Content in WordPress



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

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.



Total Views
Views on SlideShare
Embed Views



3 Embeds 11 6 3 2



Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment
  • Growing up in Dublin we didn’t get a lot of snow, so this was a kids dream come true. Another highlight that year was this.
  • Karen McGrane, Jeff Eaton, Deanne Barker and many others have long talked about the difference between content management systems and web publishing systems. In a web publishing system, the focus is on “making web pages” – and we mix structure and content. In a true content management system the two are separate
  • Arguably, by default, WordPress creates “blobs” – what does in to that big primary WYSIWYG editor is a mixture of headings, subheadings, callouts, images, and other content – but in a fully unstructured way.
  • But we do actually have some existing metadata:DateCategoriesTagsTitleExcerptPost Thumbnail / Featured ImageAuthor info (based on the logged in user). Further, media “attached” to the post are tracked as a relationship in meta and can be pulled up, including post-thumbnail.
  • NPR Case study – Create Once, Publish Everywhere. Today we will focus on the content entry part of the equation, and less on display – though I’ll talk about that at the end
  • Even as just stories they can be incredibly powerful.But we also have the opportunity to make them real. So I wanted to talk a little about how we can think about the systems we build and the stories we tell in a different way. So that maybe we can help create the kind of experiences that stay with people forever.
  • In this simple example, we get a custom post type for alerts but there isn’t really much complexity to it – otherwise it is mostly a blob. I do get to use the “date published” differently in the template

Beyond Posts & Pages - Structured Content in WordPress Beyond Posts & Pages - Structured Content in WordPress Presentation Transcript

  • Beyond Posts & Pages Getting Chunky with WordPress WordCamp Boston 2013 #wcbos #chunky @jeckman
  • #wcbos #chunky @jeckman
  • 3 #wcbos #chunky @jeckman
  • #wcbos #chunky @jeckman
  • Structured Content FTW WordPress 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 #wcbos #chunky @jeckman
  • Adaptive Content 1. 2. 3. 4. 5. Reusable content Structured content Presentation-independent content Meaningful metadata Usable CMS interfaces #wcbos #chunky t-strategy-for-mobile @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 Jacobson #wcbos #chunky ve_content_management @jeckman
  • WordPress Blobs #wcbos #chunky @jeckman
  • #wcbos #chunky @jeckman
  • Can WordPress COPE? #wcbos #chunky @jeckman
  • We can make WordPress chunkier. #wcbos #chunky @jeckman
  • #wcbos #chunky m-made-for-you-furry-monster-feet @jeckman
  • Custom Post Types Custom Taxonomies Custom 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 #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 Types Custom Taxonomies Custom Meta Data #wcbos #chunky @jeckman
  • Example: Stories Here we have a custom post type for “Stories” with two custom taxonomies: Locations and Topics #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 Types Custom Taxonomies Custom 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, update_post_meta($post_id, update_post_meta($post_id, update_post_meta($post_id, } #wcbos #chunky 'pullquote',$_POST['pullquote']); 'school', $_POST['school'] ); 'teacher', $_POST['teacher'] ); 'coaches', $_POST['coaches'] ); @jeckman
  • #wcbos #chunky @jeckman
  • Chunky Via Plugins • Custom Post Type UI – • Custom Post Type List Shortcode – • Secondary HTML Content – • Attachments – #wcbos #chunky @jeckman
  • #wcbos #chunky @jeckman
  • For Further Exploration • Relationships between Posts #wcbos #chunky @jeckman
  • #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 ( ) – JavaScript ( see ) – API ( ) #wcbos #chunky @jeckman
  • Thank You! @jeckman #wcbos #chunky @jeckman