Customizing WordPress Child Theme
In this tutorial we will create Custom Post Types and add variables and functionality to them. Also we will add some styling for more user-friendly display in the dashboard.
Having set up our basic Child Theme structure we will now proceed with the customization. But before that we will do some basic WP configuration and go through the settings. You may be used to building WordPress based sites and therefore you may have some habits in as much as settings and configuration are concerned.
Semiomantics XO Custom Magazine for WordPress
Some basic WP Settings
Here is what I do in the dashboard:
1. Trash and permanently delete the Hello World Post.
2. Delete the default Links.
3. Set Permalinks to: /%category%/%postname%/
4. Under Settings General enter Blog Name and Tagline; for the purpose of this exercise I use as a Title: WordPress TTP and as a Tagline: Tips, Themes and Plugins
5. Add some content to test content display by importing an RSS feed using a plugin such as Feedwordpress. I pulled into a new category called Blog the feed from my author-blog at:
http://yorgonestoridis.com/feed
Custom Posts and Child Theme
We have set up a basic child theme for the purpose of modifying and customizing the Parent Theme. Creating structural modifications such as creating Custom Posts and Taxonomies are not strictly speaking theme relevant but should apply to all themes or as the case may be, to multiple themes in a Multi-user installation.
For this reason we will lodge the file which defines the custom posts outside any specific theme folder but inside wp-contents/themes.
We create a file called posttypes.php in wp-contents/themes. This file serves to define our custom post types and the way they integrate into the WP architecture.
In order to include the new Post Types in our Child theme, we include the posttype.php using an include function. This we doby adding a new file to our child theme; this file we call functions.php.
Child Theme functions.php
As you know, every WP theme contains a functions.php file; when creating a child theme which needs to expand the functions existing in the parent theme, then we just add a file with the same name, ‘functions.php’ to the child theme and append the functions defined in the parent theme.
Note: functions.php of the child theme does not override existing functions in the parent theme as is the case with styles (‘style.css)!
PHP allows us easily to include files in a script with the ‘include’ function and then by adding the URL to the file you wish to include.
Our ‘functions.php’ file will look as follows:
<?php
include_once (ABSPATH . 'wp-content/themes/posttypes.php');
?>
Please note that we use the ABSPATH function to construct the URL as the normal url path
url(".../themes/posttypes.php")
does not work here.
Save functions.php into your Child Theme Folder.
Define Post Types in posttypes.php
In order to set up our post types we proceed step by step:
- Set up Custom Post Types
- Add advanced Variables to Post Types
- Add advanced custom post type functionality
- Change the Menu Position (Dashboard) of the Custom Post Types
- Add custom post type icon
1. Custom Post Types
Custom Post Types allow to separate different content from the traditional blog content. Blog content usually is edited as Posts and Pages, whereas Pages (static content) can be organized in a hierarchical way and posts are sorted by categories and tags. In order to display static content (pages) using customized layout, we can create different page templates easily.
Custom Post Types allow to sort content by Posts and Custom Post Types whereas custom post types are similar to posts but using custom taxonomies and as the case may be custom layouts or design adapted to the content. A typical example is a single product page from a shop compared to a single post page on the blog section of the website.
For the purpose of our exercise we will create 3 Custom Post Types
- WordPress Tips
- WordPress Themes
- WordPress Plugins
Setting up post types is relatively easy; while we could use plugins to create custom post types, I think hard-coding is a more solid and professional way of creating them. To create a new Custom Post Type we just need to add a few lines of code to the functions file or in our case to the abstraction file at posttypes.php which will then be included int the functions.php as per above where we have added the include function into functions.php.
We will create now the 3 Custom Post Types whereas the code used for each of them is the same except for the post type names and the function names.
To create the first post type, edit posttypes.php and paste in:
<?php
// Add new post type for WP Tips
add_action('init', 'wordpress_tips_init');
function wordpress_tips_init()
{
$args = array(
'label' => _x('WP Tips'),
'singular_label' => _x('WP Tip'),
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => null,
'supports' => array('title','editor','comments')
);
register_post_type('wordpress_tips',$args);
}
Save the file.
At the top we type a comment explaining what the following code is all about (Add new Post Type for WP Tips). Then we call the function in to WordPress with ‘add_action’ and at the bottom we register the post type. As you can see the function consists of a number of arguments which we will look into later ($args).
Check out your Dashboard now and you will see that the new post type is added to the menu just above ‘Appearance’.
To add new post types, you just need to copy and paste the above code and make simple changes to the name and labels of the post type.
2. Add advanced Variables
The above post types work, however they are not well refined. For this reason we will add some more variables. As the new posts are still called “Post” in the editor for example we will need to relabel to display the real name of the post type. For this we will write a label variable which can take an array of labels and we thus relabel all instances of our Custom Post Type.
The variable we create with the array of labels looks as follows:
$wordpress_tips_labels = array(
'name' => _x('WP Tips', 'post type general name'),
'singular_name' => _x('WP Tip', 'post type singular name'),
'all_items' => __('All WP Tips'),
'add_new' => _x('Add new WP Tip', 'wordpress_tips'),
'add_new_item' => __('Add new WP Tip'),
'edit_item' => __('Edit WP Tip'),
'new_item' => __('New WP Tip'),
'view_item' => __('View WP Tip'),
'search_items' => __('Search in WP Tips'),
'not_found' => __('No WP Tips found'),
'not_found_in_trash' => __('No WP Tips found in trash'),
'parent_item_colon' => ''
);
We will insert this piece of code just before our block of arguments and then change the arguments accordingly as follows:
<?php
// Add new post type for WP Tips
add_action('init', 'wordpress_tips_init');
function wordpress_tips_init()
{
$wordpress_tips_labels = array(
'name' => _x('WP Tips', 'post type general name'),
'singular_name' => _x('WP Tip', 'post type singular name'),
'all_items' => __('All WP Tips'),
'add_new' => _x('Add new WP Tip', 'wordpress_tips'),
'add_new_item' => __('Add new WP Tip'),
'edit_item' => __('Edit WP Tip'),
'new_item' => __('New WP Tip'),
'view_item' => __('View WP Tip'),
'search_items' => __('Search in WP Tips'),
'not_found' => __('No WP Tips found'),
'not_found_in_trash' => __('No WP Tips found in trash'),
'parent_item_colon' => ''
);
$args = array(
/* 'label' => _x('WP Tips'), */
'labels' => $wordpress_tips_labels,
/* 'singular_label' => _x('WP Tips'), */
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => null,
'supports' => array('title','editor','comments')
);
register_post_type('wordpress_tips',$args);
}
As you can see from the two commented lines, we have changed ‘label’ to ‘labels and defined with the variable from above ‘$wordpress_tips_labels’ and we have deleted the ‘singular label’ as it is replaced wby ‘singular name’ from the label variable.
For the other new post types it’s the same game, just copy and paste and change the labels accordingly.
Save posttypes.php and check it out in your dashboard.
You will now see all labels added and your site becomes a lot more user-friendly and less confusing.
3. Add advanced functionality
We can define the functionalities of our new post types with an array under the variable ‘supports’; basically the ‘supports’ line defines which functionalities should be supported, i.e. which content should be displayed.
In our example, the line above looks like this:
'supports' => array('title','editor','comments')
When you go to your dashboard, and add a new WP Tip you will see the editor shows the ‘title’, ‘content’ and ‘comments’ fields.
While we can go crazy on adding supported functionality, we will here just look at some standard functionalities. To add more functionality we just need to append the array in the supports variable like so:
'supports' => array('title','editor','author','thumbnail','excerpt','comments','custom-fields'),
'has_archive' => 'wordpress_tips'
By adding the above functionalities to the supports variable, we get something pretty close to the standard post editor, since we add the author, excerpts and custom fields as well as the featured picture functionality.
Also we can add a new variable, such as ‘has archive’ and then name the archive, in our example ‘WordPress Tips’.
This archive variable allows us to create an index page just for the WP Tips post types.
Our Code for the WP Tips Custom Post Type is as follows:
<?php
// Add new post type for WP Tips
add_action('init', 'wordpress_tips_init');
function wordpress_tips_init()
{
$wordpress_tips_labels = array(
'name' => _x('WP Tips', 'post type general name'),
'singular_name' => _x('WP Tip', 'post type singular name'),
'all_items' => __('All WP Tips'),
'add_new' => _x('Add new WP Tip', 'wordpress_tips'),
'add_new_item' => __('Add new WP Tip'),
'edit_item' => __('Edit WP Tip'),
'new_item' => __('New WP Tip'),
'view_item' => __('View WP Tip'),
'search_items' => __('Search in WP Tips'),
'not_found' => __('No WP Tips found'),
'not_found_in_trash' => __('No WP Tips found in trash'),
'parent_item_colon' => ''
);
$args = array(
/* 'label' => _x('WP Tips'), */
'labels' => $wordpress_tips_labels,
/* 'singular_label' => _x('WP Tips'), */
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => null,
'supports' => array('title','editor','author','thumbnail','excerpt','comments','custom-fields'),
'has_archive' => 'wordpress_tips'
);
register_post_type('wordpress_tips',$args);
}
Copy and paste with the necessary changes for the other custom post types and save the file.
Check it out from the Dashboard Menu and the Editor.
As per now, our custom posts menu in the dashboard is positioned just above appearance and below comments. As custom posts are similar to posts, we want to move the custom post tabs just below the Posts tab.
As you can see from our code above, the menu position is set to ‘null’. The value ‘null’ makes that the custom post types are added at the bottom of the first section of the dashboard menu.
Depending of where you want to position your custom posts, you will need to change the value ‘null’ to another value according to the below reference scale:
0 — at the very top
5 — below Posts
10 — below Media
15 — below Links
20 — below Pages
25 — below comments
60 — below first separator
65 — below Plugins
70 — below Users
75 — below Tools
80 — below Settings
100 — below second separator
As we aim the spot below “Posts” we will use the value ‘5’, which will result in
...
'menu_position' => 5,
...
If you want to set a particular order, you can also use 3 different numbers, like 4,5 and 6 respectively.
Do the modification inside the arguments of each post type and save.
By repositioning the custom post type menu items , we signal priority and importance.
Check it out from the dashboard and note that our custom posts are right below ‘Posts’ now.
5. Add Custom Post Type Icons
In order to make our custom post types stick out from the menu and to add user-friendly visual identifiers, we replace the default icons with custom icons.
There are two sizes needed, 16px and 32 px for the menu and the page title area respectively.
I have created sample icons and psd files for your convenience: please download from HERE.
Decompress the downloaded rar file and copy the image folder into wp-contents/themes (as we had done with posttypes.php, as we want to make these images available to all themes.
To add these icons we introduce a new function to posttypes.php with a function batch including some css/html code for styling purposes:
// Add new Custom Post Type icons
add_action( 'admin_head', 'wordpress_icons' );
function wordpress_icons() {
?>
<style type="text/css" media="screen">
#menu-posts-wordpress_tips .wp-menu-image {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/tips-16x16.png) no-repeat 6px !important;
}
.icon32-posts-wordpress_tips {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/tips-32x32.png) no-repeat !important;
}
#menu-posts-wordpress_themes .wp-menu-image {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/themes-16x16.png) no-repeat 6px !important;
}
.icon32-posts-wordpress_themes {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/themes-32x32.png) no-repeat !important;
}
#menu-posts-wordpress_plugins .wp-menu-image {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/plugins-16x16.png) no-repeat 6px !important;
}
.icon32-posts-wordpress_plugins {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/plugins-32x32.png) no-repeat !important;
}
</style>
<?php }
Note the incomplete php delimiter at the end which is needed to switch back to php from css/html code.
Resulting posttypes.php code:
At this stage, your posttypes.php looks as follows:
<?php
// Add new post type for WP Tips
add_action('init', 'wordpress_tips_init');
function wordpress_tips_init()
{
$wordpress_tips_labels = array(
'name' => _x('WP Tips', 'post type general name'),
'singular_name' => _x('WP Tip', 'post type singular name'),
'all_items' => __('All WP Tips'),
'add_new' => _x('Add new WP Tip', 'wordpress_tips'),
'add_new_item' => __('Add new WP Tip'),
'edit_item' => __('Edit WP Tip'),
'new_item' => __('New WP Tip'),
'view_item' => __('View WP Tip'),
'search_items' => __('Search in WP Tips'),
'not_found' => __('No WP Tips found'),
'not_found_in_trash' => __('No WP Tips found in trash'),
'parent_item_colon' => ''
);
$args = array(
/* 'label' => _x('WP Tips'), */
'labels' => $wordpress_tips_labels,
/* 'singular_label' => _x('WP Tips'), */
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => 5,
'supports' => array('title','editor','author','thumbnail','excerpt','comments','custom-fields'),
'has_archive' => 'wordpress_tips'
);
register_post_type('wordpress_tips',$args);
}
// Add new post type for WP Themes
add_action('init', 'wordpress_themes_init');
function wordpress_themes_init()
{
$wordpress_themes_labels = array(
'name' => _x('WP Themes', 'post type general name'),
'singular_name' => _x('WP Theme', 'post type singular name'),
'all_items' => __('All WP Themes'),
'add_new' => _x('Add new WP Theme', 'wordpress_themes'),
'add_new_item' => __('Add new WP Theme'),
'edit_item' => __('Edit WP Theme'),
'new_item' => __('New WP Theme'),
'view_item' => __('View WP Theme'),
'search_items' => __('Search in WP Themes'),
'not_found' => __('No WP Theme found'),
'not_found_in_trash' => __('No WP Theme found in trash'),
'parent_item_colon' => ''
);
$args = array(
'labels' => $wordpress_themes_labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => 5,
'supports' => array('title','editor','author','thumbnail','excerpt','comments','custom-fields'),
'has_archive' => 'wordpress_themes'
);
register_post_type('wordpress_themes',$args);
}
// Add new post type for WP Plugins
add_action('init', 'wordpress_plugins_init');
function wordpress_plugins_init()
{
$wordpress_plugins_labels = array(
'name' => _x('WP Plugins', 'post type general name'),
'singular_name' => _x('WP Plugin', 'post type singular name'),
'all_items' => __('All WP Plugins'),
'add_new' => _x('Add new WP Plugin', 'wordpress_plugins'),
'add_new_item' => __('Add new WP Plugin'),
'edit_item' => __('Edit WP Plugin'),
'new_item' => __('New WP Plugin'),
'view_item' => __('View WP Plugin'),
'search_items' => __('Search in WP Plugins'),
'not_found' => __('No WP Plugin found'),
'not_found_in_trash' => __('No WP Plugin found in trash'),
'parent_item_colon' => ''
);
$args = array(
'labels' => $wordpress_plugins_labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => 5,
'supports' => array('title','editor','author','thumbnail','excerpt','comments','custom-fields'),
'has_archive' => 'wordpress_plugins'
);
register_post_type('wordpress_plugins',$args);
}
// Add new Custom Post Type icons
add_action( 'admin_head', 'wordpress_icons' );
function wordpress_icons() {
?>
<style type="text/css" media="screen">
#menu-posts-wordpress_tips .wp-menu-image {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/tips-16x16.png) no-repeat 6px !important;
}
.icon32-posts-wordpress_tips {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/tips-32x32.png) no-repeat !important;
}
#menu-posts-wordpress_themes .wp-menu-image {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/themes-16x16.png) no-repeat 6px !important;
}
.icon32-posts-wordpress_themes {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/themes-32x32.png) no-repeat !important;
}
#menu-posts-wordpress_plugins .wp-menu-image {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/plugins-16x16.png) no-repeat 6px !important;
}
.icon32-posts-wordpress_plugins {
background: url(<?php bloginfo('url') ?>/wp-content/themes/images/plugins-32x32.png) no-repeat !important;
}
</style>
<?php }
?>
Check it out from your dashboard and you should see something similar to this:
Custom Post Types with Custom Icons
Related posts:
- How to build a Custom WordPress Site 2
- How to build a custom WordPress Site
- Custom Widgets for WordPress
- WordPress 3.4 Beta
- Facebook Strategy with WordPress