您的主要问题是,当您列出事件时,您(很可能)使用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/media
或http://example.com/events/one-event/show/whatever
.
show
is the endpoint, 这意味着一个变量show = media
或show = 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();
}
}