All in One Event Calendar WordPress custom permalink slug and archive

Modify the permalink slug and archive URL for the All in one Event Calendar WordPress plugin without hacking at it's core files. A simple ai1ec rewrite.


I’ve been working with the All in One Event Calendar WordPress plugin for The WP Conf and am really liking the setup and ease of use. But being a programer I was a bit elated when browsing the code and found no actionable hooks or filters.

For example, the plugin generates an event post_type called “ai1ec_event“. While the post_type name doesn’t matter, and that is great that it won’t conflict with other event plugins or custom post types that might be named event it doesn’t allow a user to generate a custom permalink slug. With that being said, one would be left with a URL like: That is not SEO friendly or pretty to look at. I would prefer /session/ or /event/.

If ai1ec added a filter to their code then someone with a bit of coding skills would be able to modify it with out hacking at the core files worried about auto-updates overwriting everything.

A simple filter – solution and/or core hack

apply_filters would be a simple solution that the devs could do and would not take more that a few seconds and one line of code to do. I read a few support requests where they mentioned adding this option into the settings, but (later removing it?). That’s a lot more code and might be more of a hassle. Why not just add this to your code in the file app/helper/class-ai1ec-app-helper.php:309.

register_post_type( AI1EC_POST_TYPE, apply_filters( 'ai1ec_event_post_type_args', $args ) );

Our options with out a core hack

The above solution is really for For our needs we have to add some semi-hacky-code. I found this solution on WordPress Stackexchange which works like a charm.

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.

add_action( 'init', 'ai1ec_post_type_init', 99 );

function ai1ec_post_type_init() {
	if ( function_exists( 'ai1ec_initiate_constants' ) && 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 ] );
		$labels = array(
			'name'               	=> _x( 'Sessions', 'Custom post type name', AI1EC_PLUGIN_NAME ),
			'singular_name'      	=> _x( 'Session', 'Custom post type name (singular)', AI1EC_PLUGIN_NAME ),
			'add_new'            	=> __( 'Add New', AI1EC_PLUGIN_NAME ),
			'add_new_item'       	=> __( 'Add New Session', AI1EC_PLUGIN_NAME ),
			'edit_item'          	=> __( 'Edit Session', AI1EC_PLUGIN_NAME ),
			'new_item'           	=> __( 'New Session', AI1EC_PLUGIN_NAME ),
			'view_item'          	=> __( 'View Session', AI1EC_PLUGIN_NAME ),
			'search_items'       	=> __( 'Search Sessions', AI1EC_PLUGIN_NAME ),
			'not_found'          	=> __( 'No Sessions found', AI1EC_PLUGIN_NAME ),
			'not_found_in_trash' 	=> __( 'No Sessions found in Trash', AI1EC_PLUGIN_NAME ),
			'parent_item_colon'  	=> __( 'Parent Session', AI1EC_PLUGIN_NAME ),
			'menu_name'          	=> __( 'Sessions', AI1EC_PLUGIN_NAME ),
			'all_items'          	=> $ai1ec_app_helper->get_all_items_name(),
		$supports = array( 'title', 'editor', 'comments', 'custom-fields', 'thumbnail' );
		$args = array(
			'labels'				=> $labels,
			'public' 				=> true,
			'publicly_queryable' 	=> true,
			'show_ui' 				=> true,
			'show_in_menu' 			=> true,
			'query_var' 			=> true,
            'rewrite' 				=> array( 'slug' => 'session', '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' 			=> true,
			'menu_position' 		=> 5,
			'supports'				=> $supports,
			'exclude_from_search' 	=> $ai1ec_settings->exclude_from_search,
		register_post_type( AI1EC_POST_TYPE, $args );
	endif; // AI1EC_POST_TYPE // ai1ec_initiate_constants()

Add the following into your themes functions.php file, or better yet into your site’s functionality plugin file. That’s it. Just be sure to change the $labels to suite your needs.

Default image
πŸ’πŸ½β€β™‚οΈ Husband to Jeana. ⚾️ Dodgers obsessed. πŸ† World Series Champs. πŸ’» Senior WordPress engineer @ Beachbody. πŸŒπŸΌβ€β™‚οΈScratch golfer. 🌱 Hydroponic Gardner. 🍿 Plex nerd. πŸš™ '15 WRX & '66 Corvette C2. 🐢 Missing my love Keiki; RIP 😒. Follow me on Twitter @TheFrosty & Instagram @TheFrosty.
Articles: 285


  1. Omg, thank you so much for this! πŸ™‚

  2. Hi!

    First off all, thank you for sharing! However, I’ve tried your code adding it to my child theme function.php: the URL definitely looks much better, but I get a 404 error πŸ™

    Any clue about it?
    Thank you in advance…

Leave a Reply

%d bloggers like this: