需要在2个不同的单曲模板上显示相同的自定义帖子类型

时间:2017-12-11 作者:Ray Gulick

我有一个客户,他想在他们的网站上以两个不同品牌的部分显示家庭计划(自定义帖子类型),具体取决于帖子访问的列表页面。几年前,我从@gmazzap找到了这个解决方案,它看起来很有希望,但我无法让它工作:Multiple templates for custom post type

具体来说,它无法修改备用列表页面上的URL:它只是使用CPT注册中指定的slug:

\'rewrite\' => array( \'slug\' => \'plan\', \'with_front\' => false ),
这意味着,当我单击“page\\u kioskoverview,php”模板上的计划链接时,它会显示标准“单一计划”上的帖子。php的模板,而不是备用的“单个kioskplan”。php的模板。

下面是我的代码:

add_action(\'template_redirect\', \'change_plans_plink\');
function change_plans_plink() {
  if (is_page_template(\'page_kioskoverview.php\')) { 
    add_filter( \'post_link\', \'plans_query_string\', 10, 2 );
  }
}
function plans_query_string( $url, $post ) {
  if ( $post->post_type === \'plans\' ) { 
    $url = add_query_arg( array(\'style\'=>\'alt\'), $url );
  }
  return $url;
}

//designate alternative single template for above alt link
add_action(\'template_include\', \'kiosk_plan_single\');
function kiosk_plan_single($template) {
  if( is_singular(\'plans\') ) {
    $alt = filter_input(INPUT_GET, \'style\', FILTER_SANITIZE_STRING);
    if ( $alt === \'alt\' ) $template = \'single-kioskplans.php\';
  }
  return $template;
}
经过几天的研究(并尝试了一些变化但没有成功),我无法发现问题,但我肯定错过了一些东西。

3 个回复
最合适的回答,由SO网友:kierzniak 整理而成

要为同一帖子类型显示不同的模板,我需要创建两个不同的链接,检查我当前所在的链接,并决定加载哪个模板。

工作示例:

/**
 * Register event post type
 *
 * Registering event post type will add such a permalink structure event/([^/]+)/?$
 */
function wpse_288345_register_event_post_type() {

    $labels = array(
        \'name\' => __( \'Events\' ),
        \'singular_name\' => __( \'Event\' ),
        \'add_new\' => __( \'Add new\' ),
        \'add_new_item\' => __( \'Add new\' ),
        \'edit_item\' => __( \'Edit\' ),
        \'new_item\' => __( \'New\' ),
        \'view_item\' => __( \'View\' ),
        \'search_items\' => __( \'Search\' ),
        \'not_found\' => __( \'Not found\' ),
        \'not_found_in_trash\' => __( \'Not found Events in trash\' ),
        \'parent_item_colon\' => __( \'Parent\' ),
        \'menu_name\' => __( \'Events\' ),

    );

    $args = array(
        \'labels\' => $labels,
        \'hierarchical\' => false,
        \'supports\' => array( \'title\', \'page-attributes\' ),
        \'taxonomies\' => array(),
        \'public\' => true,
        \'show_ui\' => true,
        \'show_in_menu\' => true,
        \'show_in_nav_menus\' => false,
        \'publicly_queryable\' => true,
        \'exclude_from_search\' => false,
        \'has_archive\' => true,
        \'query_var\' => true,
        \'can_export\' => true,
        \'rewrite\' => array(\'slug\' => \'event\'),
        \'capability_type\' => \'post\',
    );

    register_post_type( \'event\', $args );
}

add_action( \'init\', \'wpse_288345_register_event_post_type\' );

/**
 * Add custom rewrite rule for event post type.
 *
 * Remember to flush rewrite rules to apply changes.
 */
function wpse_288345_add_event_rewrite_rules() {

    /**
     * Custom rewrite rules for one post type.
     * 
     * We wil know on which url we are by $_GET parameters \'performers\' and \'summary\'. Which we will add to
     * public query vars to obtain them in convinient way.
     */
    add_rewrite_rule(\'event/performers/([^/]+)/?$\', \'index.php?post_type=event&name=$matches[1]&performers=1\', \'top\');
    add_rewrite_rule(\'event/summary/([^/]+)/?$\', \'index.php?post_type=event&name=$matches[1]&summary=1\', \'top\');
}

add_action(\'init\', \'wpse_288345_add_event_rewrite_rules\');

/**
 * Add \'performers\' and \'summary\' custom event query vars.
 */
function wpse_288345_register_event_query_vars( $vars ) {

    $vars[] = \'performers\';
    $vars[] = \'summary\';

    return $vars;
}

add_filter( \'query_vars\', \'wpse_288345_register_event_query_vars\' );

/**
 * Decide which template to load
 */
function wpse_288345_load_performers_or_summary_template( $template ) {

    // Get public query vars
    $performers = (int) get_query_var( \'performers\', 0 );
    $summary    = (int) get_query_var( \'summary\', 0 );

    // If performer = 1 then we are on event/performers link
    if( $performers === 1 ) {
        $template = locate_template( array( \'single-event-performers.php\' ) );
    }

    // If summary = 1 then we are on event/summary link
    if( $summary === 1 ) {
        $template = locate_template( array( \'single-event-summary.php\' ) );
    }

    if($template == \'\') {
        throw new \\Exception(\'No template found\');
    }

    return $template;
}

add_filter( \'template_include\', \'wpse_288345_load_performers_or_summary_template\' );

SO网友:Ray Gulick

这是我使用GET参数和条件语句实现的另一种方法。

在备用列表页面上,我添加了“?模板=永久链接的信息亭。

在singles模板(single plans.php)上,我在模板顶部添加了以下内容(当然还有模板底部的“endif”):

$kiosk = $_GET[\'template\'];
if(isset($kiosk)) :

if(isset($kiosk)) { 
    show kiosk version
    } else {
    show standard version
    }

SO网友:mattmaldre

我也在尝试几乎完全相同的代码,但它不起作用。只有一个改变才能让它完全运行。只需添加locate_template 到一行。

改变

if ( $alt === \'alt\' ) $template = \'single-kioskplans.php\';

if ( $alt === \'alt\' ) $template = locate_template(\'single-kioskplans.php\');
完整代码如下所示:

add_action(\'template_redirect\', \'change_plans_plink\');
function change_plans_plink() {
  if (is_page_template(\'page_kioskoverview.php\')) { 
    add_filter( \'post_link\', \'plans_query_string\', 10, 2 );
  }
}
function plans_query_string( $url, $post ) {
  if ( $post->post_type === \'plans\' ) { 
    $url = add_query_arg( array(\'style\'=>\'alt\'), $url );
  }
  return $url;
}

//designate alternative single template for above alt link
add_action(\'template_include\', \'kiosk_plan_single\');
function kiosk_plan_single($template) {
  if( is_singular(\'plans\') ) {
    $alt = filter_input(INPUT_GET, \'style\', FILTER_SANITIZE_STRING);
    if ( $alt === \'alt\' ) $template = locate_template(\'single-kioskplans.php\');
  }
  return $template;
}

结束