Creating a Meta Box for a Custom Post Type
With a combination of a custom post type and post meta boxes with custom fields, we can create a powerful plugin by making each post an options container. In this tutorial, we create a very small plugin that lets the user pick an own color in a post definition page of the admin area and displays it in the front end.
Steps
- Include the library
- Define a Custom Post Type
- Define Custom Columns of Post Listing Table
- Define the Cell Output of Custom Columns
- Define the CSS Rules of Post Listing Page
- Define the Front-end Article Output
- Add a Meta Box and Custom Field
- Instantiate the extended classes
Screenshot
Include the library
The library (framework) file needs to be loaded. Change the library path as you need.
13 |
include( dirname( dirname( __FILE__ ) ) . '/library/apf/admin-page-framework.php' ); |
Define a Custom Post Type
We are going to declare two classes, one for a post type and the other for a meta box. We’ve covered how to register a post type and meta box already in in the previous tutorials (Add a Meta Box for Posts, Create a Custom Post Type and Custom Taxonomy). If you haven’t done them and are not cretin how, it is recommended checking them out.
Here, we use APF_Tutorial_PostType for a class name as an example, extend the AdminPageFramework_PostType factory class, and set the post type argument to the setArguments() method in the setUp() method.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
class APF_Tutorial_PostType extends AdminPageFramework_PostType { /** * Sets up necessary settings. */ public function setUp() { $this->setArguments( array( // argument - for the array structure, refer to http://codex.wordpress.org/Function_Reference/register_post_type#Arguments 'labels' => array( 'name' => __( 'Colors', 'admin-page-framework-turorial' ), 'add_new_item' => __( 'Add Color', 'admin-page-framework-tutorial' ), ), 'supports' => array( 'title' ), // e.g. array( 'title', 'editor', 'comments', 'thumbnail', 'excerpt' ), 'public' => true, 'menu_icon' => version_compare( $GLOBALS['wp_version'], '3.8', '>=' ) ? 'dashicons-welcome-learn-more' : 'https://lh4.googleusercontent.com/-z7ydw-aPWGc/UwpeB96m5eI/AAAAAAAABjs/Brz6edaUB58/s800/demo04_16x16.png', // (framework specific key) this sets the screen icon for the post type for WordPress v3.7.1 or below. 'screen_icon' => dirname( APFDEMO_FILE ) . '/asset/image/wp-logo_32x32.png', // a file path can be passed instead of a url, plugins_url( 'asset/image/wp-logo_32x32.png', APFDEMO_FILE ) ) ); } |
We are going to add more code in this class.
Define Custom Columns of Post Listing Table
Next, for the post listing table in the admin area of the post type page (edit.php), we define what columns are displayed in the table. Since we are just getting started and don’t want it to be complicated, let’s just have only three columns: checkbox, title, and a custom column named “Color.” The Color column will display a custom field value embedded by a meta box we are going to add later.
To define columns, we can use the predefined callback method that the framework provides whose name is made up of “columns_” + “{post type slug}”. It receives an array holding the column slugs in the keys and the HTML output values in the values. Like other pre-defined callback methods, this method gets automatically called when the page tries to define and display the post listing table.
46 47 48 49 50 51 52 53 54 55 56 |
public function columns_apf_tutorial_posts( $aHeaderColumns ) { return array( 'cb' => '<input type="checkbox" />', // Checkbox for bulk actions. 'title' => __( 'Title', 'admin-page-framework' ), // Post title. Includes "edit", "quick edit", "trash" and "view" links. If $mode (set from $_REQUEST['mode']) is 'excerpt', a post excerpt is included between the title and links. 'color' => __( 'Color', 'admin-page-framework-tutorial' ), ) // + $aHeaderColumns // uncomment this to enable the default columns. ; } |
If you need to enable the default columns, just uncomment the line + $aHeaderColumns, which will unite the arrays so that the passed default columns array will be merged.
Define the Cell Output of Custom Columns
While the post listing table processes rendering each row and its column, the framework receives a callback for custom columns. The callback method name is made up of ”cell_” + “{post type slug}” + _ + “{column key}”. The column key is the one you set in the custom column array in the columns_{post type slug}() method.
So to display the output of the cell of the custom column, we use the method name, cell_apf_tutorial_posts_color().
The method receives the following two parameters.
- (string) the HTML cell output.
- (integer) the parsing post ID.
So let’s add the following code. It uses the get_post_meta() WordPress core function and the key ‘my_custom_color’ is passed. The meta key is the one we are going to set in the meta box class later in this tutorial. And the method displays an HTML container element with the background color of that value.
62 63 64 65 66 67 68 69 70 71 72 |
public function cell_apf_tutorial_posts_color( $sCell, $iPostID ) { // cell_{post type}_{column key} $_sColor = get_post_meta( $iPostID, 'my_custom_color', true ); $_sColor = $_sColor ? $_sColor : 'transparent'; return $sCell . '<div class="color-sample-container">' . '<p style="background-color: ' . esc_attr( $_sColor ) . '">' . '</p>' . '</div>'; } |
Define the CSS Rules of Post Listing Page
We can define CSS rules for that post listing page. There are different ways to do that but here we modify the inline CSS rules that the framework inserts. For that, we use a method named “style_{instantiated class name}()”.
There is only one parameter for the method.
- (string) the inline CSS rules.
79 80 81 82 83 84 85 86 87 88 89 90 91 |
public function style_APF_Tutorial_PostType( $sStyle ) { return $sStyle . " .color-sample-container { height: 3em; } .color-sample-container p { border: solid 1px #CCC; width: 3em; height: 100%; } "; } |
Define the Front-end Article Output
When the user clicks the View link in the title cell of the post listing table, a page opens in the front-end and it is supposed to display the contents of the post. And we are going to display the output based on the custom field value set by the meta box field which we are going to add later.
For that, we can use the content() method which is automatically called when an article page of the post type of the class is rendered. Alternatively, content_{instantiated class name}() method can be used.
They receive the following parameter.
- (string) the HTML content output of the post.
Here is an example. It retrieves a custom field value with get_post_meta() method and the key “my_custom_color” is set. The key is the one we are going to use for a meta box field. So it means, “give me a value of the custom field ‘my_custom_color’ associated with the displaying post.” and the value is assigned to the $_sSelectedColor variable. The method then returns an HTML box with the background color of that set value.
100 101 102 103 104 105 106 107 108 109 110 |
public function content( $sContent ) { $_sSelectedColor = get_post_meta( $GLOBALS['post']->ID, 'my_custom_color', true ); $_sSelectedColor = $_sSelectedColor ? $_sSelectedColor : 'transparent'; return "<h3>" . __( 'Selected Color', 'admin-page-framework-tutorial' ) . "</h3>" . "<div style='width: 100%;'>" . "<div style='margin:auto; width: 3em; height: 3em; background-color:" . $_sSelectedColor . "'></div>" . "</div>" ; } |
Add a Meta Box and Custom Field
As we added blocks of code that retrieve meta data with the key named “my_custom_color,” we need to add a custom field with that key name. It can be achieved with a meta box. Define a meta box extending the AdminPageFramework_MetaBox factory class.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
public function setUp() { /** * Adds setting fields in the meta box. */ $this->addSettingFields( array( 'field_id' => 'my_custom_color', 'type' => 'color', 'title' => __( 'Color', 'admin-page-framework-tutorial' ), ) ); } |
Instantiate the extended classes
Finally, we instantiate the classes.
136 137 138 139 140 141 142 143 144 |
new APF_Tutorial_PostType( 'apf_tutorial_posts' ); // the post type slug new APF_Tutorial_CustomPostTypeMetaBox( null, // meta box ID - can be null. __( 'Tutorial - Add a Meta Box to Custom Post Type', 'admin-page-framework-demo' ), // title array( 'apf_tutorial_posts' ), // post type slugs: post, page, etc. 'normal', // context 'low' // priority ); |
Conclusion
In this tutorial, we added only one custom field because the instruction should be kept as simple as possible. However, you can add your own fields as you need. Imagine you add a field that sets a pixel size and another color field. Then you can provide your users with options for a border width and the border color in addition to the background color.
The field can be for a url to perform an API request to display fetched data from an external site. The potential is immeasurable.
Code
Try the code below and post comments if you get a problem.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
<?php /** * Plugin Name: Admin Page Framework Tutorial 13 - Add a Meta Box to a Custom Post Type * Plugin URI: http://en.michaeluno.jp/admin-page-framework * Description: Adds a meta box to custom post type created by the framework and display the set custom field value. * Author: Michael Uno * Author URI: http://michaeluno.jp * Version: 1.0.0 * Requirements: PHP 5.2.4 or above, WordPress 3.4 or above. Admin Page Framework 3.0.6 or above */ // Include the library file. Set your file path here. include( dirname( dirname( __FILE__ ) ) . '/library/apf/admin-page-framework.php' ); class APF_Tutorial_PostType extends AdminPageFramework_PostType { /** * Sets up necessary settings. */ public function setUp() { $this->setArguments( array( // argument - for the array structure, refer to http://codex.wordpress.org/Function_Reference/register_post_type#Arguments 'labels' => array( 'name' => __( 'Colors', 'admin-page-framework-turorial' ), 'add_new_item' => __( 'Add Color', 'admin-page-framework-tutorial' ), ), 'supports' => array( 'title' ), // e.g. array( 'title', 'editor', 'comments', 'thumbnail', 'excerpt' ), 'public' => true, 'menu_icon' => version_compare( $GLOBALS['wp_version'], '3.8', '>=' ) ? 'dashicons-welcome-learn-more' : 'https://lh4.googleusercontent.com/-z7ydw-aPWGc/UwpeB96m5eI/AAAAAAAABjs/Brz6edaUB58/s800/demo04_16x16.png', // (framework specific key) this sets the screen icon for the post type for WordPress v3.7.1 or below. 'screen_icon' => dirname( APFDEMO_FILE ) . '/asset/image/wp-logo_32x32.png', // a file path can be passed instead of a url, plugins_url( 'asset/image/wp-logo_32x32.png', APFDEMO_FILE ) ) ); } /* * Modifies the columns of post listing table. * * @remark columns_{post type slug} * @return array */ public function columns_apf_tutorial_posts( $aHeaderColumns ) { return array( 'cb' => '<input type="checkbox" />', // Checkbox for bulk actions. 'title' => __( 'Title', 'admin-page-framework' ), // Post title. Includes "edit", "quick edit", "trash" and "view" links. If $mode (set from $_REQUEST['mode']) is 'excerpt', a post excerpt is included between the title and links. 'color' => __( 'Color', 'admin-page-framework-tutorial' ), ) // + $aHeaderColumns // uncomment this to enable the default columns. ; } /** * Modifies the 'color' column cell contents of the post listing table * @return string */ public function cell_apf_tutorial_posts_color( $sCell, $iPostID ) { // cell_{post type}_{column key} $_sColor = get_post_meta( $iPostID, 'my_custom_color', true ); $_sColor = $_sColor ? $_sColor : 'transparent'; return $sCell . '<div class="color-sample-container">' . '<p style="background-color: ' . esc_attr( $_sColor ) . '">' . '</p>' . '</div>'; } /** * Modifies the CSS rules of the admin page of the post listing table of the post type of this class. * @callback filter style_{instantiated class name} * @return string */ public function style_APF_Tutorial_PostType( $sStyle ) { return $sStyle . " .color-sample-container { height: 3em; } .color-sample-container p { border: solid 1px #CCC; width: 3em; height: 100%; } "; } /** * Modifies the output of the post content. * * This method is called in the single page of this class post type. * * Alternatively, you may use the 'content_{instantiated class name}' method, */ public function content( $sContent ) { $_sSelectedColor = get_post_meta( $GLOBALS['post']->ID, 'my_custom_color', true ); $_sSelectedColor = $_sSelectedColor ? $_sSelectedColor : 'transparent'; return "<h3>" . __( 'Selected Color', 'admin-page-framework-tutorial' ) . "</h3>" . "<div style='width: 100%;'>" . "<div style='margin:auto; width: 3em; height: 3em; background-color:" . $_sSelectedColor . "'></div>" . "</div>" ; } } class APF_Tutorial_CustomPostTypeMetaBox extends AdminPageFramework_MetaBox { /* * Use the setUp() method to define settings of this meta box. */ public function setUp() { /** * Adds setting fields in the meta box. */ $this->addSettingFields( array( 'field_id' => 'my_custom_color', 'type' => 'color', 'title' => __( 'Color', 'admin-page-framework-tutorial' ), ) ); } } new APF_Tutorial_PostType( 'apf_tutorial_posts' ); // the post type slug new APF_Tutorial_CustomPostTypeMetaBox( null, // meta box ID - can be null. __( 'Tutorial - Add a Meta Box to Custom Post Type', 'admin-page-framework-demo' ), // title array( 'apf_tutorial_posts' ), // post type slugs: post, page, etc. 'normal', // context 'low' // priority ); |
Hello,
First of all, thank you for this amazing framework.
I’m trying to put a METABOX in several pages of taxonomies and not achieving results.
How could insert a METABOX in various taxonomies?
An array of this type for the purpose would be worth in the declaration of the class?
Best regards and thanks in advance for your help
Hi,
The framework does not have the functionality to add meta boxes in
edit-tags.php
. However, you can add custom fields to the taxonomy definition form. You may check the example code in “…admin-page-framework/example/post_type/taxonomy/APF_TaxonomyField.php”. The code that instantiates the class is in “…admin-page-framework/include/class/admin/demo/AdminPageFrameworkLoader_Demo_Taxonomy.php”.Hi,
Thank you very much for your interest in helping me with my doubts Michel 🙂
It is not clear how to instantiate the class, and this created taxonomy is a taxonomy of WooCommerce. “attributes -> tag”.
I try to instantiate the calse this way, but I get no results:
best regards
Sorry Michel,
The code is working fine, thank you very much for your help.
Best regards and thank you very much for your time.
You are welcome! Glad to hear that. It would be appreciated if you could take a few minutes to write a comment on the plugin.