WordPress.org

Ready to get started?Download WordPress

Forums

Public attribute for register_post_type() (11 posts)

  1. fireproofsocks
    Member
    Posted 2 years ago #

    Using the register_post_type() function, I've found that the "public" attribute does not work as expected. The docs say that the "public" attribute is optional and it is shorthand for the following:

    publicly_queriable = true;
    show_ui = true;
    show_in_nav_menus = true;
    exclude_from_search = false;

    But if you set the above arguments verbosely, then using the get_post_types() function to search for public post-types does not return any results. This seems like a bad WP flaw... it means that the public option is NOT shorthand for the above arguments. WP does NOT treat them the same.

    Anyone run into this? Am I correct in my diagnosis of this?

  2. Big Bagel
    Member
    Posted 2 years ago #

    Looking at the code for register_post_type(), the public argument is only used when those other arguments aren't defined and has no other purpose. get_post_types() without any arguments should always return something as there are several built-in post-types. How and where are you calling these functions?

  3. fireproofsocks
    Member
    Posted 2 years ago #

    I'm calling the get_post_type() function with arguments... usually like this:

    $pts = get_post_types( array('public'=>true, '_builtin'=>false) );

    That query will not return any custom post-types if you defined them using the arguments above, e.g.

    $args = array(
       'publicly_queriable' = true,
       'show_ui' = true,
       'show_in_nav_menus'  = true,
       'exclude_from_search = false
    );
    register_post_type('my_custom_post_type', $args);
    
    $pts = get_post_types( array('public'=>true, '_builtin'=>false) );
    
    print_r($pts); // <-- empty!

    The behavior above is not what I would expect. I would expect the verbose equivalent of the $public argument to yield the same results.

    One of the big problems with the register_post_type() function is that it expects literal values, e.g. a literal true, a literal false, or a literal null. This makes coding a web form for that function particularly troublesome... if your web form uses checkboxes, for example, you have to convert the checked value to a literal boolean or the register_post_type() function won't work as expected. It's a similar situation with the $show_in_menu argument which behaves differently depending on whether a boolean or a string was passed. It's not a good idea to have function inputs like that because it requires a whole other layer of code to translate them. LOTS of WordPress functions do this sort of thing, unfortunately.

    So the problem occurs when those other arguments are defined. WordPress will set the values of those properties based on the value of the $public argument, but it also needs to do the opposite: if the $public argument isn't included, WP needs to set the value of the $public argument based on the verbose equivalents. For now I'm having to pass the $public argument along with the rest because the get_post_types() function doesn't recognize the equivalence.

  4. Big Bagel
    Member
    Posted 2 years ago #

    Do this instead to test if your post-type is even being registered:

    $pts = get_post_types( array( '_builtin' => false ) );
    print_r( $pts );

    register_post_type() won't work at all if it's called too early or too late. init is a good place to hook it to.

    ...register_post_type() function is that it expects literal values, e.g. a literal true, a literal false, or a literal null. This makes coding a web form for that function particularly troublesome...

    The output of any form input shouldn't be thrown into a function without validation anyways. I don't see the problem:

    $public = ( isset( $checked ) ) ? true : false;

    The way it is currently constructed reduces the chances of people using vague code with potentially unexpected results.

  5. fireproofsocks
    Member
    Posted 2 years ago #

    I'm hooking into the correct places -- the post types are being registered, used throughout the site etc. That's not the problem.

    The problem is that OTHER PLUGINS are searching for the $public argument when they use the get_post_types() function, and if I verbosely use the arguments defined above instead of the public argument, my post-types are not returned. I can work around this in my code, but I can't expect other plugin authors to do the same. The pieces don't fit together because of how WP has implemented this function. So I believe that it's a bug, and I'll file it.

    As a side note, try coding some HTML forms to pass inputs to WP functions and compare the amount of work and debugging to coding forms for other CMS's and you'll see that WP requires a lot more work due to do the same thing. Even writing the documentation for functions that have variable inputs like that (e.g. boolean OR string OR array) gets really really messy and it's no accident that you'd be hard pressed to find examples of functions with similar degrees of variation in their inputs in any language or framework. There is a good reason that it is not often done. Typecasting offers some improvement, e.g.

    $public = (bool) $checked;

    But that doesn't get around the difficulties you encounter when an input requires a literal boolean or a string, for example.

  6. fireproofsocks
    Member
    Posted 2 years ago #

  7. Big Bagel
    Member
    Posted 2 years ago #

    It's a problem with the documentation not the code. The public argument is not just shorthand for the other four arguments; it can act as such if they aren't set themselves, but it is also saved and it can be used as an argument with get_post_types(). Just set public to something in addition to the other four.

    As a side note, try coding some HTML forms to pass inputs to WP functions and compare the amount of work and debugging to coding forms for other CMS's...

    I have. Checking variable types in addition to values is a choice not a bug. There are both benefits and issues with this.

    Edit:
    The public argument is by default set to false. This:

    $args = array(
        'publicly_queriable' => true,
        'show_ui' => true,
        'show_in_nav_menus' => true,
        'exclude_from_search' => false
    );
    register_post_type( 'my_custom_post_type', $args );

    is the same as this:

    $args = array(
        'public' => false,
        'publicly_queriable' => true,
        'show_ui' => true,
        'show_in_nav_menus' => true,
        'exclude_from_search' => false
    );
    register_post_type( 'my_custom_post_type', $args );

    Which obviously makes this return nothing, since it's specifically checking for what public is set to:

    $pts = get_post_types( array( 'public'=>true, '_builtin'=>false ) );

    What you're seeing is not a bug.

    To do what you're looking to do, use:

    $args = array(
        'public' => true,
    );
    register_post_type( 'my_custom_post_type', $args );

    or, if you really want to:

    $args = array(
        'public' => true,
        'publicly_queriable' => true,
        'show_ui' => true,
        'show_in_nav_menus'  => true,
        'exclude_from_search' => false
    );
    register_post_type( 'my_custom_post_type', $args );
  8. fireproofsocks
    Member
    Posted 2 years ago #

    I think the code is implemented incorrectly and the documentation is inaccurate. If the other inputs can be inferred from the $public argument, then the $public argument should be inferred from the other arguments so that the get_post_types() won't fail unexpectedly.

  9. Big Bagel
    Member
    Posted 2 years ago #

    The other inputs are inferred from the public argument only if they aren't specifically defined. This is necessary. public is completely separate otherwise. Again, it is intentional and not a bug. get_post_types() does not fail unexpectedly, you just expected it to work in a case that it shouldn't based on vague documentation.

  10. fireproofsocks
    Member
    Posted 2 years ago #

    I stand by my bug report. We'll see how it's handled. In the meantime, I'm gonna update the docs so other users won't unexpectedly run into the same issues.

  11. maxemil
    Member
    Posted 2 years ago #

    hmz.. I had a comment, but I then realized it was my fault :p
    theres a delete button missing in this forum.

Topic Closed

This topic has been closed to new replies.

About this Topic