自定义分类法以及当帖子选择了多个术语时如何留在其中?

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). '">&lsaquo;</a></div>';
}
if ( !empty($nextid) ) {
    echo '<div class="newer"><a rel="next" href="' . get_permalink($nextid). '">&rsaquo;</a></div>';
}
?>

当您点击广告时,实际上是在访问该广告的单个页面。在那一刻,WP 并不 know/remember 用户只想看到来自您点击的系统的广告。

您现在如何呈现 previous/next 链接?

一种可能的解决方案是向 URL 添加一个参数,然后在呈现 previous/next 链接时在 PHP 代码中考虑到这一点。 (例如/portfolio/advert-name/?system=mega-drive

编辑:当然 URL 也可以做得更漂亮......如果你想做一些额外的工作,你可以注册一个形式为 [=13= 的永久链接] 例如。但这需要更多的工作。

这样行吗?我认为这将是考虑替代方案的最佳解决方案。

更新: 对于实际实施,get_next_post_whereget_previous_post_where 过滤器可能非常有用。您可以将系统参数考虑到 previous/next 链接。

另一种选择:您也可以设置一个 PHP 会话并以这种方式记住当前系统,但是您将需要一个 PHP 会话,这可不是什么好事,还会妨碍你使用全页缓存(性能优化)。

另一种选择是通过 cookie 记住当前系统客户端。但是在那种情况下,除非您通过 AJAX.

加载 previous/next 链接,否则您会再次遇到缓存问题

阅读您问题的更新后,我有以下注意事项:

  • system 不是有效参数,将在 get_posts() 调用时被忽略。
  • 你用来获取上一个和下一个post的方法是非常低效的,因为你查询整个数据库,然后你把所有的东西都保存在内存中,然后你在梳理整个结果集内存,使用了很多不必要的 ram 和 CPU power

那么我们该如何改进呢?

简单:使用 $post 上的 get_previous_postget_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中的systemGET参数中)并保留所有其他系统作为要排除的系统。

所以让我们构建我们现在需要的东西。

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 . '">&lsaquo;</a></div>';
}
if ( $next_post ) {
    echo '<div class="newer"><a rel="next" href="' . get_permalink($next_post) . $url_suffix . '">&rsaquo;</a></div>';
}

注意:未经测试的代码..所以某处可能存在小错误..如果您遇到此代码的问题,请告诉我..

重要提示: 在系统页面上,您现在还必须将 '?system=current-system' 添加到您呈现的 URL 中。 可能是这样的:echo get_permalink($advert) . '?system=' . $post->post_name(可能会有所不同,具体取决于您的代码在该屏幕上的显示方式..)