0

I'm rendering a list of posts in a CPT (child for this example) inside the edit page for another CPT (parent) to establish a hierarchy. In the listing, I have links to edit and delete each child and a link to add a new one. I am looking to add some logic so that if you come to the edit page for a child via the listing, you get redirected back to the respective parent screen. However, if the user reaches the edit page for the child in any other way (such as through the standard admin interface for Children), it should fallback to the normal behavior ("reload" on save, go to listing on delete). My first attempt at accomplishing this was via a query string.

Parent's Listing:

<?php
    function render_children_table($post) {
        $post_id = $post->ID;

        $screen = get_current_screen();
        if ('parent' !== $post->post_type || $screen->action === 'add') {
            return;
        }

        $children = get_child_posts($post_id); // custom function

        ?>
        <br>
        <table>
            <thead>
                <tr>
                    <td>Title</td>
                    <td></td>
                    <td></td>
                </tr>
            </thead>
            <tbody>
                <?php foreach ($children as $child) :
                    $delete_url = sprintf(admin_url('edit.php?post=%s&action=%s&return=parent'), $child->ID, 'trash', $post_id);
                    $complete_delete_url = wp_nonce_url($delete_url, 'trash-post_' . $child->ID);
                    $edit_url = sprintf(admin_url('edit.php?post=%s&action=%s&return=parent'), $child->ID, 'edit', $post_id);

                    ?>
                    <tr>
                        <td><?= $child->post_title ?></td>
                        <td>
                            <a href="<?= $edit_url ?>">Edit</a>
                        </td>
                        <td>
                            <a href="<?= $complete_delete_url ?>">Trash</a>
                        </td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
        <br>
        <a class="button button-primary" href="<?= admin_url('post-new.php?post_type=child&return=parent&parent=' . $post->ID) ?>">
            Add Child
        </a>

        <?php
    }

Register Child Post Type:

<?php
    function register_child_post_type() {
        register_post_type('child',
            array(
                // removed for brevity
            )
        );

        add_action('save_post', 'redirect_on_child_saved');
    }

    function redirect_on_child_saved() {
        global $post;

        if ($post->post_type != 'child') return;

        $parent_id = get_value_of_parent_field(); // custom function
        $return = $_GET['return']; // this is always empty because query is not passed

        if ($return == 'parent') {
            wp_redirect(admin_url('post.php?post=' . $parent_id . '&action=edit&message=1'));
            exit();
        }
    }

I have confirmed that the redirect itself works the way I want it to. Since the query string is not passed to the update action, what's another way to implement this behavior?

Your Answer

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

Browse other questions tagged or ask your own question.