As already said in comments, do not ever use extract()
. It’s use was removed from core a few years ago. The codex was also cleaned up. The use of extract()
is even discouraged in PHP. You can rewrite your attributes as follow: (NOTE: Requires PHP 5.4+)
$attributes = shortcode_atts(
[
'posts' => -1,
'order' => '',
'orderby' => '',
'title' => '',
'id' => '',
'category' => ''
],
$atts
);
To access an attribute, you can use the following syntax (which is normal array syntax)
$attribute['category']
If you are going to make use of the 'taxonomy' => 'term'
syntax, you need to make sure your term is passed a slug. Also, when you register your taxonomy, you need to make sure that the query_var
argument is left at default. I would rather suggest in using a proper tax_query
which is more flexible.
In the example below, I have set a field
attribute which is set to slug
by default. This means that category
can be a string or an array of slugs. If you need to pass term ID’s as an integer, string or an array, you can just pass term_id
as value to the field
attribute
add_shortcode( 'faqs', 'cpt_sc' );
function cpt_sc($atts) {
$attributes = shortcode_atts(
[
'posts' => -1,
'order' => '',
'orderby' => '',
'title' => '',
'id' => '',
'category' => ''
'field' => 'slug'
],
$atts
);
// Set up your variables
$posts = $attribute['posts'];
$order = $attribute['order'];
$orderby = $attribute['orderby'];
$id = $attribute['id'];
$category = $attribute['category'];
$field = $attribute['field'];
$args = [
'post_type' => 'cpt_faqs',
'posts_per_page' => $posts,
'order' => $order,
'orderby' => $orderby,
'p' => $id,
'tax_query' => [
[
'taxonomy' => 'cpt_cats',
'field' => $field,
'terms' => $category
]
]
];
// Rest of your shortcode
}
FEW NOTES
-
The code needs at least PHP 5.4. You should however be on PHP 5.6 already to be safe
-
To make the code more dynamic, you can always set attributes for the post type and taxonomy
-
It is always advice-able to escape, sanitize and/or validate any user passed data according to the data type expected. Because you are passing all attributes directly to
WP_Query
, you should be save if you do not sanitize/escape/validate asWP_Query
will take care of that before the SQL query is executed. Still, it is good and recommended to always escape, sanitize and/or validate
EDIT
I actually forgot the handle how to check if a term is passed. You can check if a term is passed, and if the value is empty, you can simply bail or return an error message
Check with attribute
if ( '' == $attribute['category'] )
return;
Check when the variables is set
if ( '' == $category )
return;
EDIT – From comments
If a category is not specified in the shortcode, no results are returned. How can I make all posts return if no categroy is set?
We can display all posts regardless if no term is set by conditionally adding our tax_query
. If a term is passed, add the tax_query
, else, do not append the tax_query
We can try the following
$args = [
'post_type' => 'cpt_faqs',
'posts_per_page' => $posts,
'order' => $order,
'orderby' => $orderby,
'p' => $id,
];
if ( $category ) {
$args['tax_query'] = [
[
'taxonomy' => 'cpt_cats',
'field' => $field,
'terms' => $category
]
];
}