You can add custom url structures with add_rewrite_rule
for example the proposed structure in your question can be achieved with something like...
add_action( 'init', function() {
add_rewrite_rule( '^jobs/([^/]+)/edit/?$', 'index.php?post_type=jobs&name=$matches[1]', 'top' );
} );
So now if you visited https://example.com/jobs/job-title-example/edit/
you should see exactly the same as if you were to visit https://example.com/jobs/job-title-example/
this is because we're telling WordPress to handle the request in a similar way by passing the post_type
and name
as query parameters. Essentially the same as visiting https://example.com/?post_type=jobs&name=job-title-example
.
However, it might be a good idea to build the rewrite rule dynamically based off of the post type properties, something like...
add_action( 'init', function() {
if ( $post_type = get_post_type_object( 'job' ) ) {
$rewrite = !empty( $post_type->rewrite ) && is_array( $post_type->rewrite ) ? $post_type->rewrite : [];
$with_front = !empty( $rewrite[ 'with_front' ] ) ? $rewrite[ 'with_front' ] : false;
$slug = !empty( $rewrite[ 'slug' ] ) ? $rewrite[ 'slug' ] : null;
$slug = $slug ?: $post_type->name;
$front = '';
if ( $with_front ) {
$permalink_structure = get_option( 'permalink_structure' );
$front = substr( $permalink_structure, 0, strpos( $permalink_structure, '%' ) );
}
$slug = $front ? '/' . $slug : $slug;
add_rewrite_rule( '^' . $front . $slug . '/([^/]+)/edit/?$', 'index.php?post_type=' . $post_type->name . '&name=$matches[1]', 'top' );
}
}, PHP_INT_MAX );
So now if you change your jobs
post type rewrite properties the rewrite rule above will adapt automatically.
Always remember to flush your rewrite rules if making any changes.
I would also concider adding a custom query var to use in templates, like so...
add_filter( 'query_vars', function( $vars ) {
$vars[] = 'frontend_editor';
return $vars;
} );
And add to your rewrite rule with &frontend_editor=1
like so...
add_action( 'init', function() {
if ( $post_type = get_post_type_object( 'job' ) ) {
$rewrite = !empty( $post_type->rewrite ) && is_array( $post_type->rewrite ) ? $post_type->rewrite : [];
$with_front = !empty( $rewrite[ 'with_front' ] ) ? $rewrite[ 'with_front' ] : false;
$slug = !empty( $rewrite[ 'slug' ] ) ? $rewrite[ 'slug' ] : null;
$slug = $slug ?: $post_type->name;
$front = '';
if ( $with_front ) {
$permalink_structure = get_option( 'permalink_structure' );
$front = substr( $permalink_structure, 0, strpos( $permalink_structure, '%' ) );
}
$slug = $front ? '/' . $slug : $slug;
// We added `frontend_editor` parameter here.
add_rewrite_rule( '^' . $front . $slug . '/([^/]+)/edit/?$', 'index.php?post_type=' . $post_type->name . '&name=$matches[1]&frontend_editor=1', 'top' );
}
}, PHP_INT_MAX );
This is essentially the same as visiting:
https://example.com/jobs/job-title-example/?frontend_editor=1
Or
https://example.com/?post_type=jobs&name=job-title-example&frontend_editor=1
In theory you should now be able to update your template to show the editor, for example...
single-jobs.php
<?php get_header(); ?>
<!-- Check if user is authorised to edit current job -->
<?php if ( is_user_logged_in() && (int)get_post_field( 'post_author', get_the_ID() ) === get_current_user_id() ): ?>
<!-- Check for our edit parameter -->
<?php if ( get_query_var( 'frontend_editor', false ) ): ?>
<form action="">
...
</form>
<?php endif ?>
<?php endif ?>
<?php get_footer(); ?>
I think that should be enough to point you in the right direction. Please note that none of the above code has been tested!