Opened 13 years ago
Last modified 10 months ago
#19958 accepted enhancement
Allow custom post types as "home" and get_posts() to return results for more than one post type
Reported by: | sooskriszta | Owned by: | pbearne |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | 3.3.1 |
Component: | Posts, Post Types | Keywords: | needs-testing needs-design has-patch has-screenshots |
Focuses: | accessibility, administration | Cc: |
Description
In
Wordpress admin > Settings > Reading
there is an option to define what the home page or the front page should be
Front page displays
Radio button
A static page (select below)
is followed by a dropdown containing a list of all pages.
I would request that custom page types be allowed in this dropdown. This way, I could make my bbPress forums or my All-in-one event calendar, etc my homepage.
Attachments (5)
Change History (56)
#1
@
12 years ago
- Cc pbearne@… added
- Severity changed from normal to major
- Type changed from enhancement to defect (bug)
#3
@
12 years ago
- Cc jarrod@… added
What about instead putting a filter on the arguments for the wp_dropdown_pages call that produces the list of pages to choose from (line 96 in wp-admin/options-reading.php)? A developer could then use :
function filter_my_cpt($args) { $args[post_type] = 'cpt-slug';[[BR]] //to also maintain pages: $args[post_type] = 'pages, cpt-slug' } add_filter('options-front-page' , filter_my_cpt'); add_filter('options-posts-page' , filter_my_cpt');
#4
@
12 years ago
Yes feels that it would work
wp_dropdown_pages() call's get_pages() just passing the args through and get_pages() takes in post_type
And if we update the custom post/page type page to inform how to add this
I don't see the need to add it to the posts page as this is just a place holder so remove that from the code.
Added (untested) code to make the filter work with any number of filters so that this call can be part of custom post/page type page setups.
function filter_my_cpt($args) { // pass through current value if any to allow for other filters if(count($args[post_type])>0){ $args[post_type] = array_push($args[post_type],'cpt-slug'); }else{ $args[post_type] = 'cpt-slug'; } } add_filter('options-front-page' , filter_my_cpt');
so the change to options-reading.php would just a filter around the front page $args array
I that feel we should break this out a bit to make readable but this looks like the code we need.
117<ul> <li><label for="page_on_front"><?php printf( __( 'Front page: %s' ), wp_dropdown_pages(apply_filters('options-front-page', array( 'name' => 'page_on_front', 'echo' => 0, 'show_option_none' => __( '— Select —' ), 'option_none_value' => '0', 'selected' => get_option( 'page_on_front' ) ) ) ) ); ?></label></li> <li><label for="page_for_posts"><?php printf( __( 'Posts page: %s' ), wp_dropdown_pages( array( 'name' => 'page_for_posts', 'echo' => 0, 'show_option_none' => __( '— Select —' ), 'option_none_value' => '0', 'selected' => get_option( 'page_for_posts' ) ) ) ); ?></label></li> </ul>
Does this all make sense?
Paul
#5
@
12 years ago
Yes, that's a better idea for a function to utilize the filter and makes sense to me.
#6
@
12 years ago
I was doing some testing and I think I see a further problem. WP doesn't seem to properly handle having a CPT as the front page in some aspects.
For instance, the url for the front page doesn't get changed to just website.com, it's website.com/post-type/post-slug. Same goes for when a link to the new "front page" is placed in a menu. Normally the link is changed to just be website.com but it keeps it's full URL.
Part of that problem seems to be in /wp-admin/includes/nav-menu.php about line 726. It checks for a post type name of 'page' before changing the url out for menus. I haven't found where it does the URL change for the URL of the front of the site.
#8
@
12 years ago
We could just reverse this
if ( 'page' == $post_type_name ) {
becomes
if ( 'post' != $post_type_name ) {
and let the
if ( ! empty( $front_page ) ) {
do it's stuff for all the menu types but this would mean that the code will run more than needed
So the other way would to do a look-up for the page type that is used for the home page test for that setting 'page' as the default as we might not get anything back
$front_page_type = 'page' == get_option('show_on_front') ? get_post_type((int) get_option( 'page_on_front' )) : 'page'; if($front_page_type == $post_type_name ){ ...
If this works it's better and cover all the bases
or this might be even better
$front_page_type = 'page' == get_option('show_on_front') ? get_post_type((int) get_option( 'page_on_front' )) : null; if($front_page_type == $post_type_name ){ ...
Paul
#9
@
12 years ago
Hi
I have done some work on this but have not sorted the URL code
So I am just pasting the patch for now
Index: wp-admin/options-reading.php =================================================================== --- wp-admin/options-reading.php (revision 22831) +++ wp-admin/options-reading.php (working copy) @@ -114,7 +114,7 @@ </label> </p> <ul> - <li><label for="page_on_front"><?php printf( __( 'Front page: %s' ), wp_dropdown_pages( array( 'name' => 'page_on_front', 'echo' => 0, 'show_option_none' => __( '— Select —' ), 'option_none_value' => '0', 'selected' => get_option( 'page_on_front' ) ) ) ); ?></label></li> + <li><label for="page_on_front"><?php printf( __( 'Front page: %s' ), wp_dropdown_pages( apply_filters('options-front-page',array( 'name' => 'page_on_front', 'echo' => 0, 'show_option_none' => __( '— Select —' ), 'option_none_value' => '0', 'selected' => get_option( 'page_on_front' ) ) ) ) ); ?></label></li> <li><label for="page_for_posts"><?php printf( __( 'Posts page: %s' ), wp_dropdown_pages( array( 'name' => 'page_for_posts', 'echo' => 0, 'show_option_none' => __( '— Select —' ), 'option_none_value' => '0', 'selected' => get_option( 'page_for_posts' ) ) ) ); ?></label></li> </ul> <?php if ( 'page' == get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) == get_option( 'page_on_front' ) ) : ?> Index: wp-includes/post.php =================================================================== --- wp-includes/post.php (revision 22831) +++ wp-includes/post.php (working copy) @@ -3628,9 +3628,14 @@ $number = (int) $number; $offset = (int) $offset; - // Make sure the post type is hierarchical + // Make sure we have a valid post type + if ( !is_array( $post_type ) ) + $post_type = explode( ',', $post_type ); + if ( array_diff( $post_type, get_post_types() ) ) + return $pages; + // Make sure the all post types are hierarchical $hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) ); - if ( !in_array( $post_type, $hierarchical_post_types ) ) + if ( array_intersect( $post_type, $hierarchical_post_types ) == count($post_type) ) return $pages; // Make sure we have a valid post status @@ -3733,11 +3738,19 @@ if ( $parent >= 0 ) $where .= $wpdb->prepare(' AND post_parent = %d ', $parent); + // Check if post_type is an array so that Custom Page types can be added to dropdowns and lists + if ( 1 == count( $post_type ) ) { + $where_post_type = $wpdb->prepare("post_type = %s" , array_shift( $post_type ) ); + } else{ + $post_type = implode( "', '", $post_type ); + $where_post_type = "post_type IN ('$post_type')"; + } + if ( 1 == count( $post_status ) ) { - $where_post_type = $wpdb->prepare( "post_type = %s AND post_status = %s", $post_type, array_shift( $post_status ) ); + $where_post_type .= $wpdb->prepare( " AND post_status = %s", array_shift( $post_status ) ); } else { $post_status = implode( "', '", $post_status ); - $where_post_type = $wpdb->prepare( "post_type = %s AND post_status IN ('$post_status')", $post_type ); + $where_post_type .= "AND post_status IN ('$post_status')" ; } $orderby_array = array();
the test functions I used where
add_action( 'init', 'create_post_type' ); function create_post_type() { register_post_type( 'acme_product', array( 'labels' => array( 'name' => __( 'tests' ), 'singular_name' => __( 'test' ) ), 'public' => true, 'has_archive' => true, 'rewrite' => array('slug' => 'tests'), ) ); } function filter_my_cpt($args) { $args['post_type'] = array('page', 'acme_product'); return $args; } add_filter('options-front-page' , 'filter_my_cpt');
I will look at the URl code later
And I want to look getting this into the register_post_type() call
#10
@
12 years ago
I see the bug on the menus I will need to be look for if there is a set home page and then test for that post type add add the Home: XXXXX to the correct list
#11
follow-up:
↓ 12
@
12 years ago
You should attach the patch as a file instead of pasting it in the comment box.
#12
in reply to:
↑ 11
@
12 years ago
Replying to SergeyBiryukov:
You should attach the patch as a file instead of pasting it in the comment box.
even if its not complete?
I have more work to do before finished.
#13
@
12 years ago
Yes, just leave a note about what's already implemented and what else needs to be done.
It's easier to follow the discussions and development when patches are in separate files.
#14
@
12 years ago
Just added a patch this works OK but WP has "page" hard coded in a few places so I need to provide patch's so that we do a look-up for the page type for the home page see nav-menu.php line 729 and jpyper comment above for example.
We also need to find and recode the rewrite rule that hides the path/filename when loading a homepage
I also what to have look at what changes would be needed to make this a switch in the register_post_type function and not a extra filter step
And it would be good to check that we keep "page" in the $args!['post_type'!] array
#15
@
12 years ago
Notes to self
check that removing $wpdb->prepare have I broken SQL santation
this looks OK as we check for valid values before using them
check this 3639
if ( array_intersect( $post_type, $hierarchical_post_types ) == count($post_type) ) return $pages;
this should be a not the same return need to check the output of array_intersect maybe use array_diff
#16
@
12 years ago
- Summary changed from Allow custom post types as "home" to Allow custom post types as "home" and get_posts() to return results for more than one post type
#17
@
12 years ago
- Keywords has-patch needs-testing needs-codex added
This now all works
Apart from if a custom post type is set as a home page it does get servered as the root page eg. Domain.com rather at the URL of domain.com/customPostType/pagename the code for this looks like its somewhere in query.php so might be better if someone else who knows that code looks at that.
And I haven't add code to register_post_type make this a feature but will look at that this week
#21
@
12 years ago
Hi All
I need a bit of help to finish this
I have one last bug and need a code review as the function I added to options-reading needs to be move to better location.
The bug: WordPress doesn't render the custom page at the root all I am getting the 404 page
if you look at line 109 in query.php you will see I have remove the hardcoded "page" and pass in the current page type.
Without this change the custom page loads but with the URL of /pagetype/pagename and not at the root /
With this change I am getting the 404 so there is an additional change needed somewhere
I am sure that this will come back for some rework on variable name etc.
use this function to test, Note the 'show_in_home_page_list'=> true, which how I am declaring that this custom post should be added to the list
add_action( 'init', 'create_post_type' ); function create_post_type() { register_post_type( 'acme_product', array( 'labels' => array( 'name' => __( 'tests' ), 'singular_name' => __( 'test' ) ), 'public' => true, 'has_archive' => true, 'rewrite' => array('slug' => 'tests'), 'hierarchical' => true, 'show_in_home_page_list'=> true, ) ); }
I have tried to remove all the hard code strings so in itself will an improvement.
All and any help to finish this gratefully accepted.
#23
@
11 years ago
- Component changed from Administration to Posts, Post Types
- Focuses administration added
- Severity changed from major to normal
#27
@
9 years ago
I think this would be a very interesting enhancement and would make the front page setting much more flexible.
It should be possible to either set a specific post (no matter what post type, think public => true
) or a post type archive (thinkhas_archive => true
) as the front page. I don't think a new show_in_home_page_list
argument is really needed. A filter should suffice.
Perhaps we need to look at the UI first? Related: #16379
#28
follow-up:
↓ 29
@
9 years ago
I thought this was dead
Yes a filter would a way to go
just added them to a drop-down (maybe grouped) could cause it to get very long so a UI update would help
happy to refresh when needed
#30
@
4 years ago
- Keywords has-patch removed
- Owner set to pbearne
- Status changed from new to accepted
- Version changed from 3.3.1 to trunk
This ticket got a short out in https://wptavern.com/wordpress-5-6-wish-list-homepage-post-type-selection-and-block-management so I am starting to work on it along with anybody who would like to help and let's see if we can this in 5.6
I have a patch with an updated UI for admin which I would like to get validated as the right direction
As came back to this after 8 years I made a few other changes
We control which post types are allowed to be used in homepage content via a new arg in register_post_type()
'show_in_home_page_list'=> true,
backed up by a filter post_types_allowed_on_home_page
$post_types_allowed_on_home_page = apply_filters( 'post_types_allowed_on_home_page', array_keys( get_post_types( array( 'show_in_home_page_list' => true ) ) ) );
If the post capability_type of "post" the I propose we allow it to be swapped for the post type "post" and render on the homepage
To support this we should a new template file front-page-{post-type}.php and then follow the custom post type root archive-{post_type}.php => home.php this would allow a theme to provide a different layout for content if render as home page
If a post type other than "post" is set we should allow setting a page to render posts
If the post capability_type of "page" then we add them to the list of pages that can set as a home along with the normal pages (I have used an optgroup to group them by post types) for better UI
I have tackled the customizer UI yet or started to handle the settings/override the homepage
I would like feedback on the plan and UI
Paul
This ticket was mentioned in Slack in #core by thewebprincess. View the logs.
4 years ago
This ticket was mentioned in Slack in #core by laura. View the logs.
4 years ago
#35
@
4 years ago
Hey @pbearne :) Thanks for working on this patch (for so long!) - I noticed you changed src/wp-includes/assets/script-loader-packages.php
in your latest patch, is that intentional? It didn't apply cleanly so I'll leave off for my testing for now.
This ticket was mentioned in PR #524 on WordPress/wordpress-develop by adamsilverstein.
4 years ago
#36
- Keywords has-patch added; needs-refresh removed
Trac ticket: https://core.trac.wordpress.org/ticket/19958
#37
@
4 years ago
Opened a draft PR to run the test suite against the current patch.
@pbearne - are you mainly looking for feedback on the general approach? Is your code ready for testing and if so, should I apply both CustomPostTypeAsHomePages.ui.refreeh.2.patch and CustomPostTypeAsHomePages.ui.refreeh.patch ?
#38
@
4 years ago
@adamsilverstein just use the last patch
It is just the UI for setting -> reading to give you an idea of where I am going with this
to help with testing I am including code to create a book CPT in the default theme this will not be in the final patch
and the src/wp-includes/assets/script-loader-packages.php should have been patched so I have removed it
This ticket was mentioned in Slack in #core by pbearne. View the logs.
4 years ago
#40
follow-up:
↓ 41
@
4 years ago
- Focuses accessibility added
- Keywords has-screenshots added
Looking at CustomPostTypeAsHomePages.ui.refreeh.2.patch only from a UI / accessibility perspective: the markup needs improvements.
- there are now two form elements, the radio button and the new select, wrapped within the same
<label>
element: this isn't okay as the form elements aren't labelled correctly - these two form elements need to be separated and have their own meaningful, properly associated,
<label>
s - the select element can't be used as part of the radio button labelling
- the
<label>
s need to communicate what the form elements are about - a group of radio buttons is supposed to be used with keyboard by using the arrow keys, but now there's a select element between the two buttons: at this point I wonder whether radio buttons are the best type of form elements for this UI
- regardless, the
<label>
s text needs to be changed and also be translatable: the text needs to be a fully translatable string
Something along these lines would be better:
- Your latest posts (select the posts type below)
- Posts type: [select element]
- A static page (select below)
However, this wouldn't solve the problem of the select element placed between the two radio buttons.
#41
in reply to:
↑ 40
;
follow-up:
↓ 42
@
4 years ago
Replying to afercia:
However, this wouldn't solve the problem of the select element placed between the two radio buttons.
The only way to fix that is to put the post type selector below the two radio buttons swapping it with the static homepage setting as needed
Would that work?
or does showing and hide cause more problems?
#42
in reply to:
↑ 41
@
4 years ago
Replying to pbearne:
The only way to fix that is to put the post type selector below the two radio buttons swapping it with the static homepage setting as needed
Generally, show / hide can be problematic for accessibility but in this case only one of the "swapping" things needs to be used at a time. Seems an interesting idea worth exploring (pending design feedback).
#43
@
4 years ago
- Version changed from trunk to 3.3.1
This ticket predates 5.6 and therefore is not a directly attributed to trunk
or 5.6 itself. Restoring its original version of 3.3.1
. However, if this original version is not correct, please advise or adjust.
This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.
21 months ago
#46
follow-up:
↓ 47
@
21 months ago
Hey, @pbearne - do you want some help refining the UI for better accessibility on this? It seems like it's pretty well advanced, just needs some polish; but if you're still planning on working on this, it seems beneficial.
#47
in reply to:
↑ 46
@
21 months ago
Replying to joedolson:
Hey, @pbearne - do you want some help refining the UI for better accessibility on this? It seems like it's pretty well advanced, just needs some polish; but if you're still planning on working on this, it seems beneficial.
@joedolson yes I would love to get this in Happy to work on this
Do you want to have a pass at the UI?
This ticket was mentioned in Slack in #accessibility by ryokuhi. View the logs.
18 months ago
#50
@
18 months ago
So, it's been a bit more than two weeks. Something that would be really useful coming from you, @pbearne, would be a list of testing steps. I'll take a look at the UI, but we could also use some verification steps for making sure it's working as expected.
This is needed or / and an option to push / block it in the custom post type config / setup