List post by title length

时间:2018-04-09 作者:Aaron McNatt

所以在wordpress上,我有一个自定义的帖子类型,叫做Crosss,我需要在我的搜索结果页面上按最短标题和最长标题的顺序列出它们。我认为这样做的方法是创建一个名为“name length”的自定义字段,然后包含一个函数来计算每个帖子标题中的字母数,并将其指定为该自定义字段中的一个数字,但我尝试得到的代码不起作用。

function update_my_metadata(){
$args = array(
    \'post_type\' => \'crosses\', // Only get the posts
    \'post_status\' => \'publish\', // Only the posts that are published
    \'posts_per_page\'   => -1 // Get every post
);
$posts = get_posts($args);
foreach ( $posts as $post ) {
    $step = get_the_title($post->ID);
    $title_word = count_chars($step);
    update_post_meta( $post->ID, \'name_length_crosses\', $title_word );
  }
}
*编辑:为了澄清,字段中没有填写标题长度。我无法检查数据库以查看是否有任何内容,但我可以查看编辑后屏幕,并且这些值至少没有显示在那里。

*再次编辑:由ACF添加的帖子,使用钩住

add_action(\'init\',\'update_my_metadata\');
*最终编辑:如果有人感兴趣,请在此处发布相关问题:Front of word preference

4 个回复
最合适的回答,由SO网友:Liam Stewart 整理而成

将以下内容添加到functions.php 对于on save。这将在保存时创建一个元值,用于存储帖子标题的长度。

function save_crosses_title_length( $post_id ) {

  $title = get_the_title($post_id);//get the title
  $length = strlen( $title );// get the length of title

  if ( get_post_meta( $post_id, \'name_length_crosses\' ) ) {//if meta value exists
    update_post_meta( $post_id, \'name_length_crosses\', $length );//update meta value
    return;
  }

  add_post_meta( $post_id, \'name_length_crosses\', $length );//else create meta value

}

add_action( \'save_post_crosses\', \'save_crosses_title_length\');
用于实际查询帖子。。使用以下各项。您可以在此处了解有关WP\\U查询的更多信息:https://codex.wordpress.org/Class_Reference/WP_Query

$args = array(
    \'post_type\' => \'crosses\',
    \'meta_key\'  => \'name_length_crosses\',
    \'orderby\'   => \'meta_value_num\',
    \'order\'     => \'ASC\'
);

$custom_query = new WP_Query( $args );


while ( $custom_query->have_posts() ) :
   $custom_query->the_post();

   echo \'<p>\' . the_title() . \'</p>\';

endwhile;
如果您喜欢这种方法,我可以构建一个简单的循环来运行以更新现有帖子。

SO网友:Greg Much

您好@Aaron您可以使用简单的MySQL查询和CHAR\\u LENGTH()函数;)

挂钩posts_orderby 只需自定义“交叉”帖子类型的默认前端查询,过滤器将是在不保存任何元字段的情况下实现所需结果的最快方法。但是,请注意,这实际上会修改所有前端查询,

add_filter(\'posts_orderby\', \'modify_crosses_query\', 10, 2);
function modify_crosses_query($orderby_statement, $wp_query){
  if(is_admin()){ //admin queries.
    return $orderby_statement;
  }
  global $wpdb;
  // Verify correct post type, or any other query variable
  if ($wp_query->get("post_type") === "crosses") {
    $orderby_statement = \'ORDER BY CHAR_LENGTH(\'.$wpdb->posts.\'.post_title) ASC\';
  }
}

SO网友:Souvik Sikdar

您可以尝试此代码。我认为这是最好的分类方法。实际上,在foreach中使用$posts数组之前,需要对其进行排序。

$args = array(
    \'post_type\' => \'crosses\', // Only get the posts
    \'post_status\' => \'publish\', // Only the posts that are published
    \'posts_per_page\'   => -1 // Get every post
);
$posts = get_posts($args);

//This funtion is for sorting the array, depends on post\'s title length
function post_title_length_sort($a, $b){
    return strlen($a->post_title)-strlen($b->post_title);
}
usort($posts, \'post_title_length_sort\');

//You cam check your array now
//Now $posts is sorted by function "post_title_length_sort"
//and you can use the $posts array in a foreach

//print_r($posts);  for checking the array

foreach ( $posts as $post ) {

    //Your code goes here...
}
试试代码,然后告诉我结果。

SO网友:Aurovrata

钩住save_post 只适用于新职位。它不会解决现有员额的问题。这只能用钩子解决init 甚至更好admin_init 并在选项表中标记它,以防止它在每个后续请求上执行。

此外,对于新职位来说,更有效的方法是save_post_{$post_type},

//for existing posts...
add_action(\'admin_init\', \'udpate_crosses_once`);
function udpate_crosses_once(){
  $flag = get_option(\'crosses_updated\', \'no\');
  if(\'no\'===$flag){
    $args = array(
      \'post_type\' => \'crosses\', 
      \'post_status\' => \'publish\', 
      \'posts_per_page\'   => -1 
    );
    $posts = get_posts($args);
    foreach ( $posts as $post ) {
      $length = strlen( trim( $post->post_title ) );
      update_post_meta( $post->ID, \'name_length_crosses\', $length );
    }
    add_option(\'crosses_updated\', \'yes\'); //set flag.
  }
}
//for new posts...
add_action( \'save_post_crosses\', \'save_crosses_title_length\', 10, 2 );
function save_crosses_title_length( $post_id, $post) {
  // Check to see if we are autosaving
  if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE){
    return;
  }
  $length = strlen( trim($post->post_title) );// get the length of title
  //udpate the meta field, in case the post title is being updated
  update_post_meta( $post_id, \'name_length_crosses\', $length );
  //note, no need to add_post_meta, udpate_post_meta fn will add the field if not found.
}
对于前端显示器,

$crossposts = get_posts(array(
    \'post_type\' => \'crosses\',
    \'meta_key\'  => \'name_length_crosses\',
    \'orderby\'   => \'meta_value_num\',
    \'order\'     => \'ASC\'
));
if ( $crossposts ) {
    foreach ( $crossposts as $post ) :
        setup_postdata( $crossposts ); ?>
        <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
        <?php the_content(); ?>
    <?php
    endforeach; 
    wp_reset_postdata(); //Important, reset the query post data.
}

结束

相关推荐

Php将博客文章显示为网格视图

我目前正在home.php 文件,我计划在“网格视图”中显示我的最后一篇博客文章,这样一行中就有4个容器,包含标题和更多信息。我试过一些东西,但都没有按我想要的方式工作。我做的最后一件事是像这样放置一个for循环:<?php for ($x = 1; $x <= 6; $x++) : ?> <div id=\"home_post_<?php echo $x ?> \" class=\"home_post\">