Created
February 27, 2014 16:25
-
-
Save bradyvercher/9253463 to your computer and use it in GitHub Desktop.
Mustache templates for generating WordPress CPT code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* {{singular}} CPT | |
* | |
* @package {{plural}} | |
* @author Your Name <email@example.com> | |
* @license http://www.gnu.org/licenses/gpl-2.0.html | |
* @link http://www.blazersix.com/wordpress-code-generators/ | |
* | |
* @todo Remove unused code and update where needed. | |
* | |
{{#plugin_headers}} | |
* @wordpress-plugin | |
* Plugin Name: {{singular}} CPT | |
* Plugin URI: | |
* Description: A generated {{singular_lower}} custom post type implementation. | |
* Version: 1.0 | |
* Author: | |
* Author URI: | |
* License: GPL-2.0+ | |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html | |
{{/plugin_headers}} | |
*/ | |
/** | |
* Main {{singular_name}} class. | |
*/ | |
class {{class_name}} { | |
/** | |
* Register {{singular}} custom post type. | |
* | |
* Registers the {{singular}} custom post type and related admin interface | |
* elements (custom columns, update messages, meta boxes, standard menu). | |
* | |
* @link http://codex.wordpress.org/Function_Reference/register_post_type | |
*/ | |
public function init() { | |
$labels = array( | |
'name' => {{#text_domain}}_x( {{/text_domain}}'{{plural}}',{{#text_domain}} 'post type general name', '{{text_domain}}' ),{{/text_domain}} | |
'singular_name' => {{#text_domain}}_x( {{/text_domain}}'{{singular}}',{{#text_domain}} 'post type singular name', '{{text_domain}}' ),{{/text_domain}} | |
'menu_name' => {{#text_domain}}_x( {{/text_domain}}'{{plural}}',{{#text_domain}} 'admin menu', '{{text_domain}}' ),{{/text_domain}} | |
'name_admin_bar' => {{#text_domain}}_x( {{/text_domain}}'{{singular}}',{{#text_domain}} 'add new on admin bar', '{{text_domain}}' ),{{/text_domain}} | |
'add_new' => {{#text_domain}}_x( {{/text_domain}}'Add New',{{#text_domain}} '{{post_type}}', '{{text_domain}}' ),{{/text_domain}} | |
'add_new_item' => {{#text_domain}}__( {{/text_domain}}'Add New {{singular}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'new_item' => {{#text_domain}}__( {{/text_domain}}'New {{singular}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'edit_item' => {{#text_domain}}__( {{/text_domain}}'Edit {{singular}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'view_item' => {{#text_domain}}__( {{/text_domain}}'View {{singular}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'all_items' => {{#text_domain}}__( {{/text_domain}}'All {{plural}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'search_items' => {{#text_domain}}__( {{/text_domain}}'Search {{plural}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'parent_item_colon' => {{#text_domain}}__( {{/text_domain}}'Parent {{plural}}:',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'not_found' => {{#text_domain}}__( {{/text_domain}}'No {{plural_lower}} found.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'not_found_in_trash' => {{#text_domain}}__( {{/text_domain}}'No {{plural_lower}} found in Trash.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
); | |
{{#verbosify}} | |
$capabilities = array( | |
// Meta capabilities. | |
'edit_post' => 'edit_{{post_type}}', | |
'read_post' => 'read_{{post_type}}', | |
'delete_post' => 'delete_{{post_type}}', | |
// Primitive capabilities used throughout core to check permissions. | |
'edit_posts' => 'edit_{{post_type}}s', | |
'edit_others_posts' => 'edit_others_{{post_type}}s', | |
'publish_posts' => 'publish_{{post_type}}s', | |
'read_private_posts' => 'read_private_{{post_type}}s', | |
// Primitive capabilites translated from meta capabilities in map_meta_cap(). | |
'read' => 'read', | |
'delete_posts' => 'delete_{{post_type}}s', | |
'delete_private_posts' => 'delete_private_{{post_type}}s', | |
'delete_published_posts' => 'delete_published_{{post_type}}s', | |
'delete_others_posts' => 'delete_others_{{post_type}}s', | |
'edit_private_posts' => 'edit_private_{{post_type}}s', | |
'edit_published_posts' => 'edit_published_{{post_type}}s' | |
); | |
{{/verbosify}} | |
$args = array( | |
{{#verbosify}} | |
'can_export' => true, | |
'capability_type' => array( '{{post_type}}', '{{post_type}}s' ), | |
'capabilities' => $capabilities, | |
'delete_with_user' => null, | |
'description' => '', | |
{{/verbosify}} | |
'exclude_from_search' => false, | |
'has_archive' => false, | |
'hierarchical' => {{#hierarchical}}true{{/hierarchical}}{{^hierarchical}}false{{/hierarchical}}, | |
'labels' => $labels, | |
{{#verbosify}} | |
'map_meta_cap' => false, | |
'menu_icon' => null, | |
{{/verbosify}} | |
'menu_position' => 50, | |
'public' => true, | |
'publicly_queryable' => true, | |
'register_meta_box_cb' => array( $this, 'register_meta_boxes' ), | |
'rewrite' => array( | |
'slug' => '{{post_type}}', | |
'with_front' => false, | |
{{#verbosify}} | |
'feeds' => null, | |
'pages' => true, | |
'ep_mask' => EP_PERMALINK, | |
{{/verbosify}} | |
), | |
{{#verbosify}} | |
'query_var' => '{{post_type}}', | |
{{/verbosify}} | |
'show_ui' => true, | |
{{#verbosify}} | |
'show_in_admin_bar' => true, | |
{{/verbosify}} | |
'show_in_menu' => true, | |
'show_in_nav_menus' => false, | |
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'page-attributes', 'post-formats' ){{#verbosify}},{{/verbosify}} | |
{{#verbosify}} | |
'taxonomies' => array(), | |
{{/verbosify}} | |
); | |
register_post_type( '{{post_type}}', $args ); | |
if ( is_admin() ) { | |
add_filter( 'post_updated_messages', array( $this, 'updated_messages' ) ); | |
{{#verbosify}} | |
add_filter( 'parse_query', array( $this, 'parse_admin_query' ) ); | |
{{/verbosify}} | |
add_filter( 'manage_edit-{{post_type}}_columns', array( $this, 'register_columns' ) ); | |
{{#verbosify}} | |
add_action( 'manage_edit-{{post_type}}_sortable_columns', array( $this, 'register_sortable_columns' ) ); | |
{{/verbosify}} | |
add_action( 'manage_{{post_type}}_posts_custom_column', array( $this, 'display_columns' ), 10, 2 ); | |
add_action( 'save_post', array( $this, 'save_post' ), 10, 2 ); | |
} | |
{{#verbosify}} | |
add_filter( 'map_meta_cap', array( $this, 'map_meta_cap' ), 10, 4 ); | |
{{/verbosify}} | |
} | |
/** | |
* {{singular}} update messages. | |
* | |
* @see /wp-admin/edit-form-advanced.php | |
* | |
* @param array $messages The array of post update messages. | |
* @return array An array with new CPT update messages. | |
*/ | |
public function updated_messages( $messages ) { | |
$post = get_post(); | |
$post_type = get_post_type( $post ); | |
$post_type_object = get_post_type_object( $post_type ); | |
$messages['{{post_type}}'] = array( | |
0 => '', // Unused. Messages start at index 1. | |
1 => {{#text_domain}}__( {{/text_domain}}'{{singular}} updated.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
2 => {{#text_domain}}__( {{/text_domain}}'Custom field updated.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
3 => {{#text_domain}}__( {{/text_domain}}'Custom field deleted.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
4 => {{#text_domain}}__( {{/text_domain}}'{{singular}} updated.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
/* translators: %s: date and time of the revision */ | |
5 => isset( $_GET['revision'] ) ? sprintf( {{#text_domain}}__( {{/text_domain}}'{{singular}} restored to revision from %s',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, | |
6 => {{#text_domain}}__( {{/text_domain}}'{{singular}} published.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
7 => {{#text_domain}}__( {{/text_domain}}'{{singular}} saved.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
8 => {{#text_domain}}__( {{/text_domain}}'{{singular}} submitted.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
9 => sprintf( {{#text_domain}}__( {{/text_domain}}'{{singular}} scheduled for: <strong>%1$s</strong>.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
// translators: Publish box date format, see http://php.net/date | |
date_i18n( {{#text_domain}}__( {{/text_domain}}'M j, Y @ G:i',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} strtotime( $post->post_date ) ) ), | |
10 => {{#text_domain}}__( {{/text_domain}}'{{singular}} draft updated.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
); | |
if ( $post_type_object->publicly_queryable ) { | |
$permalink = get_permalink( $post->ID ); | |
$preview_permalink = add_query_arg( 'preview', 'true', $permalink ); | |
$view_link = sprintf( ' <a href="%s">%s</a>', esc_url( $permalink ), {{#text_domain}}__( {{/text_domain}}'View {{singular_lower}}',{{#text_domain}} '{{text_domain}}' ){{/text_domain}} ); | |
$preview_link = sprintf( ' <a target="_blank" href="%s">%s</a>', esc_url( $preview_permalink ), {{#text_domain}}__( {{/text_domain}}'Preview {{singular_lower}}',{{#text_domain}} '{{text_domain}}' ){{/text_domain}} ); | |
$messages[ $post_type ][1] .= $view_link; | |
$messages[ $post_type ][6] .= $view_link; | |
$messages[ $post_type ][9] .= $view_link; | |
$messages[ $post_type ][8] .= $preview_link; | |
$messages[ $post_type ][10] .= $preview_link; | |
} | |
return $messages; | |
} | |
{{#verbosify}} | |
/** | |
* Custom sort the posts on the Manage {{plural}} screen. | |
* | |
* @link http://codex.wordpress.org/Class_Reference/WP_Query | |
* | |
* @todo Update the sortable key to match the query_var set in the | |
* register_sortable_columns() method. | |
* @todo Implement custom sorting rules. | |
* | |
* @param WP_Query $wp_query The main WP_Query object passed by reference. | |
*/ | |
public function parse_admin_query( $wp_query ) { | |
// Ensure this only affects requests in the admin panel. | |
if ( ! is_admin() || empty( $_GET['post_type'] ) || '{{post_type}}' != $_GET['post_type'] ) { | |
return; | |
} | |
// An array of custom sortable column query vars. | |
$sortable_keys = array( '{{prefix}}query-var' ); | |
if ( ! empty( $_GET['orderby'] ) && in_array( $_GET['orderby'], $sortable_keys ) ) { | |
// Set the order. | |
$order = ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] ) ? 'desc' : 'asc'; | |
$wp_query->set( 'order', $order ); | |
// Implement custom sorting rules. | |
if ( '{{prefix}}query-var' == $_GET['orderby'] ) { | |
// An example to sort results by a custom meta field. | |
$wp_query->set( 'meta_key', '_{{prefix}}meta_key' ); | |
$wp_query->set( 'orderby', 'meta_value_num' ); | |
} | |
} | |
} | |
{{/verbosify}} | |
/** | |
* Register custom {{singular}} columns. | |
* | |
* @param array $columns Column names to display. | |
*/ | |
public function register_columns( $columns ) { | |
// $columns['{{prefix}}custom_column_id'] = {{#text_domain}}_x( {{/text_domain}}'Column Name'{{#text_domain}}, 'column name', '{{text_domain}}' ){{/text_domain}}; | |
return $columns; | |
} | |
{{#verbosify}} | |
/** | |
* Register custom {{singular}} sortable columns. | |
* | |
* Registering a column as sortable will allow the table header to be | |
* clicked to sort the {{singular}} posts. The query var assigned in this | |
* function will be passed in the URL as the value of 'orderby', along | |
* with whether or not results should be ASC or DESC. A hook should be | |
* attached to the 'parse_query' filter in order to handle the custom | |
* sorting rules. | |
* | |
* Multiple sortable columns may be registered at the same time. | |
* | |
* @param array $columns Column query vars with their corresponding column id as the key. | |
*/ | |
public function register_sortable_columns( $columns ) { | |
$columns['{{prefix}}custom_column_id'] = '{{prefix}}query-var'; | |
return $columns; | |
} | |
{{/verbosify}} | |
/** | |
* Display custom {{singular}} columns. | |
* | |
* @param string $column_id The id of the column to display. | |
* @param int $post_id Post ID. | |
*/ | |
public function display_columns( $column_id, $post_id ) { | |
switch ( $column_id ) { | |
case '{{prefix}}custom_column_id' : | |
// Output the custom column content here. | |
echo 'Value'; | |
break; | |
} | |
} | |
/** | |
* Save {{singular}} CPT data. | |
* | |
* @see wp_insert_post() | |
* | |
* @param int $post_id Post ID. | |
* @param WP_Post $post Post object. | |
*/ | |
public function save_post( $post_id, $post ) { | |
$is_autosave = defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE; | |
$is_revision = wp_is_post_revision( $post_id ); | |
$is_valid_nonce = isset( $_POST['{{prefix}}{{post_type}}_nonce'] ) && wp_verify_nonce( $_POST['{{prefix}}{{post_type}}_nonce'], 'save-{{post_type}}_' . $post_id ); | |
// Bail if the data shouldn't be saved or intention can't be verified. | |
if ( $is_autosave || $is_revision || ! $is_valid_nonce ) { | |
return; | |
} | |
// @todo Save custom data from $_POST global here. | |
} | |
/** | |
* Register {{singular}} meta boxes. | |
* | |
* This is the callback defined in the {{singular}} CPT registration | |
* function. Meta boxes or any other functionality that should be limited | |
* to the Add/Edit {{singular}} screen and occurs after 'do_meta_boxes' | |
* can be registered here. | |
* | |
* @param WP_Post $post Post object. | |
*/ | |
public function register_meta_boxes( $post ) { | |
// Update these parameters and uncomment to add a meta box. | |
/* | |
add_meta_box( | |
'meta-box-id', | |
{{#text_domain}}__( {{/text_domain}}'{{singular}} Meta Box',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
array( $this, 'meta_box' ), | |
'{{post_type}}', | |
'normal', | |
'default' | |
); | |
*/ | |
} | |
/** | |
* Display {{singular}} meta box. | |
* | |
* @param WP_Post $post Post object. | |
* @param array $meta_box Arguments passed when the meta box was registered. | |
*/ | |
public function meta_box( $post, $meta_box ) { | |
wp_nonce_field( 'save-{{post_type}}_' . $post->ID, '{{prefix}}{{post_type}}_nonce' ); | |
?> | |
<p> | |
<label for="field-id">Field Label:</label><br> | |
<input type="text" name="field_name" id="field-id" value="<?php echo esc_attr( $field_value ); ?>" class="regular-text"> | |
</p> | |
<p> | |
<label for="field2-id">Field Label:</label><br> | |
<textarea name="field2_name" id="field2-id" rows="3" class="widefat"><?php echo esc_textarea( $field2_value ); ?></textarea> | |
</p> | |
<?php | |
} | |
{{#verbosify}} | |
/** | |
* Map {{singular}} meta capabilities to primitive capabilities. | |
* | |
* @link http://justintadlock.com/archives/2010/07/10/meta-capabilities-for-custom-post-types | |
* @see map_meta_cap() | |
* | |
* @param array $caps Primitive capabilities determined by core. | |
* @param string $cap Capability name. | |
* @param int $user_id User ID. | |
* @return array Actual capabilities for meta capability. | |
*/ | |
public function map_meta_cap( $caps, $cap, $user_id, $args ) { | |
$meta_caps = array( 'edit_{{post_type}}', 'read_{{post_type}}', 'delete_{{post_type}}' ); | |
if ( in_array( $cap, $meta_caps ) ) { | |
$post = get_post( $args[0] ); | |
if ( 'revision' == $post->post_type ) { | |
$post = get_post( $post->post_parent ); | |
} | |
$post_type = get_post_type_object( $post->post_type ); | |
$caps = array(); | |
if ( ! $post_type->map_meta_cap ) { | |
$caps[] = $post_type->cap->$cap; | |
} | |
$user_data = get_userdata( $user_id ); | |
$post_author_data = $user_data; | |
if ( ! empty( $post->post_author ) ) { | |
$post_author_data = get_userdata( $post->post_author ); | |
} | |
switch( $cap ) { | |
case 'edit_{{post_type}}' : | |
// If the user is the author... | |
if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) { | |
// If the post is published... | |
if ( 'publish' == $post->post_status ) { | |
$caps[] = $post_type->cap->edit_published_posts; | |
} elseif ( 'trash' == $post->post_status ) { | |
if ( 'publish' == get_post_meta( $post->ID, '_wp_trash_meta_status', true ) ) { | |
$caps[] = $post_type->cap->edit_published_posts; | |
} | |
} else { | |
// If the post is draft... | |
$caps[] = $post_type->cap->edit_posts; | |
} | |
} else { | |
// The user is trying to edit someone else's post. | |
$caps[] = $post_type->cap->edit_others_posts; | |
// The post is published, extra cap required. | |
if ( 'publish' == $post->post_status ) { | |
$caps[] = $post_type->cap->edit_published_posts; | |
} elseif ( 'private' == $post->post_status ) { | |
$caps[] = $post_type->cap->edit_private_posts; | |
} | |
} | |
break; | |
case 'read_{{post_type}}' : | |
$status_obj = get_post_status_object( $post->post_status ); | |
if ( $status_obj->public ) { | |
$caps[] = $post_type->cap->read; | |
break; | |
} | |
if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) { | |
$caps[] = $post_type->cap->read; | |
} elseif ( $status_obj->private ) { | |
$caps[] = $post_type->cap->read_private_posts; | |
} else { | |
$caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); | |
} | |
break; | |
case 'delete_{{post_type}}' : | |
// If the user is the author... | |
if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) { | |
// If the post is published... | |
if ( 'publish' == $post->post_status ) { | |
$caps[] = $post_type->cap->delete_published_posts; | |
} elseif ( 'trash' == $post->post_status ) { | |
if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) ) { | |
$caps[] = $post_type->cap->delete_published_posts; | |
} | |
} else { | |
// If the post is draft... | |
$caps[] = $post_type->cap->delete_posts; | |
} | |
} else { | |
// The user is trying to edit someone else's post. | |
$caps[] = $post_type->cap->delete_others_posts; | |
// The post is published, extra cap required. | |
if ( 'publish' == $post->post_status ) { | |
$caps[] = $post_type->cap->delete_published_posts; | |
} elseif ( 'private' == $post->post_status ) { | |
$caps[] = $post_type->cap->delete_private_posts; | |
} | |
} | |
break; | |
} | |
} | |
return $caps; | |
} | |
{{/verbosify}} | |
} | |
${{prefix}}{{post_type}} = new {{class_name}}(); | |
add_action( 'init', array( ${{prefix}}{{post_type}}, 'init' ) ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* {{singular}} CPT | |
* | |
* @package {{plural}} | |
* @author Your Name <email@example.com> | |
* @license http://www.gnu.org/licenses/gpl-2.0.html | |
* @link http://www.blazersix.com/wordpress-code-generators/ | |
* | |
* @todo Remove unused code and update where needed. | |
* | |
{{#plugin_headers}} | |
* @wordpress-plugin | |
* Plugin Name: {{singular}} CPT | |
* Plugin URI: | |
* Description: A generated {{singular_lower}} custom post type implementation. | |
* Version: 1.0 | |
* Author: | |
* Author URI: | |
* License: GPL-2.0+ | |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html | |
{{/plugin_headers}} | |
*/ | |
/** | |
* Register {{singular}} custom post type. | |
* | |
* Registers the {{singular}} custom post type and related admin interface | |
* elements (custom columns, update messages, meta boxes, standard menu). | |
* | |
* @link http://codex.wordpress.org/Function_Reference/register_post_type | |
*/ | |
function {{prefix}}{{post_type}}_init() { | |
$labels = array( | |
'name' => {{#text_domain}}_x( {{/text_domain}}'{{plural}}',{{#text_domain}} 'post type general name', '{{text_domain}}' ),{{/text_domain}} | |
'singular_name' => {{#text_domain}}_x( {{/text_domain}}'{{singular}}',{{#text_domain}} 'post type singular name', '{{text_domain}}' ),{{/text_domain}} | |
'menu_name' => {{#text_domain}}_x( {{/text_domain}}'{{plural}}',{{#text_domain}} 'admin menu', '{{text_domain}}' ),{{/text_domain}} | |
'name_admin_bar' => {{#text_domain}}_x( {{/text_domain}}'{{singular}}',{{#text_domain}} 'add new on admin bar', '{{text_domain}}' ),{{/text_domain}} | |
'add_new' => {{#text_domain}}_x( {{/text_domain}}'Add New',{{#text_domain}} '{{post_type}}', '{{text_domain}}' ),{{/text_domain}} | |
'add_new_item' => {{#text_domain}}__( {{/text_domain}}'Add New {{singular}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'new_item' => {{#text_domain}}__( {{/text_domain}}'New {{singular}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'edit_item' => {{#text_domain}}__( {{/text_domain}}'Edit {{singular}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'view_item' => {{#text_domain}}__( {{/text_domain}}'View {{singular}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'all_items' => {{#text_domain}}__( {{/text_domain}}'All {{plural}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'search_items' => {{#text_domain}}__( {{/text_domain}}'Search {{plural}}',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'parent_item_colon' => {{#text_domain}}__( {{/text_domain}}'Parent {{plural}}:',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'not_found' => {{#text_domain}}__( {{/text_domain}}'No {{plural_lower}} found.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
'not_found_in_trash' => {{#text_domain}}__( {{/text_domain}}'No {{plural_lower}} found in Trash.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
); | |
{{#verbosify}} | |
$capabilities = array( | |
// Meta capabilities. | |
'edit_post' => 'edit_{{post_type}}', | |
'read_post' => 'read_{{post_type}}', | |
'delete_post' => 'delete_{{post_type}}', | |
// Primitive capabilities used throughout core to check permissions. | |
'edit_posts' => 'edit_{{post_type}}s', | |
'edit_others_posts' => 'edit_others_{{post_type}}s', | |
'publish_posts' => 'publish_{{post_type}}s', | |
'read_private_posts' => 'read_private_{{post_type}}s', | |
// Primitive capabilites translated from meta capabilities in map_meta_cap(). | |
'read' => 'read', | |
'delete_posts' => 'delete_{{post_type}}s', | |
'delete_private_posts' => 'delete_private_{{post_type}}s', | |
'delete_published_posts' => 'delete_published_{{post_type}}s', | |
'delete_others_posts' => 'delete_others_{{post_type}}s', | |
'edit_private_posts' => 'edit_private_{{post_type}}s', | |
'edit_published_posts' => 'edit_published_{{post_type}}s' | |
); | |
{{/verbosify}} | |
$args = array( | |
{{#verbosify}} | |
'can_export' => true, | |
'capability_type' => array( '{{post_type}}', '{{post_type}}s' ), | |
'capabilities' => $capabilities, | |
'delete_with_user' => null, | |
'description' => '', | |
{{/verbosify}} | |
'exclude_from_search' => false, | |
'has_archive' => false, | |
'hierarchical' => {{#hierarchical}}true{{/hierarchical}}{{^hierarchical}}false{{/hierarchical}}, | |
'labels' => $labels, | |
{{#verbosify}} | |
'map_meta_cap' => false, | |
'menu_icon' => null, | |
{{/verbosify}} | |
'menu_position' => 50, | |
'public' => true, | |
'publicly_queryable' => true, | |
'register_meta_box_cb' => '{{prefix}}register_{{post_type}}_meta_boxes', | |
'rewrite' => array( | |
'slug' => '{{post_type}}', | |
'with_front' => false, | |
{{#verbosify}} | |
'feeds' => null, | |
'pages' => true, | |
'ep_mask' => EP_PERMALINK, | |
{{/verbosify}} | |
), | |
{{#verbosify}} | |
'query_var' => '{{post_type}}', | |
{{/verbosify}} | |
'show_ui' => true, | |
{{#verbosify}} | |
'show_in_admin_bar' => true, | |
{{/verbosify}} | |
'show_in_menu' => true, | |
'show_in_nav_menus' => false, | |
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'page-attributes', 'post-formats' ){{#verbosify}},{{/verbosify}} | |
{{#verbosify}} | |
'taxonomies' => array(), | |
{{/verbosify}} | |
); | |
register_post_type( '{{post_type}}', $args ); | |
if ( is_admin() ) { | |
add_filter( 'post_updated_messages', '{{prefix}}{{post_type}}_updated_messages' ); | |
{{#verbosify}} | |
add_filter( 'parse_query', '{{prefix}}{{post_type}}_parse_admin_query' ); | |
{{/verbosify}} | |
add_filter( 'manage_edit-{{post_type}}_columns', '{{prefix}}{{post_type}}_register_columns' ); | |
{{#verbosify}} | |
add_action( 'manage_edit-{{post_type}}_sortable_columns', '{{prefix}}{{post_type}}_register_sortable_columns' ); | |
{{/verbosify}} | |
add_action( 'manage_{{post_type}}_posts_custom_column', '{{prefix}}{{post_type}}_display_columns', 10, 2 ); | |
add_action( 'save_post', '{{prefix}}{{post_type}}_save_post', 10, 2 ); | |
} | |
{{#verbosify}} | |
add_filter( 'map_meta_cap', '{{prefix}}{{post_type}}_map_meta_cap', 10, 4 ); | |
{{/verbosify}} | |
} | |
add_action( 'init', '{{prefix}}{{post_type}}_init' ); | |
/** | |
* {{singular}} update messages. | |
* | |
* @see /wp-admin/edit-form-advanced.php | |
* | |
* @param array $messages The array of post update messages. | |
* @return array An array with new CPT update messages. | |
*/ | |
function {{prefix}}{{post_type}}_updated_messages( $messages ) { | |
$post = get_post(); | |
$post_type = get_post_type( $post ); | |
$post_type_object = get_post_type_object( $post_type ); | |
$messages['{{post_type}}'] = array( | |
0 => '', // Unused. Messages start at index 1. | |
1 => {{#text_domain}}__( {{/text_domain}}'{{singular}} updated.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
2 => {{#text_domain}}__( {{/text_domain}}'Custom field updated.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
3 => {{#text_domain}}__( {{/text_domain}}'Custom field deleted.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
4 => {{#text_domain}}__( {{/text_domain}}'{{singular}} updated.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
/* translators: %s: date and time of the revision */ | |
5 => isset( $_GET['revision'] ) ? sprintf( {{#text_domain}}__( {{/text_domain}}'{{singular}} restored to revision from %s',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, | |
6 => {{#text_domain}}__( {{/text_domain}}'{{singular}} published.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
7 => {{#text_domain}}__( {{/text_domain}}'{{singular}} saved.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
8 => {{#text_domain}}__( {{/text_domain}}'{{singular}} submitted.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
9 => sprintf( {{#text_domain}}__( {{/text_domain}}'{{singular}} scheduled for: <strong>%1$s</strong>.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
// translators: Publish box date format, see http://php.net/date | |
date_i18n( {{#text_domain}}__( {{/text_domain}}'M j, Y @ G:i',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} strtotime( $post->post_date ) ) ), | |
10 => {{#text_domain}}__( {{/text_domain}}'{{singular}} draft updated.',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} | |
); | |
if ( $post_type_object->publicly_queryable ) { | |
$permalink = get_permalink( $post->ID ); | |
$preview_permalink = add_query_arg( 'preview', 'true', $permalink ); | |
$view_link = sprintf( ' <a href="%s">%s</a>', esc_url( $permalink ), {{#text_domain}}__( {{/text_domain}}'View {{singular_lower}}',{{#text_domain}} '{{text_domain}}' ){{/text_domain}} ); | |
$preview_link = sprintf( ' <a target="_blank" href="%s">%s</a>', esc_url( $preview_permalink ), {{#text_domain}}__( {{/text_domain}}'Preview {{singular_lower}}',{{#text_domain}} '{{text_domain}}' ){{/text_domain}} ); | |
$messages[ $post_type ][1] .= $view_link; | |
$messages[ $post_type ][6] .= $view_link; | |
$messages[ $post_type ][9] .= $view_link; | |
$messages[ $post_type ][8] .= $preview_link; | |
$messages[ $post_type ][10] .= $preview_link; | |
} | |
return $messages; | |
} | |
{{#verbosify}} | |
/** | |
* Custom sort the posts on the Manage {{plural}} screen. | |
* | |
* @link http://codex.wordpress.org/Class_Reference/WP_Query | |
* | |
* @todo Update the sortable key to match the query_var set in the | |
* register_sortable_columns() method. | |
* @todo Implement the custom sorting rules. | |
* | |
* @param WP_Query $wp_query The main WP_Query object passed by reference. | |
*/ | |
function {{prefix}}{{post_type}}_parse_admin_query( $wp_query ) { | |
// Ensure this only affects requests in the admin panel. | |
if ( ! is_admin() || empty( $_GET['post_type'] ) || '{{post_type}}' != $_GET['post_type'] ) { | |
return; | |
} | |
// An array of custom sortable column query vars. | |
$sortable_keys = array( '{{prefix}}query-var' ); | |
if ( ! empty( $_GET['orderby'] ) && in_array( $_GET['orderby'], $sortable_keys ) ) { | |
// Set the order. | |
$order = ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] ) ? 'desc' : 'asc'; | |
$wp_query->set( 'order', $order ); | |
// Implement custom sorting rules. | |
if ( '{{prefix}}query-var' == $_GET['orderby'] ) { | |
// An example to sort results by a custom meta field. | |
$wp_query->set( 'meta_key', '_{{prefix}}meta_key' ); | |
$wp_query->set( 'orderby', 'meta_value_num' ); | |
} | |
} | |
} | |
{{/verbosify}} | |
/** | |
* Register custom {{singular}} columns. | |
* | |
* @param array $columns Column names to display. | |
*/ | |
function {{prefix}}{{post_type}}_register_columns( $columns ) { | |
// $columns['{{prefix}}custom_column_id'] = {{#text_domain}}_x( {{/text_domain}}'Column Name'{{#text_domain}}, 'column name', '{{text_domain}}' ){{/text_domain}}; | |
return $columns; | |
} | |
{{#verbosify}} | |
/** | |
* Register custom {{singular}} sortable columns. | |
* | |
* Registering a column as sortable will allow the table header to be clicked | |
* to sort the {{singular}} posts. The query var assigned in this function | |
* will be passed in the URL as the value of 'orderby', along with whether or | |
* not results should be ASC or DESC. A hook should be attached to the | |
* 'parse_query' filter in order to handle the custom sorting rules. | |
* | |
* Multiple sortable columns can be registered at the same time. | |
* | |
* @todo Update the column identifier key and query var. | |
* | |
* @param array $columns Column query vars with their corresponding column id as the key. | |
*/ | |
function {{prefix}}{{post_type}}_register_sortable_columns( $columns ) { | |
$columns['{{prefix}}custom_column_id'] = '{{prefix}}query-var'; | |
return $columns; | |
} | |
{{/verbosify}} | |
/** | |
* Display custom {{singular}} columns. | |
* | |
* @param string $column_id The id of the column to display. | |
* @param int $post_id Post ID. | |
*/ | |
function {{prefix}}{{post_type}}_display_columns( $column_id, $post_id ) { | |
switch ( $column_id ) { | |
case '{{prefix}}custom_column_id' : | |
// Output the custom column content here. | |
echo 'Value'; | |
break; | |
} | |
} | |
/** | |
* Save {{singular}} CPT data. | |
* | |
* @see wp_insert_post() | |
* | |
* @param int $post_id Post ID. | |
* @param WP_Post $post Post object. | |
*/ | |
function {{prefix}}{{post_type}}_save_post( $post_id, $post ) { | |
$is_autosave = defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ); | |
$is_revision = wp_is_post_revision( $post_id ); | |
$is_valid_nonce = isset( $_POST['{{prefix}}{{post_type}}_nonce'] ) && wp_verify_nonce( $_POST['{{prefix}}{{post_type}}_nonce'], 'save-{{post_type}}_' . $post_id ); | |
// Bail if the data shouldn't be saved or intention can't be verified. | |
if ( $is_autosave || $is_revision || ! $is_valid_nonce ) { | |
return; | |
} | |
// @todo Save custom data from $_POST global here. | |
} | |
/** | |
* Register {{singular}} meta boxes. | |
* | |
* This is the callback defined in the {{singular}} CPT registration function. | |
* Meta boxes or any other functionality that should be limited to the | |
* Add/Edit {{singular}} screen and occurs after 'do_meta_boxes' can be | |
* registered here. | |
* | |
* @param WP_Post $post Post object. | |
*/ | |
function {{prefix}}register_{{post_type}}_meta_boxes( $post ) { | |
// Update these parameters and uncomment to add a meta box | |
// add_meta_box( 'meta-box-id', {{#text_domain}}__( {{/text_domain}}'{{singular}} Meta Box',{{#text_domain}} '{{text_domain}}' ),{{/text_domain}} '{{prefix}}{{post_type}}_meta_box', '{{post_type}}', 'normal', 'default' ); | |
} | |
/** | |
* Display {{singular}} meta box. | |
* | |
* @param WP_Post $post Post object. | |
* @param array $meta_box Arguments passed when the meta box was registered. | |
*/ | |
function {{prefix}}{{post_type}}_meta_box( $post, $meta_box ) { | |
wp_nonce_field( 'save-{{post_type}}_' . $post->ID, '{{prefix}}{{post_type}}_nonce' ); | |
?> | |
<p> | |
<label for="field-id">Field Label:</label><br> | |
<input type="text" name="field_name" id="field-id" value="<?php echo esc_attr( $field_value ); ?>" class="regular-text"> | |
</p> | |
<p> | |
<label for="field2-id">Field Label:</label><br> | |
<textarea name="field2_name" id="field2-id" rows="3" class="widefat"><?php echo esc_textarea( $field2_value ); ?></textarea> | |
</p> | |
<?php | |
} | |
{{#verbosify}} | |
/** | |
* Map {{singular}} meta capabilities to primitive capabilities. | |
* | |
* @link http://justintadlock.com/archives/2010/07/10/meta-capabilities-for-custom-post-types | |
* @see map_meta_cap() | |
* | |
* @param array $caps Primitive capabilities determined by core. | |
* @param string $cap Capability name. | |
* @param int $user_id User ID. | |
* @return array Actual capabilities for meta capability. | |
*/ | |
function {{prefix}}{{post_type}}_map_meta_cap( $caps, $cap, $user_id, $args ) { | |
$meta_caps = array( 'edit_{{post_type}}', 'read_{{post_type}}', 'delete_{{post_type}}' ); | |
if ( in_array( $cap, $meta_caps ) ) { | |
$post = get_post( $args[0] ); | |
if ( 'revision' == $post->post_type ) { | |
$post = get_post( $post->post_parent ); | |
} | |
$post_type = get_post_type_object( $post->post_type ); | |
$caps = array(); | |
if ( ! $post_type->map_meta_cap ) { | |
$caps[] = $post_type->cap->$cap; | |
} | |
$user_data = get_userdata( $user_id ); | |
$post_author_data = $user_data; | |
if ( ! empty( $post->post_author ) ) { | |
$post_author_data = get_userdata( $post->post_author ); | |
} | |
switch( $cap ) { | |
case 'edit_{{post_type}}' : | |
// If the user is the author... | |
if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) { | |
// If the post is published... | |
if ( 'publish' == $post->post_status ) { | |
$caps[] = $post_type->cap->edit_published_posts; | |
} elseif ( 'trash' == $post->post_status ) { | |
if ( 'publish' == get_post_meta( $post->ID, '_wp_trash_meta_status', true ) ) { | |
$caps[] = $post_type->cap->edit_published_posts; | |
} | |
} else { | |
// If the post is draft... | |
$caps[] = $post_type->cap->edit_posts; | |
} | |
} else { | |
// The user is trying to edit someone else's post. | |
$caps[] = $post_type->cap->edit_others_posts; | |
// The post is published, extra cap required. | |
if ( 'publish' == $post->post_status ) { | |
$caps[] = $post_type->cap->edit_published_posts; | |
} elseif ( 'private' == $post->post_status ) { | |
$caps[] = $post_type->cap->edit_private_posts; | |
} | |
} | |
break; | |
case 'read_{{post_type}}' : | |
$status_obj = get_post_status_object( $post->post_status ); | |
if ( $status_obj->public ) { | |
$caps[] = $post_type->cap->read; | |
break; | |
} | |
if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) { | |
$caps[] = $post_type->cap->read; | |
} elseif ( $status_obj->private ) { | |
$caps[] = $post_type->cap->read_private_posts; | |
} else { | |
$caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); | |
} | |
break; | |
case 'delete_{{post_type}}' : | |
// If the user is the author... | |
if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) { | |
// If the post is published... | |
if ( 'publish' == $post->post_status ) { | |
$caps[] = $post_type->cap->delete_published_posts; | |
} elseif ( 'trash' == $post->post_status ) { | |
if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) ) { | |
$caps[] = $post_type->cap->delete_published_posts; | |
} | |
} else { | |
// If the post is draft... | |
$caps[] = $post_type->cap->delete_posts; | |
} | |
} else { | |
// The user is trying to edit someone else's post. | |
$caps[] = $post_type->cap->delete_others_posts; | |
// The post is published, extra cap required. | |
if ( 'publish' == $post->post_status ) { | |
$caps[] = $post_type->cap->delete_published_posts; | |
} elseif ( 'private' == $post->post_status ) { | |
$caps[] = $post_type->cap->delete_private_posts; | |
} | |
} | |
break; | |
} | |
} | |
return $caps; | |
} | |
{{/verbosify}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$args = array( | |
'prefix' => '', | |
'taxonomy' => '', | |
'post_type' => '', | |
'singular' => '', | |
'plural' => '', | |
'text_domain' => '', | |
'hierarchical' => true, | |
'verbosify' => true, | |
'classy' => true, | |
'plugin_headers' => false, | |
); | |
$args['prefix'] = ( empty( $args['prefix'] ) ) ? '' : rtrim( $args['prefix'], '_' ) . '_'; | |
$args['text_domain'] = ( empty( $args['text_domain'] ) ) ? false : $args['text_domain']; | |
$args['singular_lower'] = strtolower( $args['singular'] ); | |
$args['plural_lower'] = strtolower( $args['plural'] ); | |
$args['class_name'] = ucwords( $args['prefix'] ) . preg_replace( '|\s+|', '_', ucwords( $args['singular'] ) ); | |
require_once( 'Mustache/Autoloader.php' ); | |
Mustache_Autoloader::register(); | |
$template = file_get_contents( 'cpt.txt' ); | |
$m = new Mustache_Engine; | |
echo $m->render( $template, $args ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment