Multiple single templates?

时间:2013-09-12 作者:user1514045

假设我有一个名为“事件”的自定义帖子类型,它有几个用于图像、文档等的自定义元框。。

是否可能有两个不同的单一模板?

例如:我有一个列出所有事件的页面,如果我单击一个事件,单一视图将显示我在event single中输入的所有元信息。php模板。

现在,我想有一个不同的页面,再次列出所有事件,但如果我单击查看单个事件,则会使用不同的模板,以便显示与事件相关的其他元数据。

或更好:

page-events.php lists all events -> click on event -> shows single-event.php

page-media.php lists all events -> click on event -> shows single-event-whatever.php
WordPress可以这样做吗?

1 个回复
SO网友:gmazzap

您的主要问题是,当您列出事件时,您(很可能)使用the_permalink() 函数获取单个事件的url。

调用此url时,Wordpress会显示单个事件,但Wordpress如何知道链接是否在page-events.php 或在page-media.php?

如果你没有对Wordpress说什么(也就是说,如果你没有把信息放在url中),WP无法区分链接是在页面中还是在其他页面中被点击。

所以,我建议你add an endpoint.

这意味着您的单个活动将有不同的url,例如,如果标准链接类似http://example.com/events/one-event/ 你也可以http://example.com/events/one-event/show/mediahttp://example.com/events/one-event/show/whatever.

show is the endpoint, 这意味着一个变量show = mediashow = whatever 作为查询变量传递给Wordpess,因此您可以使用它来包含所需的模板。

要添加端点,请使用:

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

function add_show_endpoint() {
  add_rewrite_endpoint( \'show\', EP_PERMALINK );
}
现在当你在page-media.php 你应该有这样的链接http://example.com/events/one-event/show/media 当你在的时候page-whatever.php 你应该有如下链接http://example.com/events/one-event/show/whatever.

如何做到这一点?很简单:在get_permalink 作用

add_action(\'wp_head\', \'set_event_permalink_filter\');

function set_event_permalink_filter() {
  $single_templates = array(
    // page template => endpoint to use
    \'page-media.php\' => \'media\',
    \'page-info.php\' => \'info\',
    \'page-whatever.php\' => \'whatever\'
  );
  foreach ( $single_templates as $page => $endpoint) {
    if ( is_page_template($page) ) {
      global $event_endpoint;
      $event_endpoint = $endpoint;
      add_filter(\'post_link\', \'event_permalink\', 99, 3);
      return;
    }
  }
}

function event_permalink ($permalink, $post, $leavename) {
  if ( $post->post_type != \'events\' ) return $permalink;
  global $event_endpoint;
  if ( empty($event_endpoint) ) return $permalink;
  return user_trailingslashit($permalink) . \'show/\' . $event_endpoint . \'/\';
}
此工作流比可能的要复杂一些,因为is_page_template() 条件标记doesn\'t 在回路内部工作(info), 因此,我们需要在循环开始之前检查页面模板,并使用全局变量将端点传递给event_permalink 在循环中由过滤器钩子调用的函数。

此时,如果你进入页面,例如。page-media.php 为事件帖子类型生成的所有链接以结尾/show/media/ 当您单击它们时,查询变量show 设置为media.

所以,现在我们可以template_include 过滤器和基于show 变量包括正确的模板。对于我们可以使用的pourposelocate_template 完全支持子主题。

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

function single_event_template( $template ) {
  if ( ! is_single(\'events\') ) return $template;
  global $wp_query;
  $show = $wp_query->get(\'show\');
  if ( empty($show) ) return $template;
  $file = locate_template( \'single-events-\' . $show . \'.php\', true, false );
  return $file ? : $template;
}
所以当我们访问链接时http://example.com/events/one-event/show/media (在page-media.php) 如果模板文件single-event-media.php 在父主题或子主题中找到它将是必需的,否则single-event.php 将使用。

记住,添加后all the code in this answer 到插件或中functions.php you have to flush the rewrite rules 登录后端,转到“设置”->“永久链接”,然后单击“保存更改”。

请注意,代码为totally untested 并且写在这里(没有语法突出显示),因此它可能包含拼写错误和语法错误:如果您有一些错误,请在Codex(php.net文档)中查找触发错误的代码,并检查正确的语法。

在所有代码中,假设您的CPT命名为“事件”,请根据您的需要进行更改。

还可以在中将页面模板更改为端点关联$single_templates 内部变量set_event_permalink_filter 作用

插件代码我将以上所有代码放在一个使用类的插件中(避免使用全局变量)。

类中有2个静态变量,您必须更改以满足您的需要。

该插件还包含一个过滤器:\'multiple_cpt_single_templates\' 允许从主题或其他插件向端点关联添加页面模板。您甚至可以完全清空(设置为array() ) 默认值$single_templates 静态变量,并通过过滤器填充。

作为一个插件,我使用register_activation_hook 刷新重写规则。

<?php
/**
 * Plugin Name: Multiple CPT Single Templates
 * Plugin URI: http://wordpress.stackexchange.com/questions/113878/multiple-single-templates
 * Author: G. M.
 * Author URI: http://wordpress.stackexchange.com/users/35541/
 */

add_action(\'after_setup_theme\', \'initMultipleCptSingleTemplates\');

function initMultipleCptSingleTemplates() {
    MultipleCptSingleTemplates::init();
}

register_activation_hook( __FILE__, array(\'MultipleCptSingleTemplates\', \'install\') );
register_deactivation_hook( __FILE__, array(\'MultipleCptSingleTemplates\', \'uninstall\') );

class MultipleCptSingleTemplates {

  /**
  * CHANGES FOLLOWING TWO VARIABLES ACCORDING TO YOUR NEEDS
  */

  static $cpt = \'events\';

  static $single_templates =  array(
    // page template => endpoint to use
    \'page-media.php\' => \'media\',
    \'page-info.php\' => \'info\',
    \'page-whatever.php\' => \'whatever\'
  );

  /** CONFIGIGURATION END */


  static $endpoint;

  static function init() {
    add_action(\'init\', array( __CLASS__, \'add_show_endpoint\') );
    add_filter(\'template_include\', array( __CLASS__, \'single_event_template\') );
    add_action(\'wp_head\', array( __CLASS__, \'set_event_permalink_filter\') );
  }

  static function add_show_endpoint() {
    add_rewrite_endpoint( \'show\', EP_PERMALINK );
  }

  static function set_event_permalink_filter() {
    $single_templates = apply_filter(\'multiple_cpt_single_templates\', self::$single_templates);
    if ( empty($single_templates) ) return;
    foreach ( $single_templates as $page => $endpoint) {
      if ( is_page_template($page) ) {
        self::$endpoint = $endpoint;
        add_filter(\'post_link\', array( __CLASS__, \'event_permalink\'), 99, 3);
        return;
      }
    }
  }

  static function event_permalink ($permalink, $post, $leavename) {
    if ( $post->post_type != self::$cpt ) return $permalink;
    if ( empty(self::$endpoint) ) return $permalink;
    return user_trailingslashit($permalink) . \'show/\' . self::$endpoint . \'/\';
  }

  static function event_permalink ($permalink, $post, $leavename) {
    if ( $post->post_type != self::$cpt ) return $permalink;
    if ( empty(self::$endpoint) ) return $permalink;
    return user_trailingslashit($permalink) . \'show/\' . self::$endpoint . \'/\';
  }

  static  function install( $template ) {
    self::add_show_endpoint();
    flush_rewrite_rules();
  }

  static  function uninstall( $template ) {
    flush_rewrite_rules();
  }

}

结束

相关推荐