我有一个自定义的帖子类型设置和几个自定义字段。我正在创建一个显示所有自定义帖子类型的页面,但我希望有多个视图。请参见下面的示例。一个是列表视图,另一个是带有图像的平铺项目视图。
顶部将有按钮在模板之间切换。有没有一种方法可以在页面模板之间动态切换?我从来没有做过这样的事情,如果能在这件事上得到任何帮助,我将不胜感激!我宁愿不要让投资组合的每个视图都是一个新的页面。
谢谢
我有一个自定义的帖子类型设置和几个自定义字段。我正在创建一个显示所有自定义帖子类型的页面,但我希望有多个视图。请参见下面的示例。一个是列表视图,另一个是带有图像的平铺项目视图。
顶部将有按钮在模板之间切换。有没有一种方法可以在页面模板之间动态切换?我从来没有做过这样的事情,如果能在这件事上得到任何帮助,我将不胜感激!我宁愿不要让投资组合的每个视图都是一个新的页面。
谢谢
我的答案有点像@allenericr 回答点+一些缓存。
我建议仅当这3个模板在内容上不同,而不仅仅是在方面不同时,才实现这一点,否则CSS+JS解决方案应该是最佳选择。
创建主页模板\'multi-template-page.php\'
仅包含开关按钮和get_template_part
调用以包括3个不同模板文件(名为。my-template-1.php
, my-template-2.php
和my-template-3.php
) 您必须为每个模板编写。
在主模板中输入如下内容:
<?php
/*
Template Name: Multi Template Page
*/
get_header(); ?>
<ul id="template_switches">
<li><a href="#template-1" data-template="1" class="active">Template 1</a></li>
<li><a href="#template-2" data-template="2">Template 2</a></li>
<li><a href="#template-2" data-template="3">Template 3</a></li>
</ul>
<div id="template-target"><?php get_template_part(\'my-template\', \'1\'); ?></div>
<?php get_footer(); ?>
因此,默认情况下,您将激活并显示第一个模板。然后,在functions.php
将此模板的脚本排入队列:
add_action(\'wp_enqueue_scripts\', \'template_switch_script\');
function template_switch_script() {
if ( is_page_template(\'multi-template-page.php\') ) {
wp_enqueue_script(\'multi-template\', get_template_directory_uri() . \'/js/multi-template.js\', array(\'jquery\'));
$data = array(
\'url\' => admin_url(\'admin-ajax.php\'),
\'id\' => get_queried_object()->ID
);
wp_localize_script(\'multi-template\', \'multiTemplateData\', $data );
}
}
现在必须创建jsvascript文件multi-template.js
在主题的js子文件夹中:window.multiTemplateCache = {} // prepare a cache object
jQuery().ready( function($) {
// cache the 1st template on load
window.multiTemplateCache.template_1 = $(\'#template-target\').html();
$(\'#template_switches li a\').click( function(e) {
e.preventDefault();
if ( $(this).hasClass(\'active\') ) return false; // do nothing if click active link
var template = $(this).data(\'template\');
if ( window.multiTemplateCache[\'template_\' + template ] ) { // look in cache
// in cache, just output to page
$(\'#template-target\').html( window.multiTemplateCache[\'template_\' + template] );
} else { // not in cache, retrieve via ajax
// remove current template and put a loading message
$(\'#template-target\').html( \'loading...\' );
// css stuff
$(\'#template_switches li a\').removeClass(\'active\');
$(this).addClass(\'active\');
$.get(
multiTemplateData.url,
{
postId: multiTemplateData.id,
action: \'multi_template_template\',
which: template
},
function( data ) {
// cache the template
window.multiTemplateCache[\'template_\' + template ] = data;
// output the template to page
$(\'#template-target\').html( data );
}
);
} // end if
}); // end on click event
}); // on ready event
此脚本单击其中一个开关链接,检查缓存对象中是否已加载模板,如果已加载,则将其输出。如果没有,则发送一个通过所需模板的ajax请求。在将内容放入页面之前,它会被缓存,因此每个模板都会触发一次ajax调用。但仅适用于模板2和3,因为加载时缓存了模板1:)
那么,现在在你的function.php
您必须添加ajax操作和相关函数。
add_action(\'wp_ajax_multi_template_template\', \'multi_template_template\');
add_action(\'wp_ajax_nopriv_multi_template_template\', \'multi_template_template\');
function multi_template_template() {
$template = isset($_REQUEST[\'which\']) ? $_REQUEST[\'which\'] : false;
if ( ! $template ) die(\'Sorry, impossible to load content\');
$postid = isset($_REQUEST[\'postId\']) ? $_REQUEST[\'postId\'] : false;
if ( $postid ) {
global $post; // I\'m setting global $post just-in-case the template make use of it
$post = get_post($postid);
}
get_template_part(\'my-template\', $template);
die();
}
您可以改进我的代码,添加#
功能,即当您指向以下地址时http://example.com/multi-template-page/#template2
模板2被设置为活动的,并为第一个加载。。。您可以通过rewrite endpoint. 这将为每次单击按钮向服务器发送一个请求,您必须自己格式化链接以将端点附加到永久链接,不确定这是否满足您的要求。
首先注册page post类型的端点:
function wpa_view_endpoint(){
add_rewrite_endpoint( \'view\', EP_PAGES );
}
add_action( \'init\', \'wpa_view_endpoint\' );
现在,对于每个页面,如:http://example.com/some-page/
您还可以有如下URL:http://example.com/some-page/view/list/
的价值view
将通过以下方式在您的模板中提供get_query_var
:$view = get_query_var( \'view\' );
然后可以显示基于该值的任何标记。您还可以过滤页面模板的加载,并通过以下方式为每个视图加载单独的模板:
function wpa_view_template( $template = \'\' ){
global $wp_query;
if( isset( $wp_query->query_vars[\'view\'] ) ) {
$template = locate_template( $wp_query->query_vars[\'view\'] . \'.php\', false );
}
return $template;
}
add_filter( \'page_template\', \'wpa_view_template\' );
例如:http://example.com/some-page/view/list/
此筛选器将加载模板list.php
而不是默认的页面模板。如果您只是想避免页面加载,那么可以通过多种方式来实现。我在下面列出了其中的一些。
然而,首先你应该问问自己,是否真的需要避免页面加载,是否值得为此付出额外的努力,模板之间是否会有某种平滑的过渡,或者只是突然交换,你将如何处理这种过渡,等等?
以下是我可以想到的各种选择(可能还有许多其他可能的解决方案):
已经为各种视图加载了CSS,然后在按钮上应用一个类,单击该按钮可以更改CSS中的布局,并将视图数据存储为data-
单击按钮上的原始视图属性和加载视图数据使用ajax将具有指定视图的页面模板加载到页面内容中,使用jQuery的.load()
方法,您可以指定要加载页面的哪些部分,以便只替换<div id="content">
内容为<div id="content">
(或者无论您的内容节将要更改的内容是什么)从另一个url
get_template_part(\'content\', $slug);
然后你可以将这些内容注入到你的页面中,只需为点击按钮时要加载的模板发送一个slug,将所有不同的模板HTML加载到页面上,然后只需在点击按钮时显示和隐藏模板,我不知道这些解决方案是否完美,但我想说的是1和3或6的某种组合将是我的选择。我想在大多数情况下,我更喜欢3而不是6,这样我就有了实际存在的页面。如果模板在内容和布局上没有太大的不同,我会说只使用CSS类来重新配置它,但是从上面的图片来看,模板的性质似乎会非常不同,如果你只使用没有JS的CSS版本,你将隐藏和显示图像,而不知道用户是否想看到它们,无缘无故浪费了一些带宽。
我可能会为每个视图设置一个页面,告诉它使用哪个模板,然后当用户单击按钮时,我会从另一个模板中提取内容,然后将其插入当前模板的内容所在的位置。
这样,爬虫程序(无需设置HTML快照)和浏览器因任何原因缺少JS/AJAX的用户就可以使用其他视图。
您还可以从WordPress安装和加载保存的HTML中设置的任何缓存中获益。
而且,如果有人想在推特或Facebook帖子中链接到一个视图,其他单击他们链接的人将被带到该视图,但也可以查看其他视图。
我会让模板按钮链接到这些页面,然后使用e.preventDefault()
在模板按钮锚定标记的click event listener上。
您还可以钩住历史API,将新状态注入浏览器的历史。这样,用户可以在切换模板时使用后退/前进按钮。
您也可以连接历史API,而不需要单独的页面,只需通过历史API中可用的方法更改所有内容,但是如果您的模板以页面的形式存在,那么您就不必处理通过HTML快照和哈希片段使其他模板状态可爬行的头痛问题。(不过,我从未将历史API挂接到我注入的状态也作为独立URL存在于我的网站上的页面上,因此可能会产生一些复杂情况)
这一定是错的。我在测试一些东西,所以我做了:$queried_post = new WP_Query(array(\'posts_per_page\' => 5, \'offset\'=> 1, \'category\' => 1)); var_dump($queried_post->has_posts()); exit; 我得到一个错误: Fatal error: Call to undefined method WP_Query::has_posts() &#