Routing to callback functions in WordPress – 06

I’ve sorted the options available to add an admin interface possibility of routes added using WP Router and decided to go with the easier option of using a page post-type metabox.
That would allow plugins and enhancements that work on pages and their meta information to keep working and allow an easy addition of pages to navigation menus.

The master plan

The idea is to persist routes and some meta information about them in the database to be able to later fetch that information and generate ad-hoc permalinks while allowing a user to choose which content a page should display: either the page content itself or the result of a route endpoint.

The end point of the struggle is to be able to generate the correct permalink to the route when adding a page and choosing it to be a route placeholder; sure WordPress comes with the possibility to edit the permalink [caption id=“attachment_1061” align=“aligncenter” width=“1024”]Generated permalink Generated permalink[/caption] [caption id=“attachment_1062” align=“aligncenter” width=“1024”]Cusotm made permalink Cusotm made permalink[/caption] but while I’d like to leave the user that possibility I’d also like to be able control the permalink generation altogether for a smoothest experience.

Digging for hooks

How does WordPress generates the page permalink? After some code digging I’ve found out it does in two distinct points relying but on the same functions; when the page is first rendered PHP will take care of populating the “Permalink” field using code defined in the /wp-admin/edit-form-advanced.php file at about line 449

$sample_permalink_html = $post_type_object->public ? get_sample_permalink_html($post->ID) : '';
$shortlink = wp_get_shortlink($post->ID, 'post');
$permalink = get_permalink( $post->ID );
if ( !empty( $shortlink ) && $shortlink !== $permalink && $permalink !== home_url('?page_id=' . $post->ID) )
    $sample_permalink_html .= '<input id="shortlink" type="hidden" value="' . esc_attr($shortlink) . '" /><a href="#" class="button button-small" onclick="prompt(&#39;URL:&#39;, jQuery(\'#shortlink\').val()); return false;">' . __('Get Shortlink') . '</a>';

if ( $post_type_object->public && ! ( 'pending' == get_post_status( $post ) && !current_user_can( $post_type_object->cap->publish_posts ) ) ) {
    $has_sample_permalink = $sample_permalink_html && 'auto-draft' != $post->post_status;
    <div id="edit-slug-box" class="hide-if-no-js">
        if ( $has_sample_permalink )
            echo $sample_permalink_html;
wp_nonce_field( 'samplepermalink', 'samplepermalinknonce', false );

after some code reading I get that the get_permalink function will be used to generate the permalink to the page or post if the page or post is not a newly created one; in that case WordPress will trigger an AJAX call to generate a temporary permalink taking the page title into account. Again in code that is defined in the /wp-admin/js/post.js file at line 316

}).on( 'after-autosave.update-post-slug', function() {
    // Create slug area only if not already there
    // and the title field was not focused (user was not typing a title) when autosave ran
    if ( ! $('#edit-slug-box > *').length && ! titleHasFocus ) {
        $.post( ajaxurl, {
                action: 'sample-permalink',
                post_id: $('#post_ID').val(),
                new_title: $('#title').val(),
                samplepermalinknonce: $('#samplepermalinknonce').val()
            function( data ) {
                if ( data != '-1' ) {

and the callback function answering to that AJAX call is defined in the /wp-admin/includes/ajax-actions.php file

function wp_ajax_get_permalink() {
    check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
    $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
    wp_die( add_query_arg( array( 'preview' => 'true' ), get_permalink( $post_id ) ) );

and it’s, once again, get_permalink.


I will probably tap into the pre_post_link and post_link filters defined into the get_permalink function to be able to work some magic on the permalink generation to suit my needs.