0

I am making a custom Pages screen to display all of my published pages.

I started with Matt Van Andel's excellent Custom List Table Example that works with WP_List_Table.

Each item looks something like this:

array(
  'id'   => 1,
  'page' => 'page1',
  'url'  => 'page1'
) 

Some of my pages have alternate content stored in postmetas. For the pages that have this, I want them to force a row beneath the main row so let's say page 2 has such data what I want is where the 2 alternate items are grouped with page 2:

id page url   alt-id alt-title
1 page1 page1
2 page2 page2 
              1      alternate-title-1
              2      alternate-title-2
3 page3 page3

I can get the $items array to look like this

array(
  'id'         => 2,
  'page'       => 'page2',
  'url'        => 'page2',
  'variations' => array( 
                    array(
                      alt-id   => 2,
                      alt-title=> 'alternate-title-2',
                    ),
                    array(
                      alt-id   => 3,
                      alt-title=> 'alternate-title-3',
                    )
                  )
 ) 

How do I force a row like this, so that items with a 'variations' array will display their data below their own row?

Do I need to make my own function that's similar to this? https://developer.wordpress.org/reference/classes/wp_list_table/display/

Maybe I use this to display multiple rows if necessary? https://developer.wordpress.org/reference/classes/wp_list_table/display_rows/

But how can I get my WP_List_Table class to call display_rows_alternate instead?

1 Answer 1

1

My recommendation is to structure the array so that your variations become "regular rows".

I would use your implementation of prepare_items for that.

Here your array is changed to something like that:

    $this->items = array(
        array(
            'id'         => 2,
            'page'       => 'page2',
            'url'        => 'page2',
            'alt-id'     => null,
            'alt-title'  => null
        ),
        array(
            'id'         => null,
            'page'       => null,
            'url'        => null,
            'alt-id'     => 2,
            'alt-title'  => 'alternate-title-2'
        ),
        array(
            'id'         => null,
            'page'       => null,
            'url'        => null,
            'alt-id'     => 3,
            'alt-title'  => 'alternate-title-3'
        )
    );

Then I would define custom functions for all columns by using column_$custom( $item ) (docs: https://developer.wordpress.org/reference/classes/wp_list_table/).

Something like that:

function column_id($item){
    return is_null($item['id']) ? '' : intval($item['id']);
}

function column_page($item){
    return is_null($item['page']) ? '' : esc_html($item['page']);
}

function column_url($item){
    return is_null($item['url']) ? '' : esc_html($item['url']);
}

function column_alt_id($item){
    return is_null($item['alt-id']) ? '' : intval($item['alt-id']);
}

function column_alt_title($item){
    return is_null($item['alternate-title-3']) ? '' : esc_html($item['alternate-title-3']);
}

I assume you have already defined your columns with get_columns like that (or similar):

function get_columns() {
    return array(
        'id'        => 'ID',
        'page'      => 'Page',
        'url'       => 'URL',
        'alt_id'    => 'Alternative ID',
        'alt_title' => 'Alternative Title',
    );
}

This is key because your WP_List_Table subclass needs to know that you want to call your custom column methods (e.g. column_alt_title as shown above).

1
  • This will work really well, thanks for the advice!
    – pg.
    Commented Jun 19, 2023 at 20:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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