56
Custom WORDPRESS THEME Development Tech Mixer University 2011

Custom WordPress theme development

Embed Size (px)

DESCRIPTION

Go over a quick crash course into what it takes to develop a WordPress theme and then jump into some deeper waters on how to utilize Custom Post Types, create custom theme options, and custom meta boxes.

Citation preview

Page 1: Custom WordPress theme development

Custom WORDPRESS THEMEDevelopmentTech Mixer University 2011

Page 2: Custom WordPress theme development

Intro to THEME DEVELOPMENTCrash course

Page 3: Custom WordPress theme development

What is a WordPress theme?

A group of templates and a stylesheet that displays content entered into the database via the WordPress admin.

At a minimum, you need: index.php style.css

Page 4: Custom WordPress theme development

Index.php<html><head>

<link rel="stylesheet" href="<? bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />

<title><? wp_title(''); ?></title></head>

<body><header><? bloginfo('name'); ?></header><nav><? wp_list_pages(); ?></nav><section>

…loop with <article />…</section><footer>© <?= date('Y').' '.get_bloginfo('name'); ?></footer>

</body></html>

Page 5: Custom WordPress theme development

Style.css/* Theme Name: Twenty Ten Theme URI: http://wordpress.org/ Description: The 2010 default theme for WordPress. Author: wordpressdotorg Author URI: http://wordpress.org/ Version: 1.0 Tags: black, blue, white, two-columns, fixed-width, custom-header, custom-background, threaded-comments, sticky-post, translation-ready, microformats, rtl-language-support, editor-style, custom-menu (optional)

License: License URI:

General comments (optional). */

Page 6: Custom WordPress theme development

What is the Loop?

PHP that uses the prefetched query of the current page to loop through the posts and displays the data as outlined in the current page’s template.

Page 7: Custom WordPress theme development

Basic Loop<? if (have_posts()) : while(have_posts()) : the_post(); ?>

<h2><a href="<? the_permalink(); ?>"><? the_title(); ?></a></h2>

<? the_content(); ?>

<p class="postmetadata"><? the_date('F j, Y'); ?> Posted in: <? the_category(', '); ?>

</p>

<? endwhile; else: ?>

<p>No Posts Found</p>

<? endif; ?>

Page 8: Custom WordPress theme development

Custom Loop<? $args = array(

'post_type' => 'movie','numberposts' => 10,'meta_key' => 'production_year','meta_value' => '1983','orderby' => 'meta_value');

$loop = new WP_query($args);

if ($loop->have_posts()) : while($loop->have_posts()) : $loop->the_post(); ?>

… stuff …

<? endwhile; else: ?>

<p>No Posts Found</p>

<? endif; ?>

Page 9: Custom WordPress theme development

Template Hierarchy

Different kinds of WordPress magic happens on templates depending on what the template name is.

Page 10: Custom WordPress theme development

Common Pages Homepage

home.php index.php

Single Post display single-{post_type}.php single.php index.php

Page display custom template page-{slug}.php page-{id}.php page.php index.php

Search Result display search.php index.php

404 (Not Found) display 404.php index.php

Attachment display MIME_type.php attachment.php single.php index.php

Archive Pages Category display

category-{slug}.php category-{id}.php category.php archive.php index.php

Tag display tag-{slug}.php tag-{id}.php tag.php archive.php index.php

Custom Taxonomies taxonomy-{taxonomy}-

{term}.php taxonomy-

{taxonomy}.php taxonomy.php archive.php index.php

Custom Post Types display

archive-{post_type}.php

archive.php index.php

Author display author-{nicename}.php author-{id}.php author.php archive.php index.php

Date display date.php archive.php index.php

Page 11: Custom WordPress theme development

Template HierarchyIt all ends at the index

Page 12: Custom WordPress theme development

A Basic Theme 404.php - Custom “not found” page archive.php - Overall template for archived content attachment.php - Overall template for attachments of any mime type comments.php - The template called with comments_template() footer.php - The template called with get_footer() functions.php - A place to create custom functions, register sidebars, and other settings header.php - The template called with get_header() index.php - The basic home template page.php - Overall template for pages search.php - Search results template searchform.php - The template called with get_search_form() sidebar.php - The template called with get_sidebar() single.php - Overall template for single posts style.css - The main stylesheet

Page 13: Custom WordPress theme development

Bonus Template Functions

Call alternate comment, sidebar, header, and footer templates

short-comments.php - comments_template('/short-comments.php')

sidebar-simple.php - get_sidebar('simple');

header-simple.php - get_header('simple');

footer-simple.php - get_footer('simple');

Page 14: Custom WordPress theme development

Custom POST TYPES & TAXONOMIESMake your own stuff

Page 15: Custom WordPress theme development

What is a Post Type?

Content entered into the database goes into the posts table and is assigned a post_type.

Page 16: Custom WordPress theme development

Default Post Types Main Content

Post - blog style content Page - static content

Other Attachment - any images or other files uploaded to a post (of any type) Revision - an archive of version of a particular post Nav Menu Item - used in the menu system

Page 17: Custom WordPress theme development

What is a Taxonomy?

Content can be organized by assigning terms to them. Terms are saved in the terms table, then they are grouped into a taxonomy in the term_taxonomy table, and finally they are related to posts in the term_relationships table.

Page 18: Custom WordPress theme development

Default Taxonomies Post Taxonomies

Category - hierarchical Post Tag - non-hierarchical

Other Link Category - for the links system Nav menu - used in the menu system

Page 19: Custom WordPress theme development

Custom Examples Post Type: Movie

Taxonomy: Actor Term: Debbie Reynolds Term: Angeline Jolie Term: Clark Gable Term: Ewan McGregor

Taxonomy: Director Term: Ron Howard Term: Steven Spielberg

Post Type: Book Taxonomy: Author

Term: Frank Peretti Term: James Patterson Term: Seth Godin Term: Lynn Austin

Taxonomy: Publisher Term: Atlas Press Term: Hay House Term: O’Reilly Media

Taxonomy: Subject Term: Arts & Photography Term: Suspense & Horror Term: Reference

Post Type: Photo Taxonomy: Album

Term: Summer Child Term: Fourth of July Child Term: First Day of School

Term: Christmas Term: Sports

Taxonomy: Year Term: 2001 Term: 2002 Term: 2003

Post Type: Project Taxonomy: Type

Term: Design Child Term: Logo Child Term: Brochure Child Term: Website

Term: Development Taxonomy: Tools

Term: Photoshop Term: HTML5 Term: JavaScript Term: WordPress

Page 20: Custom WordPress theme development

Useful Plugins

Like most things in WordPress, there are plugins that help create and manage Custom Post Types and Taxonomies.

Page 21: Custom WordPress theme development

Create Custom Post Type UI

Creates Both TONS of labeling options

WP Post Type UI Creates Both Buggy Allows a custom icon

More Types & More Taxonomies Separate plugins for each Allows you to override built in types

and taxonomies Allows a custom icon Works seamlessly with the More

Fields Plugin (stay tuned for more)

Manage Custom Post Type Order

Drag and drop ordering

Post Type Switcher Change the post type one item at a time

Convert Post Types Bulk edit post types

Term Management Tools Merge - combine two or more terms

into one Set parent - set the parent for one or

more terms (for hierarchical taxonomies)

Change taxonomy - convert terms from one taxonomy to another

Page 22: Custom WordPress theme development

Registration Code

The best method for creating Custom Post Types and taxonomies for is to register them yourself without a plugin.

Page 23: Custom WordPress theme development

register_post_type()add_action( 'init', 'register_cpt_project' );

function register_cpt_project() {

$labels = array( 'name‘ => _x( 'Projects', 'project' ), 'singular_name' => _x( 'Project', 'project' ), 'add_new‘ => _x( 'Add New', 'project' ), 'add_new_item' => _x( 'Add New Project', 'project' ), 'edit_item' => _x( 'Edit Project', 'project' ), 'new_item' => _x( 'New Project', 'project' ), 'view_item' => _x( 'View Project', 'project' ), 'search_items‘ => _x( 'Search Projects', 'project' ), 'not_found' => _x( 'No projects found', 'project' ), 'not_found_in_trash' => _x( 'No projects found in Trash', 'project' ), 'parent_item_colon' => _x( 'Parent Project:', 'project' ), 'menu_name' => _x( 'Projects ', 'project' ) );

$args = array( 'labels' => $labels,'hierarchical' => false, 'supports‘ => array( 'title', 'editor',

'thumbnail' ), 'public' => true,'show_ui' => true,'show_in_menu' => true,'show_in_nav_menus' => false,'publicly_queryable' => true,'exclude_from_search' => false,'has_archive' => true,'query_var' => true,'can_export' => true,'rewrite' => true,'capability_type' => 'post'

);

register_post_type( 'project', $args );}

Page 24: Custom WordPress theme development

register_taxonomy()add_action( 'init', 'register_taxonomy_type' );

function register_taxonomy_type() {

$labels = array( 'name' => _x( 'Types', 'type' ),'singular_name' => _x( 'Type', 'type' ),'search_items‘ => _x( 'Search Types', 'type' ),'popular_items' => _x( 'Popular Types', 'type' ),'all_items‘ => _x( 'All Types', 'type' ),'parent_item' => _x( 'Parent Type', 'type' ),'parent_item_colon' => _x( 'Parent Type:', 'type' ),'edit_item' => _x( 'Edit Type', 'type' ),'update_item' => _x( 'Update Type', 'type' ),'add_new_item' => _x( 'Add New Type', 'type' ),'new_item_name' => _x( 'New Type Name', 'type' ),'add_or_remove_items' => _x( 'Add or remove types', 'type' ),'menu_name' => _x( 'Types', 'type' ),

);

$args = array( 'labels' => $labels,'public‘ => true,'show_in_nav_menus' => true,'show_ui' => true,'show_tagcloud' => false,'hierarchical‘ => true,

'rewrite' => true,'query_var' => true

);

register_taxonomy( 'type', 'project', $args );}

Page 25: Custom WordPress theme development

There’s still an easy way outDon’t get too worried about memorizing all of this. Just memorize the web address where you can find two amazing generators:

Themergency.com/generators

Page 26: Custom WordPress theme development

Custom META BOXESNeed more input

Page 27: Custom WordPress theme development

What are Custom Fields?

The postmeta table holds extra data and options attached to each post. Custom fields can be used by theme and plugin developers to save extra pieces of information that you can use in templates and other places.

Page 28: Custom WordPress theme development

How Custom fields work The data is saved in the postmeta table

meta_id - the ID of the item being saved post_id - the ID of the post it belongs to meta_key- the name of the data being collected meta_value - the entered value

Use the data in a template or function get_post_meta() - returns the values of the specified key the_meta() - outputs a simple list of all custom fields and their values get_post_custom() - returns a multidimensional array with all custom fields of

a particular post or page

Page 29: Custom WordPress theme development

Code ExamplesExample 1:$my_key = get_post_meta($post->ID, 'my_key', true);

if ($my_key != '')echo '<p>' . $my_key . '</p>';

Example 2:<? $my_meta = get_post_custom(); ?><ul class="my_meta">

<li><b>Nice Label 1:</b> <?= $meta['my_key_1'][0]; ?></li><li><b>Nice Label 2:</b> <?= $meta['my_key_2'][0]; ?></li><li><b>Nice Label 3:</b> <?= $meta['my_key_3'][0]; ?></li>

</ul>

Page 30: Custom WordPress theme development

Custom FieldsEdit post screen

Page 31: Custom WordPress theme development

Create Your Own UI

Adding a meta box for entering in values for custom fields can make it so much easier for the user to add things like dates or select from a premade list of values.

Page 32: Custom WordPress theme development

add_meta_box() add_meta_box( $id, $title, $callback, $page, $context, $priority, $callback_args );

$id - HTML 'id' attribute of the edit screen section $ title - title of the edit screen section, visible to user $callback - function that prints out the HTML for the edit screen section. $page - the type of Write screen on which to show the edit screen section $context - the part of the page where the edit screen section should be shown $priority - the priority within the context where the boxes should show $callback_args - arguments to pass into your callback function

add_action('admin_menu', 'project_add_box');function project_add_box() { global $meta_fields; add_meta_box('project_info', 'Project Info', 'project_show_box', 'project', 'normal', 'high');}

Page 33: Custom WordPress theme development

Array of Fields$meta_fields = array(

array('name' => 'Project URL','desc' => 'URL to the live

site.','id' => 'url','type' => 'text','value' => 'http://'

),

array('name' => 'Project Date','desc' => 'When the project

was released.','id' => 'date','type‘ => 'date'

),

array('name' => 'Tools','desc' =>

'What tools did you use for this project?','id'

=> 'tools','type' =>

'checkbox_group','options' =>

array( 'jQuery', 'HTML5', 'CSS 3', 'Photoshop', 'Illustrator', 'WordPress')

));

Page 34: Custom WordPress theme development

Callbackfunction project_show_box() {

global $meta_fields, $post;

// Use nonce for verificationecho '<input type="hidden" name="project_meta_box_nonce" value="',

wp_create_nonce(basename(__FILE__)), '" />';

// start a tableecho '<table class="form-table">';

// start a loop through the fieldsforeach ($meta_fields as $field) {

// get current post meta data$meta = get_post_meta($post->ID, $field['id'], true);

// start a table rowecho '<tr> <th style="width:20%"><label for="', $field['id'], '">',

$field['name'], '</label></th>','<td>';

Page 35: Custom WordPress theme development

Switch Caseswitch ($field['type']) {

// textcase 'text':

echo '<input type="text" name="', $field['id'], '" id="', $field['id'], '" value="', $meta ? $meta : $field['value'], '" size="30" style="width:97%" /> <br /><span class="desc">', $field['desc'], '</span>';

break;

… continue with other field types …

} // end switchecho '<td>', '</tr>';

} // end foreach echo '</table>';}

Page 36: Custom WordPress theme development

Save Postadd_action('save_post', 'project_save_data');

// Save data from meta boxfunction project_save_data($post_id) {

global $meta_fields;

// verify nonceif (!

wp_verify_nonce($_POST['project_meta_box_nonce'], basename(__FILE__)))

return $post_id;

// check autosaveif (defined('DOING_AUTOSAVE') &&

DOING_AUTOSAVE)return $post_id;

// check permissionsif ('page' == $_POST['post_type']) {

if (!current_user_can('edit_page', $post_id))

return $post_id;} elseif (!current_user_can('edit_post',

$post_id)) {return $post_id;

}

foreach ($meta_fields as $field) {

// get the current value$old = get_post_meta($post_id,

$field['id'], true);

// get the new value$new = $_POST[$field['id']];

// update if there’s a new valueif ($new && $new != $old) {

update_post_meta($post_id, $field['id'], $new);

// delete if the new value is empty

} elseif ('' == $new && $old) {delete_post_meta($post_id,

$field['id'], $old);}

}}

Page 37: Custom WordPress theme development

Custom Meta Box UI

Page 38: Custom WordPress theme development

Output the Data

Using the functions we discussed before, we can now use this data in our template.

Page 39: Custom WordPress theme development

The Bad and the Ugly

The Bad:$url = get_post_meta($post->ID, ‘url', true);

if ($my_key != '')echo '<a href="' . $my_key . '“>Visit Site &rarr;</p>';

The Ugly:the_meta();

Page 40: Custom WordPress theme development

The Good<? $meta = get_post_custom();// url$url = $meta['url'][0];// date$date = $meta['date'][0];$date = strtotime($date);$date = date('F j, Y', $date);// tools$tools = $meta['tools'][0];$tools = unserialize($tools);$tools = implode(', ', $tools);?>

<ul class="post-meta"><li><a href="<?= $url; ?>">Visit Site &rarr;</a></li><li><b>Release Date:</b> <?= $date; ?></li><li><b>Tools Used:</b> <?= $tools; ?></li>

</ul>

Page 41: Custom WordPress theme development

Custom THEME OPTIONSEven more stuff

Page 42: Custom WordPress theme development

Why is this useful?

You can create an easy way to input additional data that can be used in a variety of ways in your theme.

Page 43: Custom WordPress theme development

Example Usages Social Networks

The user can insert their twitter, facebook, etc. handles once The template outputs these in the necessary places of the theme

On/Off switches Show secondary navigation? Are you available for live chat? Use Breadcrumbs?

Custom layout options Two column featured posts 3 Category Posts Featured slider with recent posts listed below

Page 44: Custom WordPress theme development

Create Your Own

This is almost as simple as adding a custom meta box, except the data isn’t limited to just a post, it can be used site wide.

Page 45: Custom WordPress theme development

add_theme_page() add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function);

$page_title - the text to be displayed in the title tags of the page when the menu is selected $menu_title - the text to be used for the menu $capability - the capability required for this menu to be displayed to the user $menu_slug - the slug name to refer to this menu by (should be unique for this menu) $function - the function to be called to output the content for this page

add_action( 'admin_menu', 'theme_options_add_page' );

function theme_options_add_page() {add_theme_page( 'Theme Options', 'Theme Options',

'edit_others_posts', 'theme_options', 'theme_options_do_page');}

Page 46: Custom WordPress theme development

register_setting() register_setting( $option_group, $option_name, $sanitize_callback );

$option_group - settings group name $option_name - the name of an option to sanitize and save $sanitize_callback - a callback function that sanitizes the option's value

add_action( 'admin_init', 'theme_options_init' );

function theme_options_init(){register_setting( 'our_options', 'our_theme_options',

'theme_options_validate');}

Page 47: Custom WordPress theme development

Array of Fields$fields = array(

array('label' => 'Social Media','type' => 'section'

),array(

'label' => 'Facebook','id' => 'facebook','type' => 'text','desc' => 'Facebook URL'

),array(

'label' => 'Youtube','id' => 'youtube','type' => 'text','desc' => 'Youtube URL'

),

array('label' => 'Twitter','id' => 'twitter','type' => 'text','desc' => 'Twitter URL'

),array(

'label' => 'Miscellaneous',

'type' => 'section'),array(

'label' => 'Featured Video',

'id' => 'featvideo','type' => 'text','desc' => 'Youtube URL

for video to be featured on the homepage.')

);

Page 48: Custom WordPress theme development

Callbackfunction theme_options_do_page() {

global $fields;

if(!isset( $_REQUEST['settings-updated']))$_REQUEST['settings-updated'] =

false;

// the page headingecho '<div class="wrap">';screen_icon();echo '<h2>Theme Options</h2>';

// notifies on load if options were savedif(false !== $_REQUEST['settings-

updated'])echo '<div class="updated

fade"><p><strong>Options saved</strong></p></div>';

// start formecho '<form method="post"

action="options.php">';settings_fields( 'our_options' );

// get the settings$options = get_option('our_theme_options');

// start a tableecho '<table id="options" class="form-

table">';

// start a loop through the fieldsforeach ($fields as $field) {

// section rowsif ($field['type'] == 'section') {echo '<tr><td colspan="2"><h3>',

$field['label'], '</h3></td></tr>';}

// field rowselse {// start a table rowecho '<tr valign="top"><th scope="row">',

$field['label'], '</th>','<td>';

Page 49: Custom WordPress theme development

Switch Caseswitch ($field['type']) {

// textcase 'text':

echo '<input type="text" name= "our_the_options[', $field['id'], ']" id="', $field['id'], '" value="', $meta ? $meta : $field['value'], '" size="30" style="width:97%" /> <br /><span class="desc">', $field['desc'], '</span>';

break;

… continue with other field types …

} // end switchecho '<td>', '</tr>';

} // end foreachecho '</table>';// close out the containerecho '<p class="submit"><input type="submit" class="button-primary" value="Save

Options" /></p></form></div>';}

Page 50: Custom WordPress theme development

Save Datafunction theme_options_validate( $input ) {

global $fields;

foreach ($fields as $field) {switch ($field['type']) {

//textcase 'text':

// Say our text option must be safe text with no HTML tags$input[$field['id']] =

wp_filter_nohtml_kses( $input[$field['id']] );break;

… continue with other field types …

} // end switch} // end foreachreturn $input;

}

Page 51: Custom WordPress theme development

Theme OptionsOur custom fields

Page 52: Custom WordPress theme development

Output the Data

Create a function to call the data from the setting and use it in your templates.

Page 53: Custom WordPress theme development

Custom Functions// get the value we savedfunction get_our_options($field) {

$options = get_option('our_theme_options');return $options[$field];

}

// print the valuefunction our_options($field) {

print get_our_options($field);}

Page 54: Custom WordPress theme development

OutputSocial Links:<ul class="social-links">

<li><a href="<? our_options('facebook'); ?>">Facebook</a></li>

<li><a href="<? our_options('youtube'); ?>">Youtube</a></li><li><a href="<? our_options('twitter'); ?>">Twitter</a></li>

</ul>

Miscellaneous:<div class="featured-video">

<?= apply_filters('the_content', get_our_options('featvideo')); ?></div>

Page 55: Custom WordPress theme development

DownloadSee these slides and get all of the code we covered today:

bit.ly/tmu_wp

Page 56: Custom WordPress theme development

Thank You! QUESTIONS?Tammy Hart@tammyhart

[email protected]