Custom Post Types

Creating a Custom Post Type

To create a custom post type, you need to extend the  hji\common\postType\CustomPostType core class. This class is simply a data transfer object (DTO) that only contains public properties and no business logic (methods). This allows us to have a clear definition of a custom post type and separate the logic if its consumption by the application, which provides great flexibility and maintainability for our core codebase.

 namepace hji\myplugin\models;

 use hji\common\postType\CustomPostType;

 class MyPostType extends CustomPostType
 {
    public $post_type = 'my-post-type';
 }The only required parameter in the CustomPostType is  <code>$post_type

. For the full list of supported parameters see  hji\common\postType\CustomPostType class definition.

Registering Custom Post Type

Since your post type is just a DTO object, it needs to be processed by something else and registered with WordPress. All these things are done behind the scenes via  PluginAPI::registerPostTypes(), which is available to you via api()method in your core application file.

Here's how to register your custom post type within the  hji\myplugin\App class:

function ini()
{
    $this->registerPostTypes();
}


function registerPostTypes()
{
    $this->api()->registerPostTypes([models\MyPostType::class]);
}

Note that  PluginAPI::registerPostType() accepts array of strings, where each string is a fully qualified namespace for your custom post type class. This means that you don't need to instantiate your post type class within your code base. Instead, it will be instantiated and automatically consumed by Membership.

Adding Custom Fields (Meta Boxes)

The construction of meta fields within Membership is currently handled by the CMB2 library. The connection between the custom post type definition and CMB2 is obfuscated by PluginAPI, so you don't really have to deal with the CMB2 directly.

To define your custom meta boxes (with the meta fields), simply assign your schema to the  CustomPostType::$fieldsSchema property.

Example:

namepace hji\myplugin\models;

use hji\common\postType\CustomPostType;

class MyPostType extends CustomPostType
{
    public $post_type = 'my-post-type';

    public $fieldsSchema = [
        [
            'id'        => 'test_metabox',
            'title'     => 'Test Metabox',
            'context'   => 'normal',
            'priority'  => 'high',
            'show_names'=> true,
            'fields     => [
                [
                    'id'    => 'first_name',
                    'name'  => 'First Name',
                    'type'  => 'text'
                ],
                [
                    'id'    => 'last_name',
                    'name'  => 'Last Name',
                    'type'  => 'text'
                ],
            ]
        ]
    ];
}

For complete schema structure refer to the CMB2: Create a Metabox documentation.

All field ID's are automatically prefixed with MyPostType::$fieldPrefix (default "_hj_") during field registration process. Therefore, if you directly get/add/update post meta, you have to prefix your field id accordingly.
function getFirstName()
{
    return get_post_meta($this->postId, $this->myPostType->fieldPrefx . 'first_name', true);
}

Adding Taxonomies

Adding taxonomies is as simple as assigning an array of supported properties (see register_taxonomies() arguments section) to the CustomPostType::$taxonomiesSchema.

Example:

namepace hji\myplugin\models;

use hji\common\postType\CustomPostType;


class MyPostType extends CustomPostType
{
    public $post_type = 'my-post-type';

    public $taxonomiesSchema = [
        'listing_status' => [
            'rewrite' => [
                'slug'  => 'status'
            ],
            'labels'    => [
                'name'  => 'Listing Status'
            ]
        ]
    ];
}

Admin Columns (Admin Posts Table)

Example: Pocket Listings custom post type

You can define your custom admin columns by assigning an array of properties to the  CustomPostType::$adminColsSchema.

Example:

namepace hji\myplugin\models;

use hji\common\postType\CustomPostType;


class MyPostType extends CustomPostType
{
    public $post_type = 'my-post-type';

    public $adminColsSchema = [
        'featured_image' => [
          'title'          => 'Thumbnail',
          'featured_image' => 'thumbnail',
          'width'          => 100,
          'height'         => 100,
        ],
        'title' => [
          'post_field' => 'title'
        ],
        'agent_tags' => [
          'title'    => 'Agent Tags',
          'taxonomy' => 'agent_tags',
          'link'     => 'view'
        ],
        'email' => [
          'title' => 'Agent Email',
          'field' => 'email',
        ],
        'date',
    ];
}

For the complete list of supported parameters of the admin columns schema, refer to  hji\common\postType\CustomPostType inline documentation.

Admin Filters (Admin Post Table Filters)

Just as Admin Columns, we can define custom filters to filter our custom posts.

Example: Filter testimonials by agent

You can define your custom admin filters by assigning array of properties to the  CustomPostType::$adminFiltersSchema.

Example:

namepace hji\myplugin\models;

use hji\common\postType\CustomPostType;


class MyPostType extends CustomPostType
{
    public $post_type = 'my-post-type';
    public $adminFiltersSchema = []; 
    protected $agents;


    public function __contruct(AgentsModel $agents)
    {
        $this->agents               = $agents;
        $this->adminFiltersSchema   = $this->adminFilters();
    }


    protected function adminFilters()
    {
        return [
            'agent_id' => [
                'title' => 'Agent',
                'meta_key' => 'agent_id',
                'options' => [$this->agents, 'getAgentsList']
            ]
        ];
    }
}

In the example above we're mixing some logic into our DTO class, but it's ok as long as all methods are private (or protected) and their sole purpose is to construct the properties of the object. This way we're not really adding any business logic, because it's not used anywhere else. In other words, we should never use  MyPostType instance anywhere in our code like this MyPostType::doSomething(). The real value of MyPostType should be simply translated into an array of properties i.e. $postTypeProperties = get_object_vars(new MyPostType());.

Still need help? Contact Us Contact Us