您如何使用CPT作为默认主页?


20

我有一个客户的网站,该网站将大量使用自定义帖子类型来配置其网站。但是对于他们要求的主页,我处于艰难和艰难的境地之间。

实际上,主页将是WordPress中特定“页面”的堆栈。基本上,将有以下页面:简介博客关于我们投资组合与我们联系。它们将全部堆叠在一起,因此您可以从一页滚动到另一页。

我的第一个本能是只使用一个页面(称为Home)并嵌入一个接受页面内容并输出正确顺序(即[pageOrder]intro, blog, about-us, portfolio, contact-us[/pageOrder])的短代码。该页面将使用自定义页面模板来布置内容,控制循环并将导航添加到页面左侧。但这一切似乎都是k脚的。

我的理想解决方案是创建一个自定义帖子类型(称为Stack),该类型允许最终用户通过拖放操作定位页面,并让CPT负责布局和导航等工作。

我理想的解决方案的问题是设置。WordPress允许您为网站的默认主页选择页面。但这与页面的发布类型有关,我不确定在何处进行修改以使用户也可以选择Stack作为默认主页。

因此,为了添加CPT到默认主页的可用页面下拉菜单中,我该连接到哪里?

Answers:


11

感谢@toscho给出了有用的答案,但对我来说有点琐,所以我仔细研究了一下,发现可以添加一个过滤器了:

function wpa18013_add_pages_to_dropdown( $pages, $r ){
    if('page_on_front' == $r['name']){
        $args = array(
            'post_type' => 'stack'
        );
        $stacks = get_posts($args);
        $pages = array_merge($pages, $stacks);
    }

    return $pages;
}
add_filter( 'get_pages', 'wpa18013_add_pages_to_dropdown', 10, 2 );

更新资料

添加上述代码后,我确实可以使用自定义帖子类型作为主页,但是WordPress将重定向永久链接,因为它不是“页面”帖子类型。因此http://localhost/test将重定向到http://localhost/test/stacks/home-stack,这不是我想要的。

不过,添加此操作可以解决该问题,并查询我的自定义帖子类型以及主页页面:

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

我也使用过这样的过滤器,但必须仅限于首页查询。然后我被一些奇怪的行为/错误打败了:我只有404。无论如何+1。:)
fuxia

接得好。函数内部的额外条件(确保post_type尚未设置page_id且不为0)阻止所有404。现在,我可以对我所有的自定义帖子,我的所有帖子以及我的所有页面运行查询,而不会受到任何干扰。
EAMann

@EAmann感谢您的代码!尽管它将首页的标题更改为“帖子标题|标题”,但它仍应能正常工作。主页名称,是否可以将其更改为只是主页名称?
INT

这根本不起作用...服务器警告/错误:wpa18013_add_pages_to_dropdown()未定义变量
Dameer 2013年

8

可能是吧?我先前解决方案的改进版。

add_filter( 'wp_dropdown_pages', 'add_cpt_to_front_page_dropdown', 10, 1 );


/**
 * Adds CPTs to the list of available pages for a static front page.
 *
 * @param  string $select Existing select list.
 * @return string
 */
function add_cpt_to_front_page_dropdown( $select )
{
    if ( FALSE === strpos( $select, '<select name="page_on_front"' ) )
    {
        return $select;
    }

    $cpt_posts = get_posts(
        array(
            'post_type'      => 'YOUR_POST_TYPE'
        ,   'nopaging'       => TRUE
        ,   'numberposts'    => -1
        ,   'order'          => 'ASC'
        ,   'orderby'        => 'title'
        ,   'posts_per_page' => -1
        )
    );

    if ( ! $cpt_posts ) // no posts found.
    {
        return $select;
    }

    $current = get_option( 'page_on_front', 0 );

    $options = walk_page_dropdown_tree(
        $cpt_posts
    ,   0
    ,    array(
            'depth'                 => 0
         ,  'child_of'              => 0
         ,  'selected'              => $current
         ,  'echo'                  => 0
         ,  'name'                  => 'page_on_front'
         ,  'id'                    => ''
         ,  'show_option_none'      => ''
         ,  'show_option_no_change' => ''
         ,  'option_none_value'     => ''
        )
    );

    return str_replace( '</select>', $options . '</select>', $select );
}

这仅是选择自定义帖子类型,但这不会使其显示该自定义帖子类型为首页吗?还是我错过了什么?
Hameedullah Khan

@Hameedullah-选择它后,WordPress将更新一个选项,该选项标记应该将哪个页面用于首页。然后,当用户访问首页时,WordPress从数据库读回相同的选项。
EAMann

@Hameedullah Khan你是对的。这在3.1之前有效,现在我重定向到该帖子的固定链接–我得到404。奇怪。我希望我有时间。:(
fuxia

5

为什么不只是创建一个front-page.php使用常规查询/循环的模板文件,或者(如果将自定义主题选项设置为在首页上显示CPT),又基于CPT输出一个自定义查询/循环,则该模板文件使用吗?

那里的问题是,您将必须创建一个单独的主题选项来控制Front Page的输出,同时指示用户将Front Page设置为静态页面。

为了使事情变得容易,您可以register_setting通过设置API使用调用中的“阅读”选项组,将“主题”选项挂接到“设置阅读”中,以使其与现有的Front-Page选项一起显示。


我喜欢简单的解决方案,Chip我认为您的最好。WordPress允许为首页codex.wordpress.org/Template_Hierarchy#Home_Page_display自定义模板 ,然后人们可以在其中执行任何操作。
2011年

这是最可维护和最直接的解决方案。该front-page.php自动选择,因为是WordPress模板层次结构的一部分。无需记住发生这种情况的原因(或需要将其标记为下一个人)。
奥德斯2014年

2

我认为自从EAMann在2011年编写更新以来,情况可能已经有所改变,并且他提供的wpa18013_add_pages_to_dropdown()函数不再起作用。如Dameer的评论中所述,此函数当前(2013年12月)引发错误“ wpa18013_add_pages_to_dropdown()缺少参数2”

无论如何,对我而言,解决方案是在没有第二个参数的情况下重写函数,或者检查其内容。然后,完整的代码块变为:

function add_unbox_tabs_to_dropdown( $pages ){
    $args = array(
        'post_type' => 'unbox_tabs'
    );
    $items = get_posts($args);
    $pages = array_merge($pages, $items);

    return $pages;
}
add_filter( 'get_pages', 'add_unbox_tabs_to_dropdown' );

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

请注意,在上面的示例中,我要添加的自定义帖子类型是“ unbox_tabs”,而不是“ stack”。


1

我正在使用这种技术来包含来自插件的模板。因此,@ ChipBennett的解决方案不适用。

为了从静态页面列表的插件中添加CPT(),我修改了@EAMann的解决方案,如下所示: 'hierarchical' => 'false'

add_action( 'admin_head-options-reading.php', 'wpse_18013_modify_front_pages_dropdown' );
add_action( 'pre_get_posts', 'wpse_18013_enable_front_page_stacks' );

function wpse_18013_modify_front_pages_dropdown()
{
    // Filtering /wp-includes/post-templates.php#L780
    add_filter( 'get_pages', 'wpse_18013_add_cpt_to_pages_on_front' );
}

function wpse_18013_add_cpt_to_pages_on_front( $r )
{
    $args = array(
        'post_type' => 'stack'
    );
    $stacks = get_posts( $args );
    $r = array_merge( $r, $stacks );

    return $r;
}

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

核心参考v3.4.2:
3.5 RC3中的行号略有不同,但是代码保持不变

/**
 * wp-admin/options-reading.php#L96
 * Happens inside a <li><label>-</label></li>
 */
    wp_dropdown_pages( array( 
                'name' => 'page_on_front'
            ,   'echo' => 0
            ,   'show_option_none' => __( '&mdash; Select &mdash;' )
            ,   'option_none_value' => '0'
            ,   'selected' => get_option( 'page_on_front' ) 
        ) 
    )

/**
  * wp-includes/post-template.php#L768
  */
function wp_dropdown_pages($args = '') {
    $defaults = array( /* defaults array */ );    
    $r = wp_parse_args( $args, $defaults );
    extract( $r, EXTR_SKIP );  
    $pages = get_pages( $r );
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.