按自定义字段的最后一个字对类别帖子进行排序

时间:2022-01-14 作者:ayyyT5

我正在尝试按所有帖子都具有的自定义字段的最后一个单词排序类别页面。自定义字段表示一个名称,因此最后一个单词将是姓氏。最后,分类页面的帖子应该按姓氏按字母顺序列出。

我如何做到这一点?

Threads I\'m looking at:

My code:

function sort_research_cycles_by_last_name($query) {
    $isResearchCategory = current_cat_is_sub_of(get_category_by_slug(\'research-cycles\')->term_id) || current_cat_is_sub_of(get_category_by_slug(\'profile-expert-fr\')->term_id);
    if ($isResearchCategory && $query->is_main_query()) {
        /*
         * Uncommenting the following two lines and setting orderby to $orderby
         * results in an odd order that I can\'t make sense of.
         */
        // global $wpdb;
        // $orderby = "SUBSTRING_INDEX($wpdb->postmeta.meta_key, \' \', -1)";
        
        /*
         * This currently only orders posts by alpha order of the first word
         */
        $query->set(\'meta_key\',\'wpcf-name-of-researcher\');
        $query->set(\'orderby\',\'meta_value\');
        $query->set(\'order\',\'ASC\');
    }
}
add_action(\'pre_get_posts\',\'sort_research_cycles_by_last_name\');

1 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

但我没有使用WP\\u查询,因为我只是更改类别的顺序。php页面(所以,如果我错了,请纠正我,但在这种情况下不需要WP\\U查询,对吗?)。

是的,你是。整个要点pre_get_posts 操作是在查询对象进入数据库更改参数之前,为您提供对该对象的访问权限。那个$query 变量是WP_Query 对象,并且您的代码可以是这样提示的类型:

function sort_research_cycles_by_last_name( \\WP_Query $query) {
事实上,链接到there的答案与下面编写的SQL部分中需要做的事情最接近。

它涵盖了除如何按元键的最后一个单词排序之外的所有内容。

这是因为使用WP_Query 开箱即用。您需要将姓氏提取到单独的字段中,or 重新排序姓名,使姓氏先出现,例如。Nowell Tom 而不是Tom Nowell.

您可以根据post meta值是否存在、其类型、其值(完整值,而不是子节)来查询post meta值,甚至可以查询其值的子字符串是否存在,例如,查找包含XYZ的所有meta。但是,您不能按子节排序,您所做的任何比较都适用于整个值。

官方文件概述了以下参数:

meta\\u compare(string)–测试“meta\\u值”的运算符。可能的值为“=”、“!=”、\'>;\',\'>;=\',\'<;\',\'<;=\',\'LIKE、NOT LIKE、IN、NOT IN、BETWEEN、NOT BETWEEN、NOT EXISTS、REGEXP、NOT REGEXP或RLIKE。默认值为“=”。

从…起https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters.

REGEXP 是最接近你想要的,但那只会让你走得更远;它是否以空格后的单词yes或no结尾"E;。就排序而言,这将把所有符合条件的人放在末尾或开头,但在这两组中没有字母排序,只有一个有/无。这对过滤有用,但对排序不有用。

原始SQL,不可靠的超硬选项使用原始SQL可能是可行的,但结果将非常不可靠,SQL将被其他插件破坏。正如我在评论中提到的,并非所有人都有姓氏,并非所有姓氏都是一个单词,有些人在姓氏或其他指标后有头衔。双筒姓氏或带有空格的姓氏会有问题,而且比人们意识到的更常见,例如。de Sousa.

如果您选择走这条路,那么这将比使用单独的元键困难得多。提取最后一个单词的查询在其最通用的形式中类似于此SELECT:

SELECT SUBSTRING_INDEX(yourColumnName,’ ‘,-1) as anyVariableName from yourTableName;
您需要找出SQL过滤器的完整列表,然后构建一个检查以仅识别需要此排序的查询,然后解析并重建查询,以便它重写排序部分。

您可能需要创建一个额外的查询来执行此操作,此查询将是slow and expensive。预计性能会受到重大影响。还可能会遇到其他试图修改posts SQL查询的插件的问题。

您还需要弄清楚如何处理带有尾随空格的名称,因为这将导致在与启发式方法一起使用时最后一个字段为空

此解决方案最耗时,手动更新每个条目将更容易、更快。

使用姓氏元真正的解决方案是first_namelast_name 字段,与显示名称字段组合。这样你就可以知道名字和姓氏,但也可以解释修饰语、意符、后缀、标题、中间名等。例如,我自己的名字TomJ Nowell不符合名字/姓氏模式。This is also what WordPress itself does.

如有必要,您可以通过执行WP_Query 对于所有没有last_name 元键,然后抓取名字/姓氏并将其保存为单独的键。分50批执行此操作,以避免超时。当所有的帖子都被处理后,它自然会发现没有新的帖子需要处理,工作也就完成了。在其他地方更新站点,让用户在现有表单中更新这些值,工作就完成了。

另外,拥有名字/姓氏可以让用户选择使用这两个名字进行排序。这是contact应用程序中的一个常见特征,因为存在显著的文化和区域差异。它还允许您对姓氏相同的人进行子排序。