Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Custom Post Type as Static Frontpage WordPress

  • SOLVED

I have asked this question before and got an answer, but when 3.3 came out, it stopped working. Yes, I said 3.3.

Here's what I'm trying to do, I have a custom post type and I want the custom post type PAGE set as the static home page. Every other methods I tried didn't work.

By the way, this is PLUGIN, so I cannot load a template into the theme.

This is what was written for me. It essentially creates a rewrite rule to set the CPT page as the static frontpage.

class LoadRewrites {
public function __construct() {
$this->buildRewrites();
add_filter('rewrite_rules_array', array(&$this, 'addRewrites'));
add_filter('query_vars', array(&$this, 'addQueryVars'));
add_action('wp_loaded', array(&$this, 'flushRules'));
}
public function buildRewrites() {
$newrules = array();
$frontPost = get_post(get_option("page_on_front"));
$newrules['^$'] = 'index.php?'.$frontPost->post_type.'='.$frontPost->post_name;
$this->newrules = $newrules;
}
public function addRewrites($rules) {
return $this->newrules + $rules;
}
public function addQueryVars($vars) {
//array_push($vars, 'theCategory');
return $vars;
}
public function flushRules() {
$rules = get_option('rewrite_rules');
foreach ($this->newrules as $rule) {
if (!isset($rules[$rule])) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
return;
}
}
}
}

new LoadRewrites();


Like I said, it WAS working. But now, the root url redirects to the custom post type url.

An example is... http://example.com/cptslug/pagename when in reality it should be just http://example.com

I need this ASAP, then of course who doesn't. LOL

Answers (7)

2012-06-14

Hai Bui answers:

Try adding this to the plugin, replacing 'your_custom_post_type' with your post type
add_filter( 'get_pages', 'add_my_cpt' );

function add_my_cpt( $pages )
{
$my_cpt_pages = new WP_Query( array( 'post_type' => 'your_custom_post_type' ) );
if ( $my_cpt_pages->post_count > 0 )
{
$pages = array_merge( $pages, $my_cpt_pages->posts );
}
return $pages;
}


It will add the custom post type pages in the dropdown to select the static home page through the admin Settings -> Reading -> Front Page Displays. Then you can choose one of the custom post type PAGE as front page


Hai Bui comments:

And don't forget to remove your rewrite rule when you try my solution.


Armand Morin comments:

Yes, it does add to the Reading setting, but the URL redirects to the URL of the custom post type.

Like this... http://example.com/cptslug/pagename when in reality it should be just http://example.com


Hai Bui comments:

Did you remove your custom rewrite rule? My solution does not need it


Armand Morin comments:

Yes, I removed the rewrite rule code I had before. I assumed your solution did not need it.


Hai Bui comments:

harder than I though... try adding this (replacing your_cpt with your custom post type):


add_action( 'pre_get_posts', 'enable_front_page_cpt' );
function enable_front_page_cpt( $query ){
if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
$query->query_vars['post_type'] = array( 'page', 'your_cpt' );
}

add_action("template_redirect", 'template_redirect_frontpage_cpt');
function template_redirect_frontpage_cpt() {
if (is_front_page())
{
include(TEMPLATEPATH . "/single-your_cpt.php");
die();
}
}


Armand Morin comments:

This was close and did stop the issue I had with the page redirecting. But now, if I select to show lastest posts as main page or any other page, it will always default to the CPT template. So, it works and it does'nt, if that makes sense.


Hai Bui comments:

We can fix it by checking if the page is 'photo' post type:
function enable_front_page_cpt( $query ){
if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
$query->query_vars['post_type'] = array( 'page','photo' );
}
add_action( 'pre_get_posts', 'enable_front_page_cpt' );

add_action("template_redirect", 'template_redirect_frontpage_cpt');

function template_redirect_frontpage_cpt() {
if (is_front_page() && is_singular('photo'))
{
include(TEMPLATEPATH . "/single-photo.php");
die();
}
}


Hai Bui comments:

regarding my last answer, please replace 'photo' with your custom post type


Armand Morin comments:

Thanks, that worked.

thanks... FYI you and AdamGold, both gave great responses so I doubled the award so I can give you both the original amount.

thank you so much.

2012-06-14

AdamGold answers:

If the following URL does work:
http://example.com/index.php?cpt=post_name

Then this code should work:
<?php
class LoadRewrites {

public function __construct() {

$this->buildRewrites();

add_action( 'generate_rewrite_rules', array(&$this, 'addRewrites'));

add_filter('query_vars', array(&$this, 'addQueryVars'));

add_action('wp_loaded', array(&$this, 'flushRules'));

}

public function buildRewrites() {
global $wp_rewrite;

$frontPost = get_post(get_option("page_on_front"));

$new_rules = array(
'^$' => 'index.php?' . $frontPost->post_type . '=' . $frontPost->post_name,
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}

public function addRewrites($rules) {

return $this->newrules + $rules;

}

public function addQueryVars($vars) {

//array_push($vars, 'theCategory');

return $vars;

}

public function flushRules() {

$rules = get_option('rewrite_rules');

foreach ($this->newrules as $rule) {

if (!isset($rules[$rule])) {

global $wp_rewrite;

$wp_rewrite->flush_rules();

return;

}

}

}

}



new LoadRewrites();
?>


If it doesn't, can you please comment here with a link to the actual page you want to show? (you can replace the URL to example.com, I just need the parameters after index.php)


Armand Morin comments:

Adam,

I definately think you you're on the right track. But I ran into an issue on this line.

$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;

I got an error... Fatal error: Unsupported operand types for that line.

Any ideas?


AdamGold comments:

Please try the following:
Replace:
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;

With:
$wp_rewrite->rules = array_merge($new_rules, $wp_rewrite->rules);


AdamGold comments:

I had a little mistake in my last code, this is the new one:

<?php

class LoadRewrites {



public function __construct() {

add_action( 'generate_rewrite_rules', array(&$this, 'addRewrites'));



add_filter('query_vars', array(&$this, 'addQueryVars'));



add_action('wp_loaded', array(&$this, 'flushRules'));



}



public function buildRewrites() {

global $wp_rewrite;



$frontPost = get_post(get_option("page_on_front"));



$new_rules = array(

'^$' => 'index.php?' . $frontPost->post_type . '=' . $frontPost->post_name,

);

$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;

}



public function addRewrites($rules) {



return $this->newrules + $rules;



}



public function addQueryVars($vars) {



//array_push($vars, 'theCategory');



return $vars;



}



public function flushRules() {



$rules = get_option('rewrite_rules');



foreach ($this->newrules as $rule) {



if (!isset($rules[$rule])) {



global $wp_rewrite;



$wp_rewrite->flush_rules();



return;



}



}



}



}
new LoadRewrites();

?>


AdamGold comments:

Sorry, mistake again :D

<?php



class LoadRewrites {







public function __construct() {



add_action( 'generate_rewrite_rules', array(&$this, 'addRewrites'));







add_filter('query_vars', array(&$this, 'addQueryVars'));







add_action('wp_loaded', array(&$this, 'flushRules'));







}







public function buildRewrites() {



global $wp_rewrite;







$frontPost = get_post(get_option("page_on_front"));







$new_rules = array(



'^$' => 'index.php?' . $frontPost->post_type . '=' . $frontPost->post_name,



);



$wp_rewrite->rules = array_merge($new_rules, $wp_rewrite->rules);



}







public function addRewrites($rules) {







return $this->newrules + $rules;







}







public function addQueryVars($vars) {







//array_push($vars, 'theCategory');







return $vars;







}







public function flushRules() {







$rules = get_option('rewrite_rules');







foreach ($this->newrules as $rule) {







if (!isset($rules[$rule])) {







global $wp_rewrite;







$wp_rewrite->flush_rules();







return;







}







}







}







}

new LoadRewrites();



?>


AdamGold comments:

Wow, seems like I am really not in focus today :|

<?php

class LoadRewrites {
public function __construct() {
add_action( 'generate_rewrite_rules', array(&$this, 'buildRewrites'));
add_filter('query_vars', array(&$this, 'addQueryVars'));
add_action('wp_loaded', array(&$this, 'flushRules'));
}

public function buildRewrites() {
global $wp_rewrite;
$frontPost = get_post(get_option("page_on_front"));
$new_rules = array(
'^$' => 'index.php?' . $frontPost->post_type . '=' . $frontPost->post_name,
);
$wp_rewrite->rules = array_merge($new_rules, $wp_rewrite->rules);
}
public function addRewrites($rules) {
return $this->newrules + $rules;
}
public function addQueryVars($vars) {
//array_push($vars, 'theCategory');
return $vars;
}

public function flushRules() {
$rules = get_option('rewrite_rules');

foreach ($this->newrules as $rule) {
if (!isset($rules[$rule])) {
global $wp_rewrite;

$wp_rewrite->flush_rules();

return;

}

}

}

}

new LoadRewrites();

?>


Armand Morin comments:

Ok, I just tried the last code you posted. I got this.

Warning: Invalid argument supplied for foreach() on this line...
foreach ($this->newrules as $rule) {

I also got...

Warning: Cannot modify header information - headers already sent


AdamGold comments:

Okay, you don't even need that function, so here is the new code - After you save it to the FTP refresh your permalinks page in the admin:

<?php

class LoadRewrites {
public function __construct() {
add_action( 'generate_rewrite_rules', array(&$this, 'buildRewrites'));
add_filter('query_vars', array(&$this, 'addQueryVars'));
//add_action('wp_loaded', array(&$this, 'flushRules'));
}

public function buildRewrites() {
global $wp_rewrite;
$frontPost = get_post(get_option("page_on_front"));
$new_rules = array(
'^$' => 'index.php?' . $frontPost->post_type . '=' . $frontPost->post_name,
);
$wp_rewrite->rules = array_merge($new_rules, $wp_rewrite->rules);
}
public function addRewrites($rules) {
return $this->newrules + $rules;
}
public function addQueryVars($vars) {
//array_push($vars, 'theCategory');
return $vars;
}

public function flushRules() {
$rules = get_option('rewrite_rules');

foreach ($this->newrules as $rule) {
if (!isset($rules[$rule])) {
global $wp_rewrite;

$wp_rewrite->flush_rules();

return;

}

}

}

}

new LoadRewrites();

?>


Armand Morin comments:

Ok, good news.. no errors. :)

Bad news... it didn't work.

The page still redirects to the CPT url like... this... http://example.com/cpt/post_name and when I tested with the default permalink it still redirected the home page to http://example.com/?cpt=post_name

Although, I see in your code you have...
'^$' => 'index.php?' . $frontPost->post_type . '=' . $frontPost->post_name,

So I saw that the page mine actually showed was without the index.php?, so I removed that and still no luck. It still redirected.


AdamGold comments:

When you go to homepage, it redirects you to the cpt page? I'm afraid this is happening because of another code. Before, you had the following error:
Warning: Cannot modify header information - headers already sent

Do you remember the line and file?


Armand Morin comments:

The the reference on that was a line in the pluggable file in Wordpress admin, it wasn't a line in the code you provided.


AdamGold comments:

Okay, can you please try the following code:


<?php



class LoadRewrites {
public var $new_rules = array();
public function __construct() {

add_action( 'generate_rewrite_rules', array(&$this, 'buildRewrites'));
add_filter('rewrite_rules_array', array(&$this, 'addRewrites'));

//add_filter('query_vars', array(&$this, 'addQueryVars'));

add_action('wp_loaded', array(&$this, 'flushRules'));

}



public function buildRewrites() {

global $wp_rewrite;

$frontPost = get_post(get_option("page_on_front"));

$this->new_rules = array(

'^$' => 'index.php?' . $frontPost->post_type . '=' . $frontPost->post_name,

);

//$wp_rewrite->rules = array_merge($new_rules, $wp_rewrite->rules);

}

public function addRewrites($rules) {

return $this->newrules + $rules;

}

public function addQueryVars($vars) {

//array_push($vars, 'theCategory');

return $vars;

}



public function flushRules() {

$rules = get_option('rewrite_rules');



foreach ($this->newrules as $rule) {

if (!isset($rules[$rule])) {

global $wp_rewrite;



$wp_rewrite->flush_rules();



return;
}
}
}
}

new LoadRewrites();

?>


AdamGold comments:

yet again...


<?php







class LoadRewrites {

public $new_rules = array();

public function __construct() {



add_action( 'generate_rewrite_rules', array(&$this, 'buildRewrites'));

add_filter('rewrite_rules_array', array(&$this, 'addRewrites'));



//add_filter('query_vars', array(&$this, 'addQueryVars'));



add_action('wp_loaded', array(&$this, 'flushRules'));



}







public function buildRewrites() {



global $wp_rewrite;



$frontPost = get_post(get_option("page_on_front"));



$this->new_rules = array(



'^$' => 'index.php?' . $frontPost->post_type . '=' . $frontPost->post_name,



);



//$wp_rewrite->rules = array_merge($new_rules, $wp_rewrite->rules);



}



public function addRewrites($rules) {



return $this->newrules + $rules;



}



public function addQueryVars($vars) {



//array_push($vars, 'theCategory');



return $vars;



}







public function flushRules() {



$rules = get_option('rewrite_rules');







foreach ($this->newrules as $rule) {



if (!isset($rules[$rule])) {



global $wp_rewrite;







$wp_rewrite->flush_rules();







return;

}

}

}

}



new LoadRewrites();



?>


Armand Morin comments:

I got...

Fatal error: Unsupported operand types on this line...

return $this->newrules + $rules;


AdamGold comments:

Okay. let's try to flush:

<?php















class LoadRewrites {



public $new_rules = array();



public function __construct() {







add_action( 'generate_rewrite_rules', array(&$this, 'buildRewrites'));



//add_filter('rewrite_rules_array', array(&$this, 'addRewrites'));







//add_filter('query_vars', array(&$this, 'addQueryVars'));







add_action('wp_loaded', array(&$this, 'flushRules'));







}















public function buildRewrites() {







global $wp_rewrite;







$frontPost = get_post(get_option("page_on_front"));







$this->new_rules = array(







'^$' => 'index.php?' . $frontPost->post_type . '=' . $frontPost->post_name,







);







$wp_rewrite->rules = array_merge($new_rules, $wp_rewrite->rules);







}







public function addRewrites($rules) {







return $this->newrules + $rules;







}







public function addQueryVars($vars) {







//array_push($vars, 'theCategory');







return $vars;







}















public function flushRules() {







$rules = get_option('rewrite_rules');















foreach ($this->newrules as $rule) {







if (!isset($rules[$rule])) {







global $wp_rewrite;















$wp_rewrite->flush_rules();















return;



}



}



}



}







new LoadRewrites();







?>


Also the following plugin could be really useful for you, to analyze your homepage rewrite:
http://wordpress.org/extend/plugins/monkeyman-rewrite-analyzer/


AdamGold comments:

in the new code, replace:
$wp_rewrite->rules = array_merge($new_rules, $wp_rewrite->rules);

with:
$wp_rewrite->rules = array_merge($this->new_rules, $wp_rewrite->rules);


Armand Morin comments:

I got this error.

Warning: Invalid argument supplied for foreach() on this line...
foreach ($this->newrules as $rule) {

Also gave me... Warning: Cannot modify header information - headers already sent by the pluggable.php in wordpress admin.

I installed the monkeyman rewrite analyzer. Is there any info you want me to send to you from that?

Also, I can install a demo site to make it easier for you. Let me know and I can PM you the details.


AdamGold comments:

Sure, PM me please. (probably won't be available in the next hours but will fix it as soon as I am available).

Also, replace:
$this->newrules

with:
$this->new_rules


AdamGold comments:

function optin_pre_posts( $query ) {
$page_on_front = get_post(get_option("page_on_front"));
if ( $query->query_vars['page_id'] == get_option("page_on_front") && $query->query_vars['post_type'] == '' && $query->query_vars['page_id'] != 0 && $page_on_front->post_type == 'optin' ) {
global $post;
$post = get_post(get_option('page_on_front'));
include(plugin_dir_path(__FILE__) . "single-optinpage.php");
die();
}
}
if ( !is_admin() && ($_SERVER['REQUEST_URI'] == '' || $_SERVER['REQUEST_URI'] == '/' || $_SERVER['REQUEST_URI'] == '/index.php') ) add_filter( 'pre_get_posts', 'optin_pre_posts' );



// *********************************************************************************** //
// ADDS PLUGIN MENU AND PAGE ICON
// *********************************************************************************** //

add_action('admin_head', 'add_wpoptin_icon');
function add_wpoptin_icon() {
global $post_type;
?>
<style>
<?php if (($_GET['post_type'] == 'optinpage') || ($post_type == 'optinpage')) : ?>
#icon-edit { background:transparent url('<?php echo WP_PLUGIN_URL .'/wp-optin-page/images/wpoptin32.png';?>') no-repeat; }
<?php endif; ?>
#adminmenu #menu-posts-optinpage div.wp-menu-image{background:transparent url("<?php echo WP_PLUGIN_URL .'/wp-optin-page/images/wpoptin16.png';?>") no-repeat center center;}
#adminmenu #menu-posts-optinpage:hover div.wp-menu-image,#adminmenu #menu-posts-optinpage.wp-has-current-submenu div.wp-menu-image{background:transparent url("<?php echo WP_PLUGIN_URL .'/wp-optin-page/images/wpoptin16.png';?>") no-repeat center center;}
</style>
<?php
}

// *********************************************************************************** //
// ADDS BACKWARD FUNCTIONALITY FOR SLL AND STANDARD VARIABLES
// *********************************************************************************** //

if ( ! function_exists( 'is_ssl' ) ) {
function is_ssl() {
if ( isset($_SERVER['HTTPS']) ) {
if ( 'on' == strtolower($_SERVER['HTTPS']) )
return true;
if ( '1' == $_SERVER['HTTPS'] )
return true;
} elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
return true;
}
return false;
}
}

if ( version_compare( get_bloginfo( 'version' ) , '3.0' , '<' ) && is_ssl() ) {
$wp_content_url = str_replace( 'http://' , 'https://' , get_option( 'siteurl' ) );
} else {
$wp_content_url = get_option( 'siteurl' );
}
$wp_content_url .= '/wp-content';
$wp_content_dir = ABSPATH . 'wp-content';
$wp_plugin_url = $wp_content_url . '/plugins';
$wp_plugin_dir = $wp_content_dir . '/plugins';
$wpmu_plugin_url = $wp_content_url . '/mu-plugins';
$wpmu_plugin_dir = $wp_content_dir . '/mu-plugins';

// *********************************************************************************** //
// ADDS TEMPLATE CHOICE
// *********************************************************************************** //

function wpoptin_template_redirect() {
global $wp_query;
if ($wp_query->query_vars["post_type"] == "optinpage") {
include(plugin_dir_path(__FILE__) . "single-optinpage.php");
die(); }
}

add_action("template_redirect", 'wpoptin_template_redirect');


// *********************************************************************************** //
// ADD STYLESHEET TO THEME PAGE
// *********************************************************************************** //
//wp_enqueue_script('custom-js', WP_PLUGIN_URL . '/wp-optin-page/js/custom-js.js');

function wpoptin_enqueue_styles() {
global $wp_query;
$page_on_front = get_post(get_option("page_on_front"));
if ($wp_query->query_vars['post_type'] == 'optinpage' || ( $wp_query->query_vars['page_id'] == get_option('page_on_front') && $page_on_front->post_type == 'optin') )
wp_register_style( 'wpoptinstylesheet', WP_PLUGIN_URL . '/wp-optin-page/wpoptin-style.css' );
wp_enqueue_style( 'wpoptinstylesheet', plugins_url( '/wp-optin-page/wpoptin-style.css', __FILE__ ), false, '1.1', 'all' );
}
add_action( 'wp_print_styles', 'wpoptin_enqueue_styles' );

function wpoptin_unregister_styles() {
global $wp_query;
if ($wp_query->query_vars["post_type"] != "optinpage" && $page_on_front->post_type != 'optin' )
wp_deregister_style( 'wpoptinstylesheet' );
}
add_action( 'wp_print_styles', 'wpoptin_unregister_styles' );


Not the prettiest, but works.


Armand Morin comments:

Adam,

thanks... FYI you and Hai Bui, both gave great responses so I doubled the award so I can give you both the original amount.

thank you so much.

2012-06-14

Rashad Aliyev answers:

Look at this issue please.

http://wordpress.org/support/topic/custom-post-type-permalink-rewrite


Armand Morin comments:

Yes, this doesn't apply to my issue above. I have a plugin which creates this custom post type and I'm trying to make it the homepage.


Rashad Aliyev comments:

Share your plugin Name or URL here. If it's not free then please share the some codes here or send via email.

2012-06-14

Gabriel Reguly answers:

Hi Amand,

Are you aware that WordPress 3.4 is the current version?

[[LINK href="http://wordpress.org/news/2012/06/green/"]]http://wordpress.org/news/2012/06/green/[[/LINK]]

Regards,
Gabriel


Armand Morin comments:

Yes I know. I just haven't had time to get around to fix this issue the problem still exists in 3.4


Gabriel Reguly comments:

Ok, how do you select your frontpage?

I use a plugin where the frontpage is a regular page with a shortcode inside it to display the CPT.

Can you post you plugin code?


Gabriel Reguly comments:

Hi Armand,

Please try this, based on Hai Bui code.


add_action( 'pre_get_posts', 'enable_front_page_cpt' );
function enable_front_page_cpt( $query ){
if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
$query->query_vars['post_type'] = array( 'page', 'your_cpt' );
}

add_action("template_redirect", 'template_redirect_frontpage_cpt');
function template_redirect_frontpage_cpt() {
if (is_front_page() )
{
$home_page_id = (int) get_option( 'page_for_posts' );
if ( empty( $home_page_id ) ) {
include(TEMPLATEPATH . "/single-your_cpt.php");
die();
}
}
}


Hopefully it will work as you desire.

Regards,
Gabriel

P.S. You it does not work, please post the plugin code.

2012-06-14

Jatin Soni answers:

Check this article may be it will solve your issue.

http://justintadlock.com/archives/2010/02/02/showing-custom-post-types-on-your-home-blog-page


Armand Morin comments:

I've read this previously. This is only if you want to display custom post type posts on the home page.

The difference is that I have a Custom Post Type PAGE I want to display.

2012-06-14

designchemical answers:

Hi,

Try turning off canonicalisation and see if that helps.

add the following filter:

remove_filter('template_redirect', 'redirect_canonical');


Armand Morin comments:

I tried it and got a page not found.

I believe the issue with this method is that, I need the template_redirect because I'm using it for wordpress to find the custom post type template in the plugin folder rather than the templates folder.

2012-06-14

John Cotton answers:

I'm assuming you can't edit your front-page.php? If you can then that's an easy place to affect what gets sent out.

Assuming not, then try this:


function cpt_homepage($query) {

if( $query->is_home ) {
$query->is_home = false;

$query->query_vars['page'] = null;
$query->query_vars[YOUR_CPT_TYPE] = YOUR_CPT_TYPE_PAGE_NAME;
$query->query_vars['post_type'] = YOUR_CPT_TYPE;
$query->query_vars['name'] = YOUR_CPT_TYPE_PAGE_NAME;

$query->query = array( 'page' => null,
YOUR_CPT_TYPE => YOUR_CPT_TYPE_PAGE_NAME,
'post_type' => YOUR_CPT_TYPE,
'name' => YOUR_CPT_TYPE_PAGE_NAME);
}

return $query;
}
add_action('parse_query', 'cpt_homepage');


You need to have the Dashboard > Reading setting set to "Your Latest Posts".

Clearly you could create an options page and have the page name and even the type come from a database variable, but put the code above in and you should get what you want.


John Cotton comments:

Go with Hai Bui - works beautifully!


John Cotton comments:

Have you tried mu solution? I'm surprised you didn't get anywhere with Hui's, but if not, mine should work for you anyway.


Armand Morin comments:

John,

Yes, Hui's and Adams's both work.

Thanks.