Allow users to publish child pages of the pages they have access to edit

Custom Post Types will be much easier to set up, and you won’t have to code your own solution to check in the Editor whether the current user has permission to create a new page or edit something.

You can set up the CPT archives at whatever URL you like.

So, in your example, you can set up a regular Page at /animals/ and a regular child Page at /animals/carnivores/. Your custom roles will not have any access to edit those.

You will then create a CPT of “cat”. You should look into all of the options for registering CPTs, as you may not need all of the options, but some may be handy, like “menu_icon” which sets the icon that appears in the wp-admin left sidebar, and some will be necessary, like “rewrite” which is what you need to set them up at the URLs you desire, and “capabilities” which are what you’ll use to restrict who can access what. You’ll also want to decide what to put in “supports” – this example includes a title, editor, and a thumbnail (featured image).

<?php
/* Plugin Name: WPSE custom post types
*/
// on init, create a custom post type called Cat
add_action('init', 'wpse_create_post_types');
function wpse_create_post_types() {
    // Capabilities: this is how you'll enable some users to edit, delete, etc.
    $capabilities = array(
        'edit_post'                 => 'edit_cat',
        'read_post'                 => 'read_cat',
        'delete_post'               => 'delete_cat',
        'create_posts'              => 'create_cats',
        'delete_posts'              => 'delete_cats',
        'delete_others_posts'       => 'delete_others_cats',
        'delete_private_posts'      => 'delete_private_cats',
        'delete_published_posts'    => 'delete_published_cats',
        'edit_posts'                => 'edit_cats',
        'edit_others_posts'         => 'edit_others_cats',
        'edit_private_posts'        => 'edit_private_cats',
        'edit_published_posts'      => 'edit_published_cats',
        'publish_posts'             => 'publish_news',
        'read_private_posts'        => 'read_private_news'
    );
    // Other CPT arguments
    $args = array(
        // Important: make sure to include the next 2 args for capabilities
        'map_meta_cap' => true,
        'capabilities' => $capabilities,
        // Important: make sure to set the rewrite to your desired archive URL
        'rewrite'           => array('slug' => 'animals/carnivores/cats'),
        // You can adjust the other args as needed
        'public' => true,
        'has_archive' => true,
        'hierarchical' => false,
        'supports' => array('title', 'editor', 'thumbnail')
    );
    // Actually create the post type
    register_post_type('cat', $args);
}

Because you have created new capabilities, no users have access to it yet – including Administrators. So to grant access, add this to the same plugin file:

// 'cat_author' is a slug, 'Custom Author Cats' is how you will see this role in wp-admin
add_role('cat_author', 'Custom Author Cats', array(
    // You may or may not want to give them all these capabilities.
    // For example you could let them publish but not delete.
    'delete_cats' => true,
    'create_cats' => true,
    'delete_cats' => true,
    'delete_others_cats' => true,
    'delete_private_cats' => true,
    'delete_published_cats' => true,
    'edit_cats' => true,
    'edit_others_cats' => true,
    'edit_private_cats' => true,
    'edit_published_cats' => true,
    'publish_cats' => true,
    'read_private_cats' => true,
    // If you want them to be able to upload files and read on the front end,
    // make sure to include the following 2 capabilities:
    'read' => true,
    'upload_files' => true
));

Finally, you may also want to have Admins (like yourself perhaps) be able to add/edit/delete these custom News posts. If so, add this to the plugin:

add_action('admin_init', 'wpse_add_admin_caps');
function wpse_add_admin_caps() {
    $role = get_role('administrator');
    $role->add_cap('delete_cats');
    $role->add_cap('create_cats');
    $role->add_cap('delete_cats');
    $role->add_cap('delete_others_cats');
    $role->add_cap('delete_private_cats');
    $role->add_cap('delete_published_cats');
    $role->add_cap('edit_cats');
    $role->add_cap('edit_others_cats');
    $role->add_cap('edit_private_cats');
    $role->add_cap('edit_published_cats');
    $role->add_cap('publish_cats');
    $role->add_cap('read_private_cats');
}

You’ll need to repeat this for each custom post type, and make sure that after the plugin is activated, you visit the Settings > Permalinks page. You don’t have to change any settings there, but visiting it will flush rewrite rules and set up the new URLs you’ve defined in the plugin. Then, the final step will be adding each user and assigning it the correct role.

Leave a Comment