-
Notifications
You must be signed in to change notification settings - Fork 10
Component Post_Type
Post_Type base class is used to make registration of post types more easy and more intuitive. It has a lot of constants defined to help IDE to suggest you available options and not to guess/google them.
Post_Type base class is defined in Objects\Post_Type.php
class.
You can say, that there are a lot of plugins, which has admin interface to register a post type. -Yes, it's true. But let's check a bit deeper what we get with an additional plugin.
Each plugin with admin interface usually include a lot of code during the page load. To register a new post type it needs to check options from the database, parse them (unserialize) and only then it calls a registration function. Furthermore, good plugins has a lot of hooks inside, which added to make this plugin more flexible. And all this staff adds some time in your page load time. Good, optimized WordPress site has more than 10 3rd-party plugins. WordPress is not the fastest CMS in the world and you want to slow it down with one more plugin, because you're too lazy to write 20-30 lines of code?
Even if you use a plugin - all of them just repeat standard WordPress options and do not optimize anything in WordPress post types registration process.
We think registering post types inside the code for your theme is the only correct way of the development of
a high-quality theme. That's why we prepared a base class to register a post type very fast and optimize
some non-trivial options of WordPress register_post_type()
function.
To create a new post type you need to create your own class and extends it from JustCoded\WP\Framework\Objects\Post_Type
.
Inside init()
method you should define Post_Type correct settings (with class properties) and call
$this->register()
at the end of the init()
.
Example:
<?php
namespace Boilerplate\Theme\Post_Type;
use JustCoded\WP\Framework\Objects\Post_Type;
class Employee extends Post_Type {
/**
* ID
*
* @var string
*/
public static $ID = 'employee';
/**
* Rewrite URL part
*
* @var string
*/
public static $SLUG = 'employee';
/**
* Registration function
*/
public function init() {
$this->label_singular = 'Employee';
$this->label_multiple = 'Employees';
$this->textdomain = 'boilerplate';
$this->has_single = true;
$this->is_searchable = true;
$this->rewrite_singular = false;
$this->is_hierarchical = false;
$this->admin_menu_pos = 25;
$this->admin_menu_icon = 'dashicons-format-gallery';
$this->taxonomies = array(
'category',
);
// IT'S IMPORTANT TO CALL THIS METHOD, BECAUSE IT CALLS register_post_type() inside!
$this->register();
}
}
Most of the class properties duplicates configuration data you can pass to WordPress register_post_type()
function. However there are few properties which makes easier to set correct values for some non-trivial
options.
By default when you created a new class - it's not included anywhere inside the code and post type won't be added.
To do this - you need to create a new instance of your new class. This class implements Singleton design
pattern, so creating an instance is available only through static instance()
method.
If you use Theme class to register your theme features, then the code will be like this:
/**
* Register post types
*/
public function register_post_types() {
Employee::instance();
}
A lot of mistakes in registering of the post types is usually made around such arguments:
public
publicly_queryable
show_in_nav_menus
exclude_from_search
has_archive
rewrite.with_front
Argument names are not very intuitive and understandable, without reading the documentation. We decide to make arguments much more intuitive. So we added logical properties, which are converted to the values for options above:
-
$has_single
- means you have a singular template for your post type. -
$has_archive
- means you have a separate archive template for your post type. -
$is_searchable
- do you want this post type appears in a search results? -
$rewrite_singular
- make rewrite structure "singular" (do not include post type "slug" prefix). -
$redirect
- ability to redirect singular to another page (for example you want your post type to appears in the search results, but it doesn't have a singular template and you want to automatically redirect to an archive page).
Another group of non-intuitive options is:
show_ui
show_in_menu
Which is replaced with such property:
-
$has_admin_menu
- set correct values forshow_ui
andshow_in_menu
.
Final arguments for register_post_types
are generated with such peace of code:
<?php
...
$labels = array(
'name' => _x( $this->label_multiple, 'post type general name', $this->textdomain ),
'singular_name' => _x( $this->label_singular, 'post type singular name', $this->textdomain ),
'menu_name' => _x( $this->label_multiple, 'admin menu', $this->textdomain ),
'add_new' => _x( 'Add New', $this->label_singular, $this->textdomain ),
);
$labels = array_merge( $labels, $this->labels );
$args = array(
'labels' => $labels,
'hierarchical' => $this->is_hierarchical,
'public' => $this->has_single,
'publicly_queryable' => $this->has_single || $this->is_searchable || $this->redirect,
'show_in_nav_menus' => $this->has_single,
'exclude_from_search' => ! $this->is_searchable,
'has_archive' => $this->has_archive,
'show_ui' => ! empty( $this->has_admin_menu ),
'show_in_menu' => $this->has_admin_menu,
'menu_position' => $this->admin_menu_pos,
'menu_icon' => $this->admin_menu_icon,
'capability_type' => $this->admin_capability,
'supports' => $this->supports,
'rewrite' => array(
'slug' => $this::$SLUG,
'with_front' => ( ! $this->rewrite_singular || $this->redirect ),
),
'query_var' => $this->query_var,
);
if ( ! empty( $this->taxonomies ) && is_array( $this->taxonomies ) ) {
$args['taxonomies'] = $this->taxonomies;
}
if ( ! empty( $this->capabilities ) ) {
$args['capabilities'] = $this->capabilities;
}
Property | Type | Default | Description |
---|---|---|---|
static $ID | string | - | Post_Type ID |
static $SLUG | string | - | Post_Type rewrite prefix, called slug |
$label_singular | string | - | Single Post Type label. |
$label_multiple | string | - | Multiple Post Type label. |
$has_single | bool | false | Has single page or not. |
$is_searchable | bool | false | Should appear in search results or not. |
$is_hierarchical | bool | false | Ability to set Parent. |
$redirect | bool|string | false | Specify where to redirect singular post type page. |
$rewrite_singular | bool | false | Simplify URLs structure and remove "slug" prefix from URL. |
$has_admin_menu | bool | true | Show in admin menu. |
$admin_menu_pos | int | 25 | Admin menu vertical position priority. |
$admin_menu_icon | string | null | Admin menu icon. |
$supports | array | * | Array of supported standard features of CPT. *Adds title, editor, featured image and revisions by default. |
$taxonomies | array | null | Taxonomy IDs to add to this CPT, should be used only for standard Category and Tags.. |
$has_archive | bool | false | Enable global archive page for CPT. We don't use it in Boilerplate. |
$labels | array | [] | Labels array to override auto-generated labels if needed. |
$admin_capability | string | 'post' | Main capability level. |
$capabilities | array | null | Custom capability options. |
$query_var | bool | true | Custom query var to be applied for single pages. |
$textdomain | string | - | Textdomain to apply to labels on post type registration. |
There are a lot of constants to help you specify different option values or use them inside Models to be sure you don't misspell some parameter:
const STATUS_ANY = 'any';
const STATUS_DRAFT = 'draft';
const STATUS_PENDING = 'pending';
const STATUS_PUBLISH = 'publish';
const STATUS_FUTURE = 'future';
const STATUS_AUTO_DRAFT = 'auto-draft';
const STATUS_PRIVATE = 'private';
const STATUS_INHERIT = 'inherit';
const SORT_ASC = 'asc';
const SORT_DESC = 'desc';
const ORDERBY_NONE = 'none';
const ORDERBY_ID = 'ID';
const ORDERBY_AUTHOR = 'author';
const ORDERBY_TITLE = 'title';
const ORDERBY_SLUG = 'name';
const ORDERBY_TYPE = 'type';
const ORDERBY_DATE = 'date';
const ORDERBY_MODIFIED = 'modified';
const ORDERBY_PARENT = 'parent';
const ORDERBY_RAND = 'rand';
const ORDERBY_COMMENTS = 'comment_count';
const ORDERBY_WEIGHT = 'menu_order';
const ORDERBY_META = 'meta_value';
const ORDERBY_META_NUMERIC = 'meta_value_num';
const ORDERBY_POST_IN = 'post__in';
const SUPPORTS_TITLE = 'title';
const SUPPORTS_EDITOR = 'editor';
const SUPPORTS_AUTHOR = 'author';
const SUPPORTS_FEATURED_IMAGE = 'thumbnail';
const SUPPORTS_EXCERPT = 'excerpt';
const SUPPORTS_TRACKBACKS = 'trackbacks';
const SUPPORTS_CUSTOM_FIELDS = 'custom-fields';
const SUPPORTS_COMMENTS = 'comments'; // (also will see comment count balloon on edit screen)
const SUPPORTS_REVISIONS = 'revisions';
const SUPPORTS_ORDER = 'page-attributes'; // (menu order, hierarchical must be true to show Parent option)
const SUPPORTS_POST_FORMATS = 'post-formats';
Method / Called in | Description |
---|---|
__construct | Register init hook to run post types registration. |
init (a)init |
Abstract method, you should define your own init method to register a post type. |
register init() |
Main logic for registering a post type based on class properties |
views (a)template_include |
Ability to update template hierarchy for specific post type. |