Custom post types are a great way to organize and structure your data in WordPress. A lot of WordPress plugins, especially complex ones, utilize custom post types to implement their features.
That’s great if plugin developers have foreseen that a user might want to modify one of their custom post types. They can add some options in the settings or maybe add some action/filter hooks in the code. But anyways, sometimes you just need to change the settings of a custom post type.
You may want to change the label of a post type, or you may want to hide it from the REST API. How to achieve this goal?
Introduction
First of all, do not modify a plugin’s code! If you modify a plugin’s code, all your changes are going to be rewritten the next time someone updates the plugin. You have to start thinking the WordPress way.
As you may know, you can register a custom post type using an in-built WordPress function — register_post_type(). What do I mean by saying that you have to think the WordPress way? It means that if you want to modify some code that a third party has written, you need to, first of all, try to modify it using actions or filters, if any provided.
Luckily, the WordPress core developers have provided us with a handy filter hook — register_post_type_args. Every time when WordPress registers a new custom post type, it parses the provided arguments and allows you to modify them using this filter hook.
As you might already have guessed, if you want to modify a custom post type without editing a register_post_type() call, you need to use this hook. Let’s practice a little bit.
Prerequisites
Let’s imagine that we have a plugin that registers a custom post type — Services. Here’s the code that registers this post type:
add_action( 'init', 'register_service_post_type', 10 );
function register_service_post_type() {
$labels = array(
'name' => 'Services',
'singular_name' => 'Service',
'menu_name' => 'Services',
'name_admin_bar' => 'Services',
'archives' => 'Service Archives',
'attributes' => 'Service Attributes',
'parent_item_colon' => 'Parent Service',
'all_items' => 'All Services',
'add_new_item' => 'Add New Service',
'add_new' => 'Add New',
'new_item' => 'New Service',
'edit_item' => 'Edit Service',
'update_item' => 'Update Service',
'view_item' => 'View Service',
'view_items' => 'View Services',
'search_items' => 'Search Service',
'not_found' => 'Not found',
'not_found_in_trash' => 'Not found in Trash',
'featured_image' => 'Featured Image',
'set_featured_image' => 'Set featured image',
'remove_featured_image' => 'Remove featured image',
'use_featured_image' => 'Use as featured image',
'insert_into_item' => 'Insert into Service',
'uploaded_to_this_item' => 'Uploaded to this service',
'items_list' => 'Services list',
'items_list_navigation' => 'Services list navigation',
'filter_items_list' => 'Filter services list',
);
$args = array(
'label' => 'Service',
'description' => 'Services you provide',
'labels' => $labels,
'supports' => array( 'title', 'editor' ),
'taxonomies' => array( 'category' ),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 20,
'menu_icon' => 'dashicons-hammer',
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => false,
'exclude_from_search' => true,
'publicly_queryable' => false,
'capability_type' => 'page',
'show_in_rest' => false,
);
register_post_type( 'service', $args );
}
If you’ve ever created your own custom post types before, there’s nothing new for you. Anyways, now know what default arguments we’ll have. Let’s try to modify them using the register_post_type_args hook.
How to change custom post type’s labels?
In the example above, I’m going to show you how to change a specific label and how to modify all labels at once:
add_filter( 'register_post_type_args', 'customize_service_post_type_labels', 10, 2 );
function customize_service_post_type_labels( $args, $post_type ) {
// Let's make sure that we're customizing the post type we really need
if ( $post_type !== 'service' ) {
return $args;
}
// Now, we have access to the $args variable
// If you want to modify just one label, you can do something like this
$args['labels']['name'] = 'Offerings';
// But let's imagine that I want to change all Service substring occurrencies to the new one
$new_labels = array();
foreach ( $args['labels'] as $key => $value ) {
if ( strpos( $value, 'Service' ) !== false ) {
$new_value = str_replace( 'Service', 'Offering', $value );
$new_labels[$key] = $new_value;
} else {
$new_labels[$key] = $value;
}
}
$args['labels'] = $new_labels;
return $args;
}
How to add new taxonomies to a custom post type?
As you might have noticed, the only taxonomy our custom post type has is category. What if I want to add the tags support to my offerings?
add_filter( 'register_post_type_args', 'add_tags_support_to_service_post_type', 10, 2 );
function add_tags_support_to_service_post_type( $args, $post_type ) {
// Let's make sure that we're customizing the post type we really need
if ( $post_type !== 'service' ) {
return $args;
}
// In our case, I'm pretty sure that the $args['taxonomies'] is an array
// But it's always a good idea to double check external variables and arguments
if ( is_array( $args['taxonomies'] ) ) {
$args['taxonomies'][] = 'post_tag';
} else {
$args['taxonomies'] = array( 'post_tag' );
}
return $args;
}
Summary
As you see, using the register_post_type_args hook, you can pretty easily customize third-party custom post types without modifying the source code. In other words, you’ll be able to update a plugin or a theme that registers the modified post types, which makes your website more secure and your job easier.
I hope you found this post helpful. Feel free to share your opinions and questions in the comments sections below. Don’t forget to follow me on LinkedIn account if you don’t want to miss new posts on my website.
Thank you for reading this post; see you in the next one!
Hi,
How to make it hierachical?
Would be
?
$args[‘hierarchical’] = true;
It’s really helpful.
Thank you!
Hi, thanks for this.
Could you please tell me where to apply the code?
Hi Daniel. You can add this code to your theme’s functions.php file, create a plugin, or use a code snippet plugin.