9

i am getting a weird error - white screen in the list of posts
for a specific Custom post type (just for that one)

  • tried deactivating all the plugins
  • tried checking for error (debugging = true)

Still nothing
the page just doesnt echos anything... (nothing in source too)

I am talking about such a url in the admin:
http://www.example.co.il/wp-admin/edit.php?post_type=submodelscpt

Here is register_post_type part i am using:

function register_submodelcpt() {
    $labels = array(
        'name'                  => __('Sub Models', THEME_NAME),
        'singular_name'         => __('Sub Models', THEME_NAME),
        'add_new'               => __('New Model', THEME_NAME),
        'add_new_item'          => __('Add new Model', THEME_NAME),
        'edit_item'             => __('Edit Model', THEME_NAME),
        'new_item'              => __('New Model', THEME_NAME),
        'all_items'             => __('All Sub Models', THEME_NAME),
        'view_item'             => __('Watch Model', THEME_NAME),
        'search_items'          => __('Search Models', THEME_NAME),
        'not_found'             =>  __('No Models found', THEME_NAME),
        'not_found_in_trash'    => __('No Models found in trash', THEME_NAME), 
        'parent_item_colon'     => '',
        'menu_name'             => __('Sub Models', THEME_NAME),

    );

    $args = array(
        'labels'                => $labels,
        'public'                => true,
        'publicly_queryable'    => true,
        'show_ui'               => true, 
        'show_in_menu'          => true, 
        'query_var'             => true,
        'rewrite'               => array('slug' => 'submodels'),
        'capability_type'       => 'post',
        'has_archive'           => true, 
        'hierarchical'          => true,
        'menu_position'         => 5,
        'menu_icon'             => get_stylesheet_directory_uri().'/images/cpt/subcars.png',            
        'supports'              => array('title', 'thumbnail', 'revisions', 'page-attributes')
    ); 
    register_post_type('submodelscpt',$args);
}
add_action('init', 'register_submodelcpt');

Did anyone encounter such an issuse?
can you think of a reason this might happen?

Another weird thing
when i change this:
http://www.example.co.il/wp-admin/edit.php?post_type=submodelscpt

To this:
http://www.example.co.il/wp-admin/edit.php?post_type=submodelscpt&orderby=date&order=desc

The posts list loads correctly...

7
  • 1
    there's nothing in your included code that would cause this, verify you don't have something interfering with queries- pre_get_posts, query filters, etc..
    – Milo
    Nov 26, 2014 at 19:39
  • thanks milo... searched for pre_get_posts across files and couldnt find anything - this is weird! ;<( thanks for trying to help.
    – Sagive
    Nov 26, 2014 at 19:58
  • Agree with @Milo, must be something acting on query. Note that there are tons of filter that act on query, not only pre_get_posts. However, if your debug is active and you get white screen with no errors I think there must be an exit or a die, try to search for them.
    – gmazzap
    Nov 26, 2014 at 21:25
  • thats a gr8 idea! will do G.M thanks for your input
    – Sagive
    Nov 28, 2014 at 17:36
  • Any progress on this? Having the same issue.
    – Nic
    Feb 18, 2015 at 1:21

4 Answers 4

8

This is to extend your own answer:

It appears that when "hierarchical" is set to true, each post behaves like a page. I am quoting here so I don't really understand why it matters but changing this line remove the problem.

Here is what the codex says about the hierarchical parameter

hierarchical

(boolean) (optional) Whether the post type is hierarchical (e.g. page). Allows Parent to be specified. The 'supports' parameter should contain 'page-attributes' to show the parent select box on the editor page.

Default: false

Note: this parameter was planned for Pages. Be careful, when choosing it for your custom post type - if you are planning to have many entries (say - over 100), you will run into memory issue. With this parameter set to true WordPress will fetch all entries of that particular post type, together with all meta data, on each administration page load for your post type.

When a custom post type is set as hierarchichal, its behavior will be same as the build in post type page. Like pages, Wordpress tries to build a tree to display the correct hierarchical tree with parent-child relationships in the back end. As you might have noticed, pages are not sorted by date in the back end, but by this parent-child relationship. This behavior you can easily see when visiting the Page page in back end.

This operation is very expensive as Wordpress needs to get each page ( or post from a hierarchical post type ) on every page load and then look for that specific page's/post's parent and child pages to build a the correct tree for that specific page/post. If you have a large amount of pages or posts in your hierarchical custom post type, the query simply becomes to big and exceeds memory limits or times out, which leads to a fatal error, hence the WSOD.

Non-hierarchical post types like the build in post type post don't have such a hierarchy as non-hierarchical post type posts can't have child posts. Because there is no need to build a parent-child relationship tree (for obvious reasons), Wordpress simply queries 20 (IIRC) posts per page ordered by date in the back end and displays them in contrast to hierarchical post type posts where Wordpress has to query all posts at once, build a tree and then display only an x amount on a posts grouped according to their parent-child relationship. You can check this behavior in the Post page in the back end

So setting a custom post type to hierarchical tells Wordpress that it should build a list/tree of posts grouped by their parent-child relationship and return those posts in that configuration. Setting a custom post type to non-hierarchical, you are telling Wordpress to skip the whole relationship thing and to just return an x amount of posts per page ordered by post date

I hope this make a bit more sense to you why you should avoid making custom post types hierarchical, and why that is also stated in the codex

2
  • very cool @pietergoosen thanks a lot for sharing - i hate just doing without the why ;)
    – Sagive
    May 9, 2015 at 22:43
  • My pleasure. Ejoy :-) May 10, 2015 at 3:25
7

I just want to add to the answers by @SagiveSEO and @PieterGoosen.

There's also a potential performance killer regarding the hierarchial post types:

Namely the parent page dropdown box that uses wp_dropdown_pages().

It's currently very unefficent as it loads (almost) all the pages into the select dropdown box.

So if we have a site with many pages, then this can hurt performance.

Just imagine a site with 1 million pages ;-)

This was reported 6 years ago with the ticket #9864. It's still open so you can still contribute to the proposed auto-complete solution.

Update:

I just wanted to mention some helpful filters:

  • wp_dropdown_pages -- a output filter for the wp_dropdown_pages() function. Might be used to append or echo some extra HTML if needed.
  • get_pages -- because wp_dropdown_pages() calls the get_pages() function.
  • page_attributes_dropdown_pages_args -- a filter for the arguments to wp_dropdown_pages() on the post.php/post-new.php screens for hierarchical post types.
  • quick_edit_dropdown_pages_args -- a filter for the argument to wp_dropdown_pages() on the edit.php screens for hierararchical post types.

that could be used to address the problem.

It's possible to modify the output of wp_dropdown_pages() on the post.php screen with:

add_filter( 'page_attributes_dropdown_pages_args', function( $dropdown_args, $post )
{
    if( 'page' === $post->post_type )
    {
        $dropdown_args['number']       = 10; // Limit the number of pages
        $dropdown_args['hierarchical'] = 0;  // Keep it non-hierarchical 
        $dropdown_args['offset']       = 1;  // Ideal for pagination
    }
    return $dropdown_args;
}, 10, 2 );

and similarly for the edit.php screen for pages:

add_filter( 'quick_edit_dropdown_pages_args', function( $dropdown_args )
{
    $screen = get_current_screen();
    if( 'edit-page' === $screen->id )
    {
        $dropdown_args['number']       = 10; // Limit the number of pages
        $dropdown_args['hierarchical'] = 0;  // Keep it non-hierarchical
        $dropdown_args['offset']        = 1;  // Suitable for pagination
    }
    return $dropdown_args;
} );

Note that the second input argument ($post) is not available for this filter callback.

It's of course possible to just remove the page attributes support:

add_action( 'init', function()
{
    remove_post_type_support( $post_type = 'page', 'page-attributes' );

} );

but then we might as well just use a non-hierarchical post type instead ;-)

List parents with ajax pagination?

It should be possible, with the help of the above filters, to create a paginated (non-hierarchical) list of parents, that would be updated via ajax. Maybe the select box options could be updated, to keep the current layout. This would probably? be a different approach than the suggested (on core trac) parent search box, with auto completion.

10
  • Thanks for that info. Something to look into in near future ;-) May 8, 2015 at 10:52
  • I just discovered this few weeks ago, when I got to work on an install with few thousand pages. I was surprised to see that the parent page dropdown box had thousands of options ;-) This is also part of the Quick Edit in the edit.php screen @PieterGoosen
    – birgire
    May 8, 2015 at 10:57
  • 1
    yes and with the current core state I wouldn't recommend using more than ~100 pages, unless you got a good server => we just have to find a way to use non hierarchial posts instead of pages for large number of items ;-)
    – birgire
    May 8, 2015 at 11:08
  • 2
    maybe if the backend would keep all the objects in memory and only sync with the database through some clever "diff" ;-) I think one proposed solution to the wp_dropdown_pages() problem, is to use a search text box with an ajax auto completion instead of the current dropdown box, when the number of pages are "large". @PieterGoosen
    – birgire
    May 8, 2015 at 13:01
  • 1
    @ialocin anything informative is appreciated, even philosophical views ;-) Aug 21, 2015 at 7:33
3

Ok... for anyone visiting this post - i have found the solution...
i actually encountered this issues again (when a site has a lot of pages)

The issue is this line when registering a custom post type:

'hierarchical'          => true,

All you need to do is to change it to false!

'hierarchical'          => false,

Explenation:
It appears that when "hierarchical" is set to true, each post behaves like a page. I am quoting here so I don't really understand why it matters but changing this line remove the problem.

-1

Here is a full example from wordpress codex

add_action( 'init', 'codex_book_init' );
function codex_book_init() {
$labels = array(
    'name'               => _x( 'Books', 'post type general name', 'your-plugin-textdomain' ),
    'singular_name'      => _x( 'Book', 'post type singular name', 'your-plugin-textdomain' ),
    'menu_name'          => _x( 'Books', 'admin menu', 'your-plugin-textdomain' ),
    'name_admin_bar'     => _x( 'Book', 'add new on admin bar', 'your-plugin-textdomain' ),
    'add_new'            => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
    'add_new_item'       => __( 'Add New Book', 'your-plugin-textdomain' ),
    'new_item'           => __( 'New Book', 'your-plugin-textdomain' ),
    'edit_item'          => __( 'Edit Book', 'your-plugin-textdomain' ),
    'view_item'          => __( 'View Book', 'your-plugin-textdomain' ),
    'all_items'          => __( 'All Books', 'your-plugin-textdomain' ),
    'search_items'       => __( 'Search Books', 'your-plugin-textdomain' ),
    'parent_item_colon'  => __( 'Parent Books:', 'your-plugin-textdomain' ),
    'not_found'          => __( 'No books found.', 'your-plugin-textdomain' ),
    'not_found_in_trash' => __( 'No books found in Trash.', 'your-plugin-textdomain' )
);

$args = array(
    'labels'             => $labels,
    'public'             => true,
    'publicly_queryable' => true,
    'show_ui'            => true,
    'show_in_menu'       => true,
    'query_var'          => true,
    'rewrite'            => array( 'slug' => 'book' ),
    'capability_type'    => 'post',
    'has_archive'        => true,
    'hierarchical'       => false,
    'menu_position'      => null,
    'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
);

register_post_type( 'book', $args );
}
2
  • whats up with the copy and paste? why did you paste this code here?
    – Sagive
    Nov 26, 2014 at 19:56
  • Sorry dint see your code i was checking it from adroid app but dont know why it hides the content sometime and sometime it strech it very anoing
    – emilushi
    Nov 26, 2014 at 21:21

Your Answer

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

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