Skip Navigation

[Resolved] how to order a view by a specific field orde

This support ticket is created 7 years, 5 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 18 replies, has 2 voices.

Last updated by Christian Cox 7 years, 5 months ago.

Assisted by: Christian Cox.

Author
Posts
#526673

bsd
I would like to make a view that shows a specific category page in a specific order.
I mean to add to the each post a "order" numeric field - wich the view will use it to show by this order.
Each post can pertence to more than one category.
What is the best way to do this in toolset?

#526722

Hi, you can use some custom code with our filter "wpv-filter-query". Add the following code to functions.php:

add_filter( 'wpv_filter_query', 'hook_search_custom_fields', 10, 3 );
function hook_search_custom_fields( $query_args, $view_settings, $view_ID ) {
    if ( $view_ID == 123 ) {
      $query_args['orderby'] = array( 'meta_value_num');
      $query_args['meta_key'] = 'wpcf-customfieldslug'; 
      $query_args['meta_type'] = 'numeric';
    }
      
return $query_args;
}

Change "123" to your View ID and change "wpcf-customfieldslug" to use the correct custom field slug.

#526733

bsd

and than the view will be ordered by the numeric custom field?
but what will happen if the same post has to have two or more custom fields - each one to define its position in a specific category posts page list?
thanks

#526742

and than the view will be ordered by the numeric custom field?
That's correct. This setting will override any sorting settings you have chosen in the View editor.

but what will happen if the same post has to have two or more custom fields - each one to define its position in a specific category posts page list?
This will not cause any problems with the code as it is now. If you want to order by a different custom field for different category post pages, you can create different Views for each category post page. Then you can modify your code in functions.php to work with these new Views. In this example I have added another View with ID 124, and custom field slug "othercustomfieldslug":

add_filter( 'wpv_filter_query', 'hook_search_custom_fields', 10, 3 );
function hook_search_custom_fields( $query_args, $view_settings, $view_ID ) {
    if ( $view_ID == 123 ) {
      $query_args['orderby'] = array( 'meta_value_num');
      $query_args['meta_key'] = 'wpcf-customfieldslug'; 
      $query_args['meta_type'] = 'numeric';
    }
    if ( $view_ID == 124 ) {
      $query_args['orderby'] = array( 'meta_value_num');
      $query_args['meta_key'] = 'wpcf-othercustomfieldslug'; 
      $query_args['meta_type'] = 'numeric';
    }
       
return $query_args;
}

Copy an entire "if" block and paste it for each View, then update your View ID and custom field slug for the current category page. Place your different Views on each category page.

#527589

bsd

i see, but it should very hard to make the same template for each category - and than if necessary change all of them if i want to change something in the category template blog appearence.
I thought about making a child post for posts and put tehre to fields:
1- category slug
2- archive order place

than i can for each post fix what is the place for each category
than i should create a general category archive template that check acording to the "child post order" and make sort according to the "archive order place" field (in the post child post).

is it clear?

i Tried to create such customized post called "category order"- and built a view for native wp posts - and tried to sort it by the child post field "archive order place" - but it show no posts
I tried to see the view as a list with the "archive order place" - and it show no value

#527630
Screen Shot 2017-05-23 at 2.25.24 PM.png

You can make some minor changes to use 1 View for all categories, without needing to add those child posts. Here is the updated filter code:

add_filter( 'wpv_filter_query', 'hook_search_custom_fields', 10, 3 );
function hook_search_custom_fields( $query_args, $view_settings, $view_ID ) {
  // array of categories and their corresponding custom field slugs for sorting
  $array = array(
    '1' => 'wpcf-custom-fieldslug',
    '2' => 'wpcf-custom-otherfieldslug'
  );
  if ( $view_ID == 31 && isset($query_args['tax_query'][0]['terms'][0])) {
     $query_args['orderby'] = array( 'meta_value_num');
     $query_args['meta_key'] = $array[$query_args['tax_query'][0]['terms'][0]];
     $query_args['meta_type'] = 'numeric';
   }
   return $query_args;
}

In this example, I have added an array of custom field slugs. The keys for this array represent the category ID, and the values represent the slug to be used for sorting. So if the category ID is 1, it will sort based on 'wpcf-custom-fieldslug' but if the category ID is 2, it will sort on 'wpcf-custom-otherfieldslug'. You can add items to this array and change it however you want, then make sure to update the $view_ID value.

Then, set your View to have a category filter based on a shortcode attribute. The category slug should be specified by 'wpvcategory'. Please see the attached screenshot for more information about that.

Finally, add your View to any page using a shortcode attribute that includes the category slug:

[wpv-view name="category-view" wpvcategory="uncategorized"]

...or...

[wpv-view name="category-view" wpvcategory="category-slug-1"]

... and so on. This way you can reuse the same View for different categories. Let me know if you need help with this, or if it resolves the problem for you.

#527986

Thanks - i will try
but what about the wordpress native category blog template?
if i make a view to change it - i am not going to call this view from a page - how it should work than?

#528046

I don't quite understand, sorry. This approach only works for Views. Would you like to sort the native category archives using the custom field as well?

#528371

yes,
I meant that i want to make a "wordpress archive" with views to change the native category appearence.
This worpress archive will be sorted according to an customized order field in the posts.
I understand that the solution you wrote me is in case i call a view from a specific page and than add the shortcode you wrote in the parameters
But when i build in views a "wp archive" it means that the category page will be called from any category link in the site.
How should i do than
Thanks!

#528560

Okay a bit of refactoring will allow you to use the same array for both a View and for the WordPress Archive. Try the following code format:

$toolset_order_array = array(
  '1' => 'wpcf-custom-fieldslug',
  '2' => 'wpcf-custom-otherfieldslug'
);

add_filter( 'wpv_filter_query', 'hook_search_custom_fields', 10, 3 );
function hook_search_custom_fields( $query_args, $view_settings, $view_ID ) {
  global $toolset_order_array;
  // array of categories and their corresponding custom field slugs for sorting
  if ( $view_ID == 31 && isset($query_args['tax_query'][0]['terms'][0])) {
     $query_args['orderby'] = array( 'meta_value_num');
     $query_args['meta_key'] = $toolset_order_array[$query_args['tax_query'][0]['terms'][0]];
     $query_args['meta_type'] = 'numeric';
   }
   return $query_args;
}

add_filter( 'pre_get_posts' , 'custom_cpt_archive_order', 10000 );
function custom_cpt_archive_order( $query ) {
  global $toolset_order_array;
  // Check if the query is for an archive
  $category_name = $query->get('category_name');
  if ( is_archive() && $category_name ) {
    $category = get_term_by('slug', $category_name, 'category');
    // Query was for archive, then set order
    if( isset($toolset_order_array[$category->term_id])) {
      $query->set('orderby', 'meta_value_num');
      $query->set('order', 'ASC');
      $query->set('meta_key', $toolset_order_array[$category->term_id]);
      $query->set('meta_type', 'numeric');
    }
  }
}
#529440

thanks

i tried your code with category number 37:

// order categories 37 by post-place
$toolset_order_array = array(
  '37' => 'post-place',
  
);
 
add_filter( 'wpv_filter_query', 'hook_search_custom_fields', 10, 3 );
function hook_search_custom_fields( $query_args, $view_settings, $view_ID ) {
  global $toolset_order_array;
  // array of categories and their corresponding custom field slugs for sorting
  if ( $view_ID == 31 && isset($query_args['tax_query'][0]['terms'][0])) {
     $query_args['orderby'] = array( 'meta_value_num');
     $query_args['meta_key'] = $toolset_order_array[$query_args['tax_query'][0]['terms'][0]];
     $query_args['meta_type'] = 'numeric';
   }
   return $query_args;
}
 
add_filter( 'pre_get_posts' , 'custom_cpt_archive_order', 10000 );
function custom_cpt_archive_order( $query ) {
  global $toolset_order_array;
  // Check if the query is for an archive
  $category_name = $query->get('category_name');
  if ( is_archive() && $category_name ) {
    $category = get_term_by('slug', $category_name, 'category');
    // Query was for archive, then set order
    if( isset($toolset_order_array[$category->term_id])) {
      $query->set('orderby', 'meta_value_num');
      $query->set('order', 'ASC');
      $query->set('meta_key', $toolset_order_array[$category->term_id]);
      $query->set('meta_type', 'numeric');
    }
  }
}

but the result is an empty results category page.
i tried to order 3 of the category posts in the field i added with "types" - "post-place"
what should be the problem?
the results are showed by avada category page format

also, what will happen with posts with no "post-place" field value?
is it possible to make a secundary order by date for empty values?
thanks

#529451

...the field i added with "types" - "post-place"
If you added the field with Types, the correct slug will be "wpcf-post-place", since all Types custom fields should use the wpcf- prefix here. Please try "wpcf-post-place".

also, what will happen with posts with no "post-place" field value?
is it possible to make a secundary order by date for empty values?

You can pass an array of order options like so:

$query_args['orderby'] = array( 'meta_value_num' => 'ASC', 'post_date' => 'DESC');

...and...

$query->set('orderby', array('meta_value_num'=> 'ASC', 'post_date' => 'DESC'));
#529461

bsd

Good! now it works - i ordered 3 posts with sucsess.

Now about the secundary order field (date) - i don't understand where exactly to put the codes you sent... i dont understand too much in php programming...
is it after the first code? inside {} of it or later?
thanks

#529468
Screen Shot 2017-05-28 at 1.30.18 PM.png

Please see the screenshot for more instructions.

#529521

tried the code according to your instructions:

 
// order categories 37 by post-place
$toolset_order_array = array(
  '37' => 'wpcf-post-place',
  
);
 
add_filter( 'wpv_filter_query', 'hook_search_custom_fields', 10, 3 );
function hook_search_custom_fields( $query_args, $view_settings, $view_ID ) {
  global $toolset_order_array;
  // array of categories and their corresponding custom field slugs for sorting
  if ( $view_ID == 31 && isset($query_args['tax_query'][0]['terms'][0])) {
     $query_args['orderby'] = array( 'meta_value_num' => 'ASC', 'post_date' => 'DESC');

     $query_args['meta_key'] = $toolset_order_array[$query_args['tax_query'][0]['terms'][0]];
     $query_args['meta_type'] = 'numeric';
   }
   return $query_args;
}
 
add_filter( 'pre_get_posts' , 'custom_cpt_archive_order', 10000 );
function custom_cpt_archive_order( $query ) {
  global $toolset_order_array;
  // Check if the query is for an archive
  $category_name = $query->get('category_name');
  if ( is_archive() && $category_name ) {
    $category = get_term_by('slug', $category_name, 'category');
    // Query was for archive, then set order
    if( isset($toolset_order_array[$category->term_id])) {
      $query->set('orderby', array('meta_value_num'=> 'ASC', 'post_date' => 'DESC'));
      $query->set('orderby', array('meta_value_num'=> 'ASC', 'post_date' => 'DESC'));

      $query->set('meta_key', $toolset_order_array[$category->term_id]);
      $query->set('meta_type', 'numeric');
    }
  }
}

still showing only results with post-place values...
something i did wrong?
thanks