问题描述

我有一个客户端,网站将大量使用自定义帖子类型来配置他们的网站。但是,我在一个岩石和一个困难的地方为他们要求的主页。

实际上,主页将是 WordPress 中特定”pages” 的堆栈。基本上,将有一些页面:简介,博客,关于我们,投资组合和联系我们。它们将被堆叠在一起,以便您可以从一个页面滚动到另一个页面。

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

我的理想解决方案是创建一个自定义帖子类型 (称为 Stack),允许最终用户使用 drag-drop 定位页面,并让 CPT 处理布局和导航等。

我的理想解决方案的问题是设置。 WordPress 允许您选择网站的默认主页的页面。但它绑定到一个 post 类型的页面,我不知道在哪里可以修改,以便用户也可以选择一个 Stack 作为默认主页。

那么,为了将 CPT 添加到默认主页的可用页面的下拉列表中,我在哪里挂钩?

最佳解决方案

感谢 @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 );

Update

添加上述代码之后,确实可以使用自定义帖子类型作为主页,但 WordPress 会重定向固定链接,因为它不是”page” 帖子类型。所以 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' );

次佳解决方案

也许是这样?精炼版 my earlier solution

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 );
}

第三种解决方案

为什么不创建一个使用普通查询/循环的 front-page.php 模板文件,或者 (如果在主页上设置了自定义主题选项来显示 CPT),则会根据 CPT 输出自定义查询/循环?

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

为了使事情变得更简单,您可以使用 「设置」API 调用 register_setting 中的 「阅读」 选项组将主题选项挂接到 settings-reading 中,以便使用现有的 Front-Page 选项显示。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。