Single Events as Sub-Page to Main Calendar Page

I’ll preface this by saying I have no experience with or knowledge of the plugin, this answer is based entirely on a 30 second scan of the code that registers the post type for use in the plugin, so you may uncover issues with this solution that my quick clicking of a test event didn’t catch. With that said…

The basic gist of this is to unset the post type registered by the plugin, and then re-register it with the same settings except for the modified rewrite slug. To understand how this works you should familiarize yourself with the register_post_type function if you’re not already.

The code that registers the post type for the plugin is in the file app/helper/class-ai1ec-app-helper.php.

The following code was tested in the Twenty Eleven theme’s functions.php file. You can do this in your own plugin, but you’ll have to be sure it runs after the event calendar plugin’s init for this to work.

Be sure to read all of the comments within the code to understand what was changed, the important detail being the rewrite argument of register_post_type which gives us our desired URL: 'rewrite' => array( 'slug' => 'calendar/event', 'with_front' => false )

add_action( 'init', 'wpa64981_event_calendar_init' );

function wpa64981_event_calendar_init() {

    // make sure the plugin is active and has set itself up
    if( defined( 'AI1EC_POST_TYPE' ) ) :

        // globalize the post types array and some plugin settings we'll need
        global $wp_post_types, $ai1ec_settings, $ai1ec_app_helper;

        // unset the original post type created by the plugin
        unset( $wp_post_types[ AI1EC_POST_TYPE ] );

        // the labels array was copied wholesale from the plugin
        // EXCEPT 'all_items' value, which originally reference $this
        $labels = array(
            'name' => _x( 'Events', 'Custom post type name', AI1EC_PLUGIN_NAME ),
            'singular_name' => _x( 'Event', 'Custom post type name (singular)', AI1EC_PLUGIN_NAME ),
            'add_new' => __( 'Add New', AI1EC_PLUGIN_NAME ),
            'add_new_item' => __( 'Add New Event', AI1EC_PLUGIN_NAME ),
            'edit_item' => __( 'Edit Event', AI1EC_PLUGIN_NAME ),
            'new_item' => __( 'New Event', AI1EC_PLUGIN_NAME ),
            'view_item' => __( 'View Event', AI1EC_PLUGIN_NAME ),
            'search_items' => __( 'Search Events', AI1EC_PLUGIN_NAME ),
            'not_found' => __( 'No Events found', AI1EC_PLUGIN_NAME ),
            'not_found_in_trash' => __( 'No Events found in Trash', AI1EC_PLUGIN_NAME ),
            'parent_item_colon' => __( 'Parent Event', AI1EC_PLUGIN_NAME ),
            'menu_name' => __( 'Events', AI1EC_PLUGIN_NAME ),
            'all_items' => $ai1ec_app_helper->get_all_items_name()
        );

        // identical to plugin's original values        
        $supports = array( 'title', 'editor', 'comments', 'custom-fields', 'thumbnail' );


        // this is where the important change is made
        // to get our own rewrite slug:
        // 
        // 'rewrite' => true
        // 
        // changes to:
        // 
        // 'rewrite' => array( 'slug' => 'calendar/event', 'with_front' => false )
        // 
        $args = array(
            'labels' => $labels,
            'public' => true,
            'publicly_queryable' => true,
            'show_ui' => true,
            'show_in_menu' => true,
            'query_var' => true,
            'rewrite' => array( 'slug' => 'calendar/event', 'with_front' => false ),
            'capability_type' => array( 'ai1ec_event', 'ai1ec_events' ),
            'capabilities' => array(
                'read_post'               => 'read_ai1ec_event',
                'edit_post'               => 'edit_ai1ec_event',
                'edit_posts'              => 'edit_ai1ec_events',
                'edit_others_posts'       => 'edit_others_ai1ec_events',
                'edit_private_posts'      => 'edit_private_ai1ec_events',
                'edit_published_posts'    => 'edit_published_ai1ec_events',
                'delete_post'             => 'delete_ai1ec_event',
                'delete_posts'            => 'delete_ai1ec_events',
                'delete_others_posts'     => 'delete_others_ai1ec_events',
                'delete_published_posts'  => 'delete_published_ai1ec_events',
                'delete_private_posts'    => 'delete_private_ai1ec_events',
                'publish_posts'           => 'publish_ai1ec_events',
                'read_private_posts'      => 'read_private_ai1ec_events' ),
            'has_archive' => true,
            'hierarchical' => false,
            'menu_position' => 5,
            'supports' => $supports,
            'exclude_from_search' => $ai1ec_settings->exclude_from_search,
        );

        // register the post type with our new settings
        register_post_type( AI1EC_POST_TYPE, $args );

    endif;


}