How can I add an else statement to this code so if there are no posts, the output would be "There are currently no posts."
function jobs_posts_shortcode($atts, $content = null) {
global $post;
extract(shortcode_atts(array(
'category_name' => 'jobs',
'num' => '5',
'order' => 'DESC',
'orderby' => 'post_date',
), $atts));
$args = array(
'category_name' => $category_name,
'posts_per_page' => $num,
'order' => $order,
'orderby' => $orderby,
);
$output = '';
$posts = get_posts($args);
foreach($posts as $post) {
setup_postdata($post);
$output .= ''.get_the_title().'<br>'.get_the_date().'<br><br>';
}
wp_reset_postdata();
return ''. $output .'';
}
add_shortcode('jobs_posts', 'jobs_posts_shortcode');
You can simply check $posts are empty or not by using the PHP empty() function. check below code.
function jobs_posts_shortcode($atts, $content = null) {
global $post;
extract( shortcode_atts( array(
'category_name' => 'jobs',
'num' => '5',
'order' => 'DESC',
'orderby' => 'post_date',
), $atts ) );
$args = array(
'category_name' => $category_name,
'posts_per_page' => $num,
'order' => $order,
'orderby' => $orderby,
);
$output = '';
$posts = get_posts($args);
if( !empty( $posts ) ){
foreach( $posts as $post ) {
setup_postdata($post);
$output .= ''.get_the_title().'<br>'.get_the_date().'<br><br>';
}
}else{
$output .= __('There are currently no posts.','textdomain');
}
wp_reset_postdata();
return ''. $output .'';
}
add_shortcode( 'jobs_posts', 'jobs_posts_shortcode' );
Related
I am having problem ordering the posts based on the title length. Here is my code:
<?php
$terms = get_terms(array(
'taxonomy' => 'vendor_category',
'slug' => 'venues',
'hide_empty' => false
));
?>
<?php
foreach ($terms as $term) {
$eventargs = array(
'post_type' => 'vendor',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'meta_key' => 'primary_category',
'meta_value' => $term->term_id,
);
$eventqry = new WP_Query($eventargs);
?>
How can i sort the posts based on the title length in ascending order.
You can save title length in post meta on save_post hook. and then you can retrieve post order by post meta value.
You can use save_post hook to save the post meta. put this code in your active theme.
//for existing vendors
add_action('admin_init', 'udpate_existing_vendor');
function udpate_existing_vendor(){
$existing_vendor_updated = get_option('existing_vendor_updated', 'no');
if( $existing_vendor_updated == 'no' ){
$vendor_args = array(
'post_type' => 'vendor',
'post_status' => 'publish',
'posts_per_page' => -1
);
$vendors = new WP_Query( $vendor_args );
if( $vendors->have_posts() ) {
while ( $vendors->have_posts() ) { $vendors->the_post();
$length = strlen( get_the_title() );
update_post_meta( get_the_ID(), 'title_length', $length );
} wp_reset_postdata();
}
update_option('existing_vendor_updated', 'yes');
}
}
// for new vendor
function save_vendor_title_length( $post_id ) {
$length = strlen( get_the_title( $post_id ) );
update_post_meta( $post_id, 'title_length', $length );
}
add_action( 'save_post_vendor', 'save_vendor_title_length');
Here your query will look like.
$terms = get_terms(array(
'taxonomy' => 'vendor_category',
'slug' => 'venues',
'hide_empty' => false
));
foreach ($terms as $term) {
$eventargs = array(
'post_type' => 'vendor',
'posts_per_page' => -1,
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_key' => 'title_length'
);
$eventqry = new WP_Query( $eventargs );
}
I've created a custom shortcode to display products with a minimum stock amount and would like to add pagination to the results as well as calling the woocommerce-ordering dropdown to be displayed on the page.
Here's the shortcode:
// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'title',
'order' => 'asc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
),
$atts, 'minimum_stock'
);
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php woocommerce_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
wp_reset_postdata();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
Any help would be very much appreciated!
Kind regards,
JP
Okay, so I've got pagination working and tidied things up a bit (it was throwing some errors in the debug log), the code now looks like this:
// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $product, $woocommerce, $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'title',
'order' => 'asc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
),
$atts, 'minimum_stock'
);
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'paged' => $paged,
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
if($products->max_num_pages>1){
?>
<nav class="woocommerce-pagination">
<?php echo paginate_links( apply_filters(
'woocommerce_pagination_args', array(
'base' => esc_url( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ),
'format' => '',
'current' => max( 1, get_query_var( 'paged' ) ),
'total' => $products->max_num_pages,
'prev_text' => '←',
'next_text' => '→',
'type' => 'list',
'end_size' => 3,
'mid_size' => 3
)
)
);
?>
</nav>
<?php }
woocommerce_reset_loop();
wp_reset_postdata();
$return = '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
// Remove ordering query arguments
WC()->query->remove_ordering_args();
return $return;
}
Does anyone know how I can now call the woocommerce-ordering dropdown?
I've tried adding:
<?php do_action( 'woocommerce_before_shop_loop' ); ?>
But this doesn't seem to work, when I check the page it does have the 'woocommerce-notices-wrapper' but there's no sign of the 'woocommerce_catalog_ordering' that I thought should also be called with 'woocommerce_before_shop_loop'.
Any and all help will be very much appreciated :)
Update:
I found this question Adding 'sort by' drop down on custom page using woocommerce short code which gave me the answer I needed to add the woocommerce-ordering dropdown.
Here's my updated code:
// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'date',
'order' => 'desc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
), $atts );
if ( ! $atts['category'] ) {
return '';
}
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// Default ordering args
$ordering_args = WC()->query->get_catalog_ordering_args( $atts['orderby'],
$atts['order'] );
$orderby = 'date';
$order = 'desc';
if ( isset( $_GET['orderby'] ) ) {
$getorderby = $_GET['orderby'];
}
if ($getorderby == 'date') {
$orderby = 'date';
$order = 'desc';
} elseif ($getorderby == 'sku_desc') {
$orderby = 'meta_value';
$order = 'desc';
$meta_key = '_sku';
} elseif ($getorderby == 'sku_asc') {
$orderby = 'meta_value';
$order = 'asc';
$meta_key = '_sku';
}
$args = array(
'post_type' => array( 'product', 'product_variation' ),
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $orderby, // $ordering_args['orderby'],
'order' => $order, // $ordering_args['order'],
'paged' => $paged,
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<div style="width:100%;">
<div style="float:right">
<form class="woocommerce-ordering" method="get">
<select name="orderby" class="orderby">
<?php
$catalog_orderby = apply_filters( 'woocommerce_catalog_orderby', array(
'date' => __( 'Sort by latest', 'woocommerce' ),
'sku_asc' => __( 'A-Z / Low to High Numbers', 'woocommerce' ),
'sku_desc' => __( 'Z-A / High to Low Numbers', 'woocommerce' )
) );
foreach ( $catalog_orderby as $id => $name )
echo '<option value="' . esc_attr( $id ) . '" ' . selected( $getorderby, $id, false ) . '>' . esc_attr( $name ) . '</option>';
?>
</select>
<?php
// Keep query string vars intact
foreach ( $_GET as $key => $val ) {
if ( 'orderby' === $key || 'submit' === $key )
continue;
if ( is_array( $val ) ) {
foreach( $val as $innerVal ) {
echo '<input type="hidden" name="' . esc_attr( $key ) . '[]" value="' . esc_attr( $innerVal ) . '" />';
}
} else {
echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $val ) . '" />';
}
}
?>
</form>
</div>
</div>
<div style="clear:both;"></div>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
if($products->max_num_pages>1){
?>
<nav class="woocommerce-pagination">
<?php echo paginate_links( apply_filters(
'woocommerce_pagination_args', array(
'base' => esc_url( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ),
'format' => '',
'current' => max( 1, get_query_var( 'paged' ) ),
'total' => $products->max_num_pages,
'prev_text' => '←',
'next_text' => '→',
'type' => 'list',
'end_size' => 3,
'mid_size' => 3
)
)
);
?>
</nav>
<?php }
woocommerce_reset_loop();
wp_reset_postdata();
$return = '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
// Remove ordering query arguments
WC()->query->remove_ordering_args();
return $return;
}
I hope someone might find this helpful :)
Kind regards,
JP
What is the syntax to filter products by their type in woocommerce shortcodes? I tried the following unsuccessfully.
[products product_type="simple" per_page="12" columns="3"]
and
[products type="simple" per_page="12" columns="3"]
//products by type shortcode
function products_by_type($atts) {
$atts = shortcode_atts( array(
'columns' => '4',
'orderby' => 'title',
'order' => 'asc',
'ids' => '',
'skus' => '',
'product_type' => 'simple'
), $atts );
$query_args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'posts_per_page' => -1,
'meta_query' => WC()->query->get_meta_query(),
'tax_query' => array(
array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => $atts['product_type'],
),
),
);
if ( ! empty( $atts['skus'] ) ) {
$query_args['meta_query'][] = array(
'key' => '_sku',
'value' => array_map( 'trim', explode( ',', $atts['skus'] ) ),
'compare' => 'IN'
);
}
if ( ! empty( $atts['ids'] ) ) {
$query_args['post__in'] = array_map( 'trim', explode( ',', $atts['ids'] ) );
}
return product_loop( $query_args, $atts, 'products' );
}
function product_loop( $query_args, $atts, $loop_name ) {
global $woocommerce_loop;
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $query_args, $atts, $loop_name ) );
$columns = absint( $atts['columns'] );
$woocommerce_loop['columns'] = $columns;
ob_start();
if ( $products->have_posts() ) {
do_action( "woocommerce_shortcode_before_{$loop_name}_loop" );
woocommerce_product_loop_start();
while ( $products->have_posts() ) {
$products->the_post();
wc_get_template_part( 'content', 'product' );
}
woocommerce_product_loop_end();
do_action( "woocommerce_shortcode_after_{$loop_name}_loop" );
}
woocommerce_reset_loop();
wp_reset_postdata();
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}
add_shortcode( apply_filters( "products_by_type_shortcode_tag", "products_by_type" ), "products_by_type" );
I have done this query and is working.I have a lot of child posts and i plan to display only child posts when listing the archive page of my custom post type city-guide.
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged
);
$query = new WP_Query( $args );
?>
<?php $i=1; while( $query->have_posts() ): $query->the_post(); ?>
{
.....
}
I have tried
$all = get_posts(array('post_type'=> 'city-guide', 'posts_per_page' => -1));
$parents = array();
foreach ($all as $single)
{
$kids = get_children($single->ID);
if(isset($kids) && !empty($kids) && count($kids) >= 1)
{
$parents[] = $single->ID;
}
}
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'post__not_in' => $parents,
'posts_per_page' => 36,
'paged' => $paged
);
$query = new WP_Query( $args );
?>
<?php $i=1; while( $query->have_posts() ): $query->the_post(); ?>
{
....
}
This did not work.Please help me find out where i went wrong.
I know it's an old question but hoping I can help someone that finds their way here looking for the same thing I was.
You can show ONLY child posts by excluding any posts with post_parent = 0 using the 'post_parent__not_in' argument:
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged,
'post_parent__not_in' => array(0)
);
This avoids the need to loop thru each parent post to get each child.
I see you are trying to push the IDs into an array but why not just use the IDs while you are looping through them while getting the children within the loop at the same time? The example below is how I would tackle this.
<?php
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged
);
$query = new WP_Query( $args );
$i=1; while( $query->have_posts() ): $query->the_post();
$parentID = get_the_ID();
$childrenArgs = array(
'post_type' => 'page',
'post_parent' => $parentID ,
);
$children = get_children($childrenArgs);
foreach ($children as $child){
echo '<h1>' . $child -> post_title . '</h1>';
$content = $child -> post_content;
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
echo $content;
}
endwhile;
?>
I think you need to look into the action pre_get_posts. Something like this in your functions.php would do the trick.
function namespace_custom_query_vars( $query ) {
if ( !is_admin() && $query->is_main_query()) {
if ( $query->query["post_type"] == 'custom_post_type' ) {
$query->set( 'post_parent__not_in', 0 );
}
}
return $query;
}
add_action( 'pre_get_posts', 'namespace_custom_query_vars' );
There's a decent post about this here. Though note that the code on this page does not compile for small syntax errors.
What about using relations? A simple disjunctive union should do the charm.
$args = array(
'post_type' => POST_TYPE,
'posts_per_page' => 36,
'orderby' => 'date',
'order' => 'DESC',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => POST_TAXONOMY,
'field' => 'slug',
'terms' => $tax_slug,
'include_children' => true
),
array(
'taxonomy' => POST_TAXONOMY,
'field' => 'slug',
'terms' => $tax_slug,
'include_children' => false,
'operator' => 'NOT IN'
)
)
);
Or is there a reason why not to consider this?
The $event_count variable doesn't prints anything, what am i doing wrong?
global $post;
$event_count = get_post_meta($post->ID, 'eab_event-bp-group_event', true);
$args = array(
'post_type' => 'incsub_event',
'posts_per_page' => -1,
'meta_key' => 'eab_event-bp-group_event',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'eab_event-bp-group_event',
'value' => $event_count,
),
),
);
$my_query = new WP_Query( $args );
if ( $my_query->have_posts() ) {
echo '<ul>';
while ( $my_query->have_posts() ) {
$my_query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
echo '</ul>';
} else {
}
wp_reset_postdata();`