latest version

Register First Custom Post Type

Posts Settings Locations

Post related options should be set in the following locations:
  • for custom post types defined in extensions: plugin extension directory (see posts.php in Plugin structure)
  • for basic post types (post, page) and post formats: theme/inc/posts.php (see Theme structure)

It is necessary to register basic post types settings in the theme because they need to work without the theme plugin activated.

Note

Please note Unyson encourages to use theme/framework-customizations directory for basic posts settings (Unyson theme options), but it is not advisable to do so (unless such settings, metaboxes etc. are not necessary for basic blog/theme functionality).

Custom Post Type Example

To analyse example extension ct-portfolio with custom post type and taxonomy, there is a file theme-plugin/extensions/ct-portfolio/posts.php with the following example content:

<?php if ( ! defined( 'FW' ) ) {
        die( 'Forbidden' );
    }

/** Register post type & taxonomy for extension */

$ct_post = fw()->extensions->get( 'ct-portfolio' );

register_post_type( $ct_post->get_post_type(), array(
        'labels'              => array(
                'name'               => __( 'Portfolio items', 'ct_theme' ),
                'singular_name'      => __( 'Portfolio Item', 'ct_theme' ),
                'menu_name'          => __( 'Portfolio items', 'ct_theme' ),
                'add_new'            => __( 'Add New', 'portfolio', 'ct_theme' ),
                'add_new_item'       => __( 'Add New Portfolio Item', 'ct_theme' ),
                'new_item'           => __( 'New Portfolio Item', 'ct_theme' ),
                'edit_item'          => __( 'Edit Portfolio Item', 'ct_theme' ),
                'view_item'          => __( 'View Portfolio Item', 'ct_theme' ),
                'all_items'          => __( 'Our projects', 'ct_theme' ),
                'search_items'       => __( 'Search Portfolio Items', 'ct_theme' ),
                'parent_item_colon'  => '',
                'not_found'          => __( 'No portfolio item found', 'ct_theme' ),
                'not_found_in_trash' => __( 'No portfolio items found in Trash', 'ct_theme' ),
        ),
        'singular_label'      => __( 'portfolio', 'ct_theme' ),
        'public'              => true,
        'publicly_queryable'  => true,
        'exclude_from_search' => false,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'menu_position'       => 4,
        'menu_icon'           => 'dashicons-images-alt',
        'capability_type'     => 'post',
        'hierarchical'        => false,
        'supports'            => array( 'title', 'editor', 'excerpt', 'thumbnail', 'comments', 'page-attributes' ),
        'has_archive'         => false,
        'rewrite'             => array( 'slug' => $ct_post->get_portfolio_slug() ),
        'query_var'           => false,
        'can_export'          => true,
        'show_in_nav_menus'   => true,
        'taxonomies'          => array( 'post_tag' )
) );

/**
* Creates taxonomies
*/


//Register taxonomy
$category_names = array(
        'singular' => __( 'Portfolio Category', 'fw' ),
        'plural'   => __( 'Portfolio Categories', 'fw' )
);

$labels = array(
        'name'              => sprintf( _x( '%s', 'taxonomy general name', 'fw' ), $category_names['plural'] ),
        'singular_name'     => sprintf( _x( '%s', 'taxonomy singular name', 'fw' ), $category_names['singular'] ),
        'search_items'      => __( 'Search categories', 'fw' ),
        'all_items'         => sprintf( __( 'All %s', 'fw' ), $category_names['plural'] ),
        'parent_item'       => sprintf( __( 'Parent %s', 'fw' ), $category_names['singular'] ),
        'parent_item_colon' => sprintf( __( 'Parent %s:', 'fw' ), $category_names['singular'] ),
        'edit_item'         => sprintf( __( 'Edit %s', 'fw' ), $category_names['singular'] ),
        'update_item'       => sprintf( __( 'Update %s', 'fw' ), $category_names['singular'] ),
        'add_new_item'      => __( 'Add New category', 'fw' ),
    'new_item_name'     => sprintf( __( 'New %s Name', 'fw' ), $category_names['singular'] ),
    'menu_name'         => sprintf( __( '%s', 'fw' ), $category_names['plural'] )
);

$args = array(
    'labels'            => $labels,
    'public'            => true,
    'hierarchical'      => true,
    'show_ui'           => true,
    'show_admin_column' => true,
    'query_var'         => true,
    'show_in_nav_menus' => true,
    'show_tagcloud'     => false,
    'rewrite'           => array(
            'slug' => $ct_post->get_taxonomy_slug()
    ),
);

register_taxonomy( $ct_post->get_taxonomy_type(), esc_attr( $ct_post->get_post_type() ), $args );

This file is automatically included as long as the extension is activated.

Result:

../../_images/custom-post-type-portfolio.png

Create New Post Type Extension

Before you create a new extension, it is a good idea to browse already written extensions at Samples Gitlab repository

In order to create a new post type extension, please copy the example ct-team extension from boilerplate at theme-plugin-boilerplate/extensions/ct-team and change settings in class-fw-extension-ct-team.php and posts.php file according to new extension needs. More information about extensions can be found in Extensions documentation

Post Settings Example

If you need to add custom metaboxes to post formats, you can do so in theme/inc/posts.php file, as in the snippet below:

<?php if ( ! defined( 'ABSPATH' ) ) {
        die( 'Direct access forbidden.' );
}

/**
* Post settings
*/

/** Register metaboxes */
add_action( 'admin_print_scripts', 'fw_ct_bee_display_metaboxes', 1000 );
function fw_ct_bee_display_metaboxes() {
        add_meta_box( "post-video-meta", esc_html__( "Video format settings", 'ct_theme' ), "fw_bee_post_video_meta", "post", "normal", "high" );
        add_meta_box( "post-audio-meta", esc_html__( "Audio format settings", 'ct_theme' ), "fw_bee_post_audio_meta", "post", "normal", "high" );
}

/** Register custom post save action */
add_action( 'save_post', '_fw_ct_bee_post_save_details' );

/** meta render callback */
function fw_bee_post_audio_meta() {
    // TODO implement callback
}

/** meta render callback */
function fw_bee_post_video_meta() {
    // TODO implement callback
}

/** post save callbacks */
function _fw_ct_bee_post_save_details() {
    // TODO implement callback
}

...