[Resolved] Filtering a view by post type within a shortcode

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.

This topic contains 7 replies, has 3 voices.

Last updated by alexG-4 2 months ago.

Assigned support staff: Waqar.

Author
Posts
#1214166

I have a number of views, each of which can apply to many different post types.

I don't want to create a separate view for each of those post types: instead, I want to be able to select which post type to use within the shortcode for that view.

I found some threads explaining how to create a drop-down to select a post type, but I couldn't see how to apply those ideas to my issue.

Thanks.

#1214222

Nigel
Supporter

Languages: English (English ) Spanish (EspaƱol )

Timezone: Europe/London (GMT+01:00)

Hi Alex

That's not an option, it would require custom coding.

Views does have the means to pass arguments to a View so that you can re-use the same View in different contexts (https://toolset.com/documentation/user-guides/passing-arguments-to-views/).

You could, for example, have the same View which displayed posts according to the post status which was set in an attribute when you insert the View.

But, the post type is not filterable.

When you create a View you specify what kind of content the View will display, and so the post type is effectively hard-wired into the View.

You could create you own solution where you registered a custom shortcode to effectively do the same as the wpv-view shortcode (namely it would receive arguments which you then used to render the View using render_view https://toolset.com/documentation/programmer-reference/views-api/#render_view) and you would also include an attribute for the post type you wanted to query and from within this custom shortcode add a wpv_filter_query filter callback to modify the View arguments and change the post_type).

See https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query

#1214330

Hi Nigel

Thanks for telling me what the components of the solution are.

I've managed to get about 75% of the way there. I've defined a shortcode

[kam_json_for_asset post_type="slug-of-post-type"]

and connected it to a view and it works inasmuch as I can invoke the view (without any filtering) via the shortcode.

I've also defined a filter for the view.

My problem is getting the attribute of the short code (post_type) into the filter.

Here is my code so far:

// Add Shortcode
function kam_json_for_asset_func( $atts ) {

	// Attributes
	$atts = shortcode_atts(
		array(
			'post_type' => 'topics',
		),
		$atts,
		'kam_json_for_asset'
	);

	$args = array(
	    'name' => 'asset-json',
	    'post_type' => $atts['post_type']
	);
	return render_view( $args );

}
add_shortcode( 'kam_json_for_asset', 'kam_json_for_asset_func' );

//Filter to return only posts of the selected type
add_filter( 'wpv_filter_query', 'kam_filter_by_post_type', 101, 3 );
function kam_filter_by_post_type( $query_args, $view_settings, $view_id ) {
    
    if ( $view_id == 274 ) { $query_args['post_type'] = ????? }
  
    return $query_args;
}

How do I make that final connection?

Thanks

#1214653

Waqar
Supporter

Languages: English (English )

Timezone: Asia/Karachi (GMT+05:00)

Hi Alex,

Nigel will be away for the next few days, so I'll be happy to follow up.

To filter the view's query and make it use a different post type, you don't need a separate shortcode.

You can simply adjust your "wpv_filter_query" function as:


add_filter( 'wpv_filter_query', 'kam_filter_by_post_type', 1000 , 3 );
function kam_filter_by_post_type( $query_args, $view_settings ) {

	// check if its the specific view
	if ( !is_admin() && ( isset($view_settings['view_id']) && $view_settings['view_id'] == 123) ) {

		// get view's shortcode attributes
		global $WP_Views;
		$attributes = $WP_Views->view_shortcode_attributes;

		// if a post type attribute is available
		if (!empty($attributes[0]['type'])) {
			// set the attribute's value as post type
			$query_args['post_type'][0] = $attributes[0]['type'];
		}

	}

	return $query_args;

}

Note: Please replace 123, with your actual view's ID.

After that, you can pass on the slug of your desired post type, using the "type" attribute, in the view's shortcode directly.

Examples:


// make view get post types with slug "books"
[wpv-view name="view-name" type="books"]

// make view get post types with slug "teams"
[wpv-view name="view-name" type="teams"]

// make view get post types with slug "movies"
[wpv-view name="view-name" type="movies"]

I hope this helps and for more personalized assistance around custom code, you can also consider hiring a professional from our list of recommended contractors:
https://toolset.com/contractors/

regards,
Waqar

#1214817

Hi Waqar

Thanks! That's much simpler.

I'm new to serious PHP development, but I just discovered the KINT debug tool and I'm no longer blind!

Based on that, I worked out that I needed to change the line

$query_args['post_type'][0] = $attributes[0]['type'];

to

$query_args['post_type'] = array($attributes[0]['post']);

and it seems to working perfectly. Unless you tell me I've screwed up, I'll close this ticket.

Alex

#1214818

Sorry - I forgot to ask...

Where can I find documentation of the structure of $WP_Views?

#1215369

Waqar
Supporter

Languages: English (English )

Timezone: Asia/Karachi (GMT+05:00)

Hi Alex,

Thanks for the update and glad it works.

The code change that you've applied is fine and it should work either way.

The $WP_Views is a global variable that is used internally in the code which is why it is not specifically documented, but you'll find the documentation for the available "Views API" hooks/filters at:
https://toolset.com/documentation/programmer-reference/views-filters/

regards,
Waqar

#1215451

My issue is resolved now. Thank you!