Date post: | 13-May-2015 |
Category: |
Education |
Upload: | tammy-hart |
View: | 9,529 times |
Download: | 2 times |
Custom WORDPRESS THEMEDevelopmentTech Mixer University 2011
Intro to THEME DEVELOPMENTCrash course
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
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>
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). */
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.
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; ?>
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; ?>
Template Hierarchy
Different kinds of WordPress magic happens on templates depending on what the template name is.
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
Template HierarchyIt all ends at the index
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
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');
Custom POST TYPES & TAXONOMIESMake your own stuff
What is a Post Type?
Content entered into the database goes into the posts table and is assigned a post_type.
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
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.
Default Taxonomies Post Taxonomies
Category - hierarchical Post Tag - non-hierarchical
Other Link Category - for the links system Nav menu - used in the menu system
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
Useful Plugins
Like most things in WordPress, there are plugins that help create and manage Custom Post Types and Taxonomies.
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
Registration Code
The best method for creating Custom Post Types and taxonomies for is to register them yourself without a plugin.
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 );}
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 );}
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
Custom META BOXESNeed more input
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.
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
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>
Custom FieldsEdit post screen
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.
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');}
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')
));
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>';
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>';}
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);}
}}
Custom Meta Box UI
Output the Data
Using the functions we discussed before, we can now use this data in our template.
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 →</p>';
The Ugly:the_meta();
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 →</a></li><li><b>Release Date:</b> <?= $date; ?></li><li><b>Tools Used:</b> <?= $tools; ?></li>
</ul>
Custom THEME OPTIONSEven more stuff
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.
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
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.
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');}
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');}
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.')
);
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>';
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>';}
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;
}
Theme OptionsOur custom fields
Output the Data
Create a function to call the data from the setting and use it in your templates.
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);}
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>
DownloadSee these slides and get all of the code we covered today:
bit.ly/tmu_wp