0

I have created a custom post type nammed job. The users will have the posibility to create/read/update/delete their posts from frontend. I created a shortcode with a form for post creating, which is working fine, the jobs are adding and they can be accesed on the generic url site_domain/jobs/job_title.

Now I want to implement the job edit page which will be available on the previous url with /edit/ concatenated, like site_domain/jobs/job_title/edit/.

How can i create another page template/shortcode which will be used only if the user is accessing this endpoint ?

2
  • are you asking how to have /edit on the end and load a template? Or are you asking how to create the editor shortcode? The first probably needs a rewrite rule and a filter for the edit link if you want to redirect WP Admin to this new page as well
    – Tom J Nowell
    Oct 7 at 11:15
  • Yes, I want to have a /edit page on which the author of the job could edit it. I know how to create the editor, it is similar to job creating page ... I was thinking it would be more logical to edit the post by accesing the /edit page and in the backend I could scrap the post name and populate the fields with data from database Oct 7 at 12:02
0

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!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.