自定义分类法以及当帖子选择了多个术语时如何留在其中?
Custom Taxonomies and how to stay in them when the posts have multiple terms selected?
想知道是否有人可以帮我想想这个?
在封锁期间,我一直在建立一个简单的网站来组织我收集的复古游戏广告,涵盖从 Atari 2600 到 N64 的所有系统。我还有 1000 个要添加到网站(需要时间),但我遇到了一个问题,我不确定如何实施修复。
您可以通过单个 post 页面按系统浏览广告,但如果广告涵盖多个系统,它会弄乱上一个和下一个 posts link 并且会让您失望进入另一个系统。
例如:如果您在到达“Battletoads and Double Dragon”时使用下一个和上一个 post link 来浏览 "mega drive / genesis" 部分这次按下一个 post 箭头,您会突然浏览标记为 NES 的广告,因为这是与之相关的第一个术语。
参见:https://www.retrogameads.com/system/mega-drive/ 并点击第一个广告,然后继续按下一个箭头,您就会明白我的意思了。
我想我可以 post 每个系统为每个广告多次,但我不喜欢这样的想法。
有人对我如何计算出用户正在浏览的 Term 并将其保留在那个 Term 中有任何建议吗?
切记,这个网站是一个正在进行的工作,所以设计只是一些基本的东西,直到我找到最好的组织方式。
让我知道你的想法。
更新:
当前获取 prev next posts...
的方法
<?php
$terms = get_the_terms( $post->ID, 'system' );
$i = 0;
$systems = array();
foreach ( $terms as $term ) {
$systems[$i] = $term->slug;
$i++;
}
$postlist_args = array(
'posts_per_page' => -1,
'post_type' => 'portfolio',
'system' => $systems[0],
'order' => 'ASC',
'orderby' => 'title'
);
$postlist = get_posts( $postlist_args );
$ids = array();
foreach ($postlist as $thepost) {
$ids[] = $thepost->ID;
}
$thisindex = array_search($post->ID, $ids);
$previd = $ids[$thisindex-1];
$nextid = $ids[$thisindex+1];
?>
<div class="prev_next">
<?php
if ( !empty($previd) ) {
echo '<div class="older"><a rel="prev" href="' . get_permalink($previd). '">‹</a></div>';
}
if ( !empty($nextid) ) {
echo '<div class="newer"><a rel="next" href="' . get_permalink($nextid). '">›</a></div>';
}
?>
当您点击广告时,实际上是在访问该广告的单个页面。在那一刻,WP 并不 know/remember 用户只想看到来自您点击的系统的广告。
您现在如何呈现 previous/next 链接?
一种可能的解决方案是向 URL 添加一个参数,然后在呈现 previous/next 链接时在 PHP 代码中考虑到这一点。 (例如/portfolio/advert-name/?system=mega-drive
)
编辑:当然 URL 也可以做得更漂亮......如果你想做一些额外的工作,你可以注册一个形式为 [=13= 的永久链接] 例如。但这需要更多的工作。
这样行吗?我认为这将是考虑替代方案的最佳解决方案。
更新: 对于实际实施,get_next_post_where
和 get_previous_post_where
过滤器可能非常有用。您可以将系统参数考虑到 previous/next 链接。
另一种选择:您也可以设置一个 PHP 会话并以这种方式记住当前系统,但是您将需要一个 PHP 会话,这可不是什么好事,还会妨碍你使用全页缓存(性能优化)。
另一种选择是通过 cookie 记住当前系统客户端。但是在那种情况下,除非您通过 AJAX.
加载 previous/next 链接,否则您会再次遇到缓存问题
阅读您问题的更新后,我有以下注意事项:
system
不是有效参数,将在 get_posts()
调用时被忽略。
- 你用来获取上一个和下一个post的方法是非常低效的,因为你查询整个数据库,然后你把所有的东西都保存在内存中,然后你在梳理整个结果集内存,使用了很多不必要的 ram 和 CPU power
那么我们该如何改进呢?
简单:使用 $post
上的 get_previous_post
和 get_next_post
函数。它接受三个参数。这是 get_next_post
的示例(但 get_previous_post
基本相同):
get_next_post( bool $in_same_term = false, array|string $excluded_terms = '', string $taxonomy = 'category' )
现在,如果您将 $in_same_term
设置为 true
,那么下一个 post 将属于 post,它共享至少一个分类术语(在我们的例子中是系统) .
您还必须将 $taxonomy
设置为 system
,因为这是自定义分类法。
另一个参数是$excluded_terms
。可惜没有 $included_terms
否则我们可以把我们想要的系统放在那里。但是我们可以换一种方式...我们可以过滤掉当前系统(在我们的URL中的system
GET参数中)并保留所有其他系统作为要排除的系统。
所以让我们构建我们现在需要的东西。
global $post;
// What system did we come from?
$system = $_GET['system'] ?? null; // Set to null if nothing was specified (uses PHP's null coalescing operator available since PHP 7
// Exclude nothing by default
$excluded_term_ids = [];
// If we came here by clicking on a system, then exclude all other systems so the previous/next links will be of the same system only
if ($system) {
// Retrieve system terms for this post
$terms = get_the_terms( $post, 'system' );
// Filter the list of terms to remove the system we came from
// This way we can create a list of terms to exclude
$excluded_terms = array_filter( $terms, function ( $term ) use ( $system ) {
return $term->slug != $system;
} );
// The get_previous_post and get_next_post functions expect $excluded_terms to be an array of term IDs, so we must map the WP_Term objects into IDs
$excluded_term_ids = array_map( function ( $term ) {
return $term->term_id;
}, $excluded_terms );
}
// Retrieve previous and next post
$previous_post = $post->get_previous_post( true, $excluded_term_ids, 'system' );
$previous_post = $post->get_next_post( true, $excluded_term_ids, 'system' );
// Echo out the page links
// And don't forget to re-add the ?system= parameter to the URL
$url_suffix = $system ? ('?system=' . $system) : '';
if ( $previous_post ) {
echo '<div class="older"><a rel="prev" href="' . get_permalink($previous_post) . $url_suffix . '">‹</a></div>';
}
if ( $next_post ) {
echo '<div class="newer"><a rel="next" href="' . get_permalink($next_post) . $url_suffix . '">›</a></div>';
}
注意:未经测试的代码..所以某处可能存在小错误..如果您遇到此代码的问题,请告诉我..
重要提示: 在系统页面上,您现在还必须将 '?system=current-system' 添加到您呈现的 URL 中。
可能是这样的:echo get_permalink($advert) . '?system=' . $post->post_name
(可能会有所不同,具体取决于您的代码在该屏幕上的显示方式..)
想知道是否有人可以帮我想想这个?
在封锁期间,我一直在建立一个简单的网站来组织我收集的复古游戏广告,涵盖从 Atari 2600 到 N64 的所有系统。我还有 1000 个要添加到网站(需要时间),但我遇到了一个问题,我不确定如何实施修复。
您可以通过单个 post 页面按系统浏览广告,但如果广告涵盖多个系统,它会弄乱上一个和下一个 posts link 并且会让您失望进入另一个系统。
例如:如果您在到达“Battletoads and Double Dragon”时使用下一个和上一个 post link 来浏览 "mega drive / genesis" 部分这次按下一个 post 箭头,您会突然浏览标记为 NES 的广告,因为这是与之相关的第一个术语。
参见:https://www.retrogameads.com/system/mega-drive/ 并点击第一个广告,然后继续按下一个箭头,您就会明白我的意思了。
我想我可以 post 每个系统为每个广告多次,但我不喜欢这样的想法。
有人对我如何计算出用户正在浏览的 Term 并将其保留在那个 Term 中有任何建议吗?
切记,这个网站是一个正在进行的工作,所以设计只是一些基本的东西,直到我找到最好的组织方式。
让我知道你的想法。
更新: 当前获取 prev next posts...
的方法<?php
$terms = get_the_terms( $post->ID, 'system' );
$i = 0;
$systems = array();
foreach ( $terms as $term ) {
$systems[$i] = $term->slug;
$i++;
}
$postlist_args = array(
'posts_per_page' => -1,
'post_type' => 'portfolio',
'system' => $systems[0],
'order' => 'ASC',
'orderby' => 'title'
);
$postlist = get_posts( $postlist_args );
$ids = array();
foreach ($postlist as $thepost) {
$ids[] = $thepost->ID;
}
$thisindex = array_search($post->ID, $ids);
$previd = $ids[$thisindex-1];
$nextid = $ids[$thisindex+1];
?>
<div class="prev_next">
<?php
if ( !empty($previd) ) {
echo '<div class="older"><a rel="prev" href="' . get_permalink($previd). '">‹</a></div>';
}
if ( !empty($nextid) ) {
echo '<div class="newer"><a rel="next" href="' . get_permalink($nextid). '">›</a></div>';
}
?>
当您点击广告时,实际上是在访问该广告的单个页面。在那一刻,WP 并不 know/remember 用户只想看到来自您点击的系统的广告。
您现在如何呈现 previous/next 链接?
一种可能的解决方案是向 URL 添加一个参数,然后在呈现 previous/next 链接时在 PHP 代码中考虑到这一点。 (例如/portfolio/advert-name/?system=mega-drive
)
编辑:当然 URL 也可以做得更漂亮......如果你想做一些额外的工作,你可以注册一个形式为 [=13= 的永久链接] 例如。但这需要更多的工作。
这样行吗?我认为这将是考虑替代方案的最佳解决方案。
更新: 对于实际实施,get_next_post_where
和 get_previous_post_where
过滤器可能非常有用。您可以将系统参数考虑到 previous/next 链接。
另一种选择:您也可以设置一个 PHP 会话并以这种方式记住当前系统,但是您将需要一个 PHP 会话,这可不是什么好事,还会妨碍你使用全页缓存(性能优化)。
另一种选择是通过 cookie 记住当前系统客户端。但是在那种情况下,除非您通过 AJAX.
加载 previous/next 链接,否则您会再次遇到缓存问题阅读您问题的更新后,我有以下注意事项:
system
不是有效参数,将在get_posts()
调用时被忽略。- 你用来获取上一个和下一个post的方法是非常低效的,因为你查询整个数据库,然后你把所有的东西都保存在内存中,然后你在梳理整个结果集内存,使用了很多不必要的 ram 和 CPU power
那么我们该如何改进呢?
简单:使用 $post
上的 get_previous_post
和 get_next_post
函数。它接受三个参数。这是 get_next_post
的示例(但 get_previous_post
基本相同):
get_next_post( bool $in_same_term = false, array|string $excluded_terms = '', string $taxonomy = 'category' )
现在,如果您将 $in_same_term
设置为 true
,那么下一个 post 将属于 post,它共享至少一个分类术语(在我们的例子中是系统) .
您还必须将 $taxonomy
设置为 system
,因为这是自定义分类法。
另一个参数是$excluded_terms
。可惜没有 $included_terms
否则我们可以把我们想要的系统放在那里。但是我们可以换一种方式...我们可以过滤掉当前系统(在我们的URL中的system
GET参数中)并保留所有其他系统作为要排除的系统。
所以让我们构建我们现在需要的东西。
global $post;
// What system did we come from?
$system = $_GET['system'] ?? null; // Set to null if nothing was specified (uses PHP's null coalescing operator available since PHP 7
// Exclude nothing by default
$excluded_term_ids = [];
// If we came here by clicking on a system, then exclude all other systems so the previous/next links will be of the same system only
if ($system) {
// Retrieve system terms for this post
$terms = get_the_terms( $post, 'system' );
// Filter the list of terms to remove the system we came from
// This way we can create a list of terms to exclude
$excluded_terms = array_filter( $terms, function ( $term ) use ( $system ) {
return $term->slug != $system;
} );
// The get_previous_post and get_next_post functions expect $excluded_terms to be an array of term IDs, so we must map the WP_Term objects into IDs
$excluded_term_ids = array_map( function ( $term ) {
return $term->term_id;
}, $excluded_terms );
}
// Retrieve previous and next post
$previous_post = $post->get_previous_post( true, $excluded_term_ids, 'system' );
$previous_post = $post->get_next_post( true, $excluded_term_ids, 'system' );
// Echo out the page links
// And don't forget to re-add the ?system= parameter to the URL
$url_suffix = $system ? ('?system=' . $system) : '';
if ( $previous_post ) {
echo '<div class="older"><a rel="prev" href="' . get_permalink($previous_post) . $url_suffix . '">‹</a></div>';
}
if ( $next_post ) {
echo '<div class="newer"><a rel="next" href="' . get_permalink($next_post) . $url_suffix . '">›</a></div>';
}
注意:未经测试的代码..所以某处可能存在小错误..如果您遇到此代码的问题,请告诉我..
重要提示: 在系统页面上,您现在还必须将 '?system=current-system' 添加到您呈现的 URL 中。
可能是这样的:echo get_permalink($advert) . '?system=' . $post->post_name
(可能会有所不同,具体取决于您的代码在该屏幕上的显示方式..)