Samples Create Custom Post Type - Page-Carbajal/WPExpress GitHub Wiki

##Create a WordPress Custom Post Type with WPExpress

Before we begin. Lets talk about what is a Custom Post Types, why WordPress allows for these and what you need to create a Custom Post Type.

A Custom Post Type is a customized Data Type defined within WordPress to manage more specific information. The need comes to be after the inclussion of Custom Fields for Posts, which were very useful and also quickly became a real pain to use.

WordPress provides you with 3 basic components for a Custom Post Type

  • Title
  • Content and
  • Featured Image

If you need extra information –Like fields for a the ISBN and Price of a Book–, you need to indicate this to WordPress.

Now imagine you have more than 10 extra fields and some of them are not related between them. They you need to manage to arrange this Data in sets that make sense.

Enter MetaBoxes. A MetaBox in WordPress is a Box for Custom Fields –Within the DB they're called meta fields an stored in a table called wp_postmeta–. You use this boxes to manage the Data Sets of your Custom Post Type, to design its information architecture. Also to set permissions for users and other goodies.

In this section, you are going to learn how to use WPExpress to build the following:

  1. A Basic Custom Post Type with just Title, Content and Featured Image for fields.
  2. A Custom Post Type with your own set of Custom Fields
  3. How to group your Custom Fields in MetaBoxes

###1. Create a Basic Custom Post Type

To create a Custom Post Type in WordPress with WPExpress we need to create a class to Extend Model\BaseModel.

BaseModel is our base class. It contains methods that will make you love working with your custom post type objects.

####Custom Post Type Declaration

<?php

namespace SomeProject\Model;

use WPExpress\Model\BaseModel;

class Book extends BaseModel
{

}

Congratulations that is essentially the only code you need to create a Custom Post Type. Now, to be able to use it. You need to call the constructor at least one time when your theme or plugin starts.

To do this, just declare a filter like this one inside your functions.php file, or anywhere you see fit.

function myCustomPostTypeRegistrationFunction()
{
    new SomeProject\Model\Book();
}
add_action( 'after_setup_theme', 'myCustomPostTypeRegistrationFunction' );

Remember to include the path to the class if you are not using composer.

###2. Create a Custom Post Type with Custom Fields

So far we have managed to create a new Custom Post Type but we need extra information for our Book. Information like ISBN, Price, Rating, Publication Year, Edition and so forth.

ISBNs are unique. There cannot be two or more books with the same ISBN. So we decide to make this a unique meta field.

Authors are attention divas, and to keep up with their need-for-attention they tend to write more than one book. So instead of using a field, we will be using a Taxonomy for the Author.

The rest of the information will meta values as well.

<?php 

namespace MyPlugin\Model;

use WPExpress\Model\BaseModel;

class Book extends BaseModel
{
    public function __construct( $bean = null )
    {
        parent::__construct($bean);

        $this->registerCustomFields();
    }

    private function registerCustomFields()
    {
        $this->fields->addTextInput('ISBN')
            ->addTextInput('Price')
            ->addTextInput('Rating')
            ->addTextInput('Edition')
            ->addTextInput('Publisher')
            ->addTextInput('PublicationYear');
    }
}

That's it. You need no more configuration.

WPExpress - Default Metabox

When you run this code, you will find that all the fields have been added to a MetaBox with the title Properties for Book.

If not defined. A meta box will be created for you to accommodate all of your custom fields.

###3. Group your Custom Fields with MetaBoxes

Ok. You already have a Custom Post Type with Custom Fields, but that's not enough for you, is it?.

No you want the freedom to build your own information architecture. At least I assume you would. So, lets dive in.

namespace MyPlugin\Model;


use WPExpress\Model\BaseModel;


class Book extends BaseModel
{

    public function __construct( $bean = null )
    {
        parent::__construct($bean);

        $this->registerCustomFields();
    }

    private function registerCustomFields()
    {
        $this->fields->addTextInput('ISBN')->addLabel('#ISBN')
            ->addTextInput('Price')
            ->addTextInput('Rating')
            ->addTextInput('Link')
            ->addTextInput('Edition')
            ->addTextInput('Publisher')
            ->addTextInput('Publication Year');

        $this->metaBoxes->add('Marketing Data')->setFields(array( 'Price', 'Rating', 'Link' ));

        $this->metaBoxes->add('Editorial Information')->setFields(array( 'ISBN', 'Edition', 'Publisher', 'Publication Year'))->disableAjaxUpdate();
    }

}

Just as the FieldCollection, BaseModel also features a handful MetaBoxCollection instantiated through the property metaBoxes.

There's no limit to the number of meta boxes you can create. Although, it is your responsibility to indicate the order of the fields.

The MetaBoxCollection and FieldCollection are very basic dictionaries used to give you an easy way to define the architecture information.

This is how your Custom Meta boxes look

WPExpress - custom metaboxes

##Observations

All data saving and loading is handled by the BaseModel class. If you need to know because, well you want to, here is how it works.

###Data Loading

All fields are stored as an array in a single meta field linked to your post. The meta_key for the wp_postmeta table is __wex_fields.

If you locate the renderFields method on BaseModel class. You will see a method call to loadFieldValues. This protected method will execute get_post_meta and load your fields with the correct data.

###Data Saving

WPExpress 1.3.0 can only save data on post. Further releases will implement Asynchronous methods for saving data.

When you click update or save on the WordPress edit screen we hook the BaseModel method saveFieldValues to the filter save_post.

What happens next is quite simple, we look for the fields, get the values and store such values on the DB.

If you have any more questions drop me a line at twitter