I created a simple shortcode
add_shortcode('lichthidau', 'hp_lich_thi_dau');
function hp_lich_thi_dau( $atts ) {
$output = '';
extract( shortcode_atts( array( 'posttype' => 'lich' ), $atts) );
$args = array(
'post_type' => $posttype,
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
$itemprop = '';
if ( 'microdata' === generate_get_schema_type() ) {
$itemprop = ' itemprop="text"';
}
echo '<div class="bang-lich">';
//while ( $the_query->have_posts() ) {
$output = $the_query->found_posts;
//}
echo '</div>';
}
wp_reset_postdata();
return $output;
}
Then put it in Gutenberg shortcode block [lichthidau] in a page (ID = 106, for example).
Without while loop, it's showing 2, which is the count of returning posts, and it's correct. However, if I enable while loop, it's taking the current page ID (106), and creating unlimited loops, while the expected result should be only two number 2.
Can anyone advice why and how to fix, please?
Thanks.
The first problem is that you're using echo in the shortcode output. The shortcode can only return content, and echo will produce unexpected results.
The second problem is trying to output the $output = $the_query->found_posts; within your loop. If you return something else, it will work.
This returns your loop with the post titles.
add_shortcode( 'lichthidau', 'hp_lich_thi_dau' );
function hp_lich_thi_dau( $atts ) {
$output = '';
extract( shortcode_atts( array( 'posttype' => 'lich' ), $atts ) );
$args = array(
'post_type' => $posttype,
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
$itemprop = '';
if ( 'microdata' === generate_get_schema_type() ) {
$itemprop = ' itemprop="text"';
}
$output = '<div class="bang-lich">';
while ( $the_query->have_posts() ) {
$the_query->the_post();
$output .= get_the_title( get_the_ID() ) . '</br>';
}
$output .= '</div>';
}
wp_reset_postdata();
return $output;
}
in our wordpress site we modified image gallery style with using theme functions. We changed div classes, ids to use jquery image slider.
To make this we used this codes on functions.php
add_filter('post_gallery', 'ct_post_gallery', 10, 2);
function ct_post_gallery($output, $attr) {
global $post;
if (isset($attr['orderby'])) {
$attr['orderby'] = sanitize_sql_orderby($attr['orderby']);
if (!$attr['orderby'])
unset($attr['orderby']);
}
extract(shortcode_atts(array(
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post->ID,
'itemtag' => 'dl',
'icontag' => 'dt',
'captiontag' => 'dd',
'columns' => 3,
'size' => 'thumbnail',
'include' => '',
'exclude' => ''
), $attr));
$id = intval($id);
if ('RAND' == $order) $orderby = 'none';
if (!empty($include)) {
$include = preg_replace('/[^0-9,]+/', '', $include);
$_attachments = get_posts(array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby));
$attachments = array();
foreach ($_attachments as $key => $val) {
$attachments[$val->ID] = $_attachments[$key];
}
}
if (empty($attachments)) return '';
// Here's your actual output, you may customize it to your need
$output = "<div id=\"icmimarlikreferans\">\n";
$output .= "<ul id=\"icmimarlikreferansimg\">\n";
// Now you loop through each attachment
foreach ($attachments as $id => $attachment) {
// Fetch the thumbnail (or full image, it's up to you)
// $img = wp_get_attachment_image_src($id, 'medium');
// $img = wp_get_attachment_image_src($id, 'my-custom-image-size');
$img = wp_get_attachment_image_src($id, 'full');
$output .= "<li class=\"item\">\n";
$output .= "<img src=\"{$img[0]}\" width=\"{$img[1]}\" height=\"{$img[2]}\" alt=\"\" />\n";
$output .= "</li>\n";
}
$output .= "</ul>\n";
$output .= "</div>\n";
return $output;
}
When we use it without making edits WordPress displaying image captions in single post pages at bottom of images in galleries . But when we use this code at functions.php captions are not displaying. We know the caption codes are missing, in this code block what we are using...
We tried to add caption functions in this codes but we have failed.
We need to display image captions at bottom of images in galleries.
We will love you if you help.
I am using taxonomy-images/ WordPress plugin (https://en-gb.wordpress.org/plugins/taxonomy-images/)
Target: I have got a poster taxonomy and I would like to display term name and term image. I would like to be able to display, retrieve ALL terms in my taxonomy, no matter term name is empty.
Issue: But if both data are not entered I can not display the term. I am not managing to correctly make use of 'hide_empty'.
Any help appreciated.
Thanks
<?php
/*
Template Name: gof Poster Home Page */
// https://en-gb.wordpress.org/plugins/taxonomy-images/
?>
<?php
$taxonomy = 'month-category';
$orderby = 'name';
$order = 'ASC';
$show_count = false;
$pad_counts = false;
$hierarchical = true;
$hide_empty = false;
$title = '';
$images = 'image_id';
$args = array(
'taxonomy' = $taxonomy,
'orderby' = $orderby,
'order' = $order,
'show_count' = $show_count,
'pad_counts' = $pad_counts,
'hierarchical' = $hierarchical,
'hide_empty' = $hide_empty,
'title_li' = $title
);
//$terms = get_terms( 'month-category', $args );
// $terms = apply_filters( 'taxonomy-images-get-terms', 'month-category', $args);
$terms = apply_filters( 'taxonomy-images-get-terms', '', $args);
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
$count = count( $terms );
$i = 0;
$term_list = '<div id="poster-cat-wrapper">';
foreach ( $terms as $term ) {
$term_list .=
'<div class="poster-cat">' .
'<a href="/posters/?gof=' . $term->name . '">' .
wp_get_attachment_image( $term->$images, 'detail' ) .
'<p>' . $term->name . '</p>' .
'</a>' .
'</div>';
$i++;
// '' . $term->name . ''
if ( $count != $i ) {
$term_list .= ' ';
}
else {
$term_list .= '</div>';
}
}
}
?>
I cannot figure out how to do this either, but I found a nasty hack. Look for this part in 'public-filters.php' in '/plugins/taxonomy-images/':
$args = wp_parse_args( $args, array(
'cache_images' => true,
'having_images' => true,
'taxonomy' => 'category',
'term_args' => array('hide_empty' => false),
) );
Change it to this:
$args = wp_parse_args( $args, array(
'cache_images' => true,
'having_images' => true,
'taxonomy' => 'category',
'term_args' => array('hide_empty' => false),
) );
Once again: Know that this is NOT the right solution! You should write a filter that does this for you. Every plugin update will break this functionality.
Good Morning
i have a woocommerce website, using visual composer i have added featured product and recent product in Homepage, How can we hide Price from featured and recent products?
I tried following code
remove_action( woocommerce_after_shop_loop_item_title','woocommerce_template_loop_price', 10 );
This will remove price from Shop, How we can do for visual composer featured products. Any suggestion.
And also is there any plugin in woocommerce, from that we can click a category that will show pop up message once clicked i need to enter that category?
Create a new file named class-custom_shortcodes.php in your theme folder and Add this code in functions.php.
What I have changed i have added custom class to featured and recent products.
Class for Featured Product : custom_featured
Class for Recent Product : custom_recent_products
Use above classes to hide the price on the home page by using function print_my_inline_style_custom.
function print_my_inline_style_custom() {
if(is_home()) {
echo '<style type="text/css">
.custom_featured , custom_recent_products {
display:none;
}
</style>';
}
}
add_action( 'wp_footer', 'print_my_inline_style_custom' );
class-custom_shortcodes.php
<?php
class WC_Custom_Shortcodes {
/**
* Init shortcodes
*/
public static function init() {
// Define shortcodes
$shortcodes = array(
'product' => __CLASS__ . '::product',
'product_page' => __CLASS__ . '::product_page',
'product_category' => __CLASS__ . '::product_category',
'product_categories' => __CLASS__ . '::product_categories',
'add_to_cart' => __CLASS__ . '::product_add_to_cart',
'add_to_cart_url' => __CLASS__ . '::product_add_to_cart_url',
'products' => __CLASS__ . '::products',
'recent_products' => __CLASS__ . '::recent_products',
'sale_products' => __CLASS__ . '::sale_products',
'best_selling_products' => __CLASS__ . '::best_selling_products',
'top_rated_products' => __CLASS__ . '::top_rated_products',
'featured_products' => __CLASS__ . '::featured_products',
'product_attribute' => __CLASS__ . '::product_attribute',
'related_products' => __CLASS__ . '::related_products',
'shop_messages' => __CLASS__ . '::shop_messages',
'woocommerce_order_tracking' => __CLASS__ . '::order_tracking',
'woocommerce_cart' => __CLASS__ . '::cart',
'woocommerce_checkout' => __CLASS__ . '::checkout',
'woocommerce_my_account' => __CLASS__ . '::my_account',
);
foreach ( $shortcodes as $shortcode => $function ) {
add_shortcode( apply_filters( "{$shortcode}_shortcode_tag", $shortcode ), $function );
}
// Alias for pre 2.1 compatibility
add_shortcode( 'woocommerce_messages', __CLASS__ . '::shop_messages' );
}
/**
* Shortcode Wrapper
*
* #param mixed $function
* #param array $atts (default: array())
* #return string
*/
public static function shortcode_wrapper(
$function,
$atts = array(),
$wrapper = array(
'class' => 'woocommerce',
'before' => null,
'after' => null
)
) {
ob_start();
$before = empty( $wrapper['before'] ) ? '<div class="' . esc_attr( $wrapper['class'] ) . '">' : $wrapper['before'];
$after = empty( $wrapper['after'] ) ? '</div>' : $wrapper['after'];
echo $before;
call_user_func( $function, $atts );
echo $after;
return ob_get_clean();
}
/**
* Cart page shortcode.
*
* #return string
*/
public static function cart() {
if ( ! is_null( WC()->cart ) ) {
return self::shortcode_wrapper( array( 'WC_Shortcode_Cart', 'output' ) );
} else {
return '';
}
}
/**
* Checkout page shortcode.
*
* #param mixed $atts
* #return string
*/
public static function checkout( $atts ) {
return self::shortcode_wrapper( array( 'WC_Shortcode_Checkout', 'output' ), $atts );
}
/**
* Order tracking page shortcode.
*
* #param mixed $atts
* #return string
*/
public static function order_tracking( $atts ) {
return self::shortcode_wrapper( array( 'WC_Shortcode_Order_Tracking', 'output' ), $atts );
}
/**
* Cart shortcode.
*
* #param mixed $atts
* #return string
*/
public static function my_account( $atts ) {
return self::shortcode_wrapper( array( 'WC_Shortcode_My_Account', 'output' ), $atts );
}
/**
* List products in a category shortcode
*
* #param array $atts
* #return string
*/
public static function product_category( $atts ) {
global $woocommerce_loop;
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'title',
'order' => 'desc',
'category' => '', // Slugs
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
), $atts );
if ( ! $atts['category'] ) {
return '';
}
// Default ordering args
$ordering_args = WC()->query->get_catalog_ordering_args( $atts['orderby'], $atts['order'] );
$meta_query = WC()->query->get_meta_query();
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'orderby' => $ordering_args['orderby'],
'order' => $ordering_args['order'],
'posts_per_page' => $atts['per_page'],
'meta_query' => $meta_query,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => array_map( 'sanitize_title', explode( ',', $atts['category'] ) ),
'field' => 'slug',
'operator' => $atts['operator']
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<?php do_action( 'woocommerce_shortcode_before_product_cat_loop' ); ?>
<?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 do_action( 'woocommerce_shortcode_after_product_cat_loop' ); ?>
<?php endif;
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;
}
/**
* List all (or limited) product categories
*
* #param array $atts
* #return string
*/
public static function product_categories( $atts ) {
global $woocommerce_loop;
$atts = shortcode_atts( array(
'number' => null,
'orderby' => 'name',
'order' => 'ASC',
'columns' => '4',
'hide_empty' => 1,
'parent' => '',
'ids' => ''
), $atts );
if ( isset( $atts['ids'] ) ) {
$ids = explode( ',', $atts['ids'] );
$ids = array_map( 'trim', $ids );
} else {
$ids = array();
}
$hide_empty = ( $atts['hide_empty'] == true || $atts['hide_empty'] == 1 ) ? 1 : 0;
// get terms and workaround WP bug with parents/pad counts
$args = array(
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'hide_empty' => $hide_empty,
'include' => $ids,
'pad_counts' => true,
'child_of' => $atts['parent']
);
$product_categories = get_terms( 'product_cat', $args );
if ( '' !== $atts['parent'] ) {
$product_categories = wp_list_filter( $product_categories, array( 'parent' => $atts['parent'] ) );
}
if ( $hide_empty ) {
foreach ( $product_categories as $key => $category ) {
if ( $category->count == 0 ) {
unset( $product_categories[ $key ] );
}
}
}
if ( $atts['number'] ) {
$product_categories = array_slice( $product_categories, 0, $atts['number'] );
}
$woocommerce_loop['columns'] = $atts['columns'];
ob_start();
// Reset loop/columns globals when starting a new loop
$woocommerce_loop['loop'] = $woocommerce_loop['column'] = '';
if ( $product_categories ) {
woocommerce_product_loop_start();
foreach ( $product_categories as $category ) {
wc_get_template( 'content-product_cat.php', array(
'category' => $category
) );
}
woocommerce_product_loop_end();
}
woocommerce_reset_loop();
return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
}
/**
* Recent Products shortcode
*
* #param array $atts
* #return string
*/
public static function recent_products( $atts ) {
global $woocommerce_loop;
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'date',
'order' => 'desc'
), $atts );
$meta_query = WC()->query->get_meta_query();
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['per_page'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_query' => $meta_query
);
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$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;
wp_reset_postdata();
return '<div class="woocommerce custom_recent_products columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
}
/**
* List multiple products shortcode
*
* #param array $atts
* #return string
*/
public static function products( $atts ) {
global $woocommerce_loop;
if ( empty( $atts ) ) {
return '';
}
$atts = shortcode_atts( array(
'columns' => '4',
'orderby' => 'title',
'order' => 'asc',
'ids' => '',
'skus' => ''
), $atts );
$meta_query = WC()->query->get_meta_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' => $meta_query
);
if ( ! empty( $atts['skus'] ) ) {
$skus = explode( ',', $atts['skus'] );
$skus = array_map( 'trim', $skus );
$args['meta_query'][] = array(
'key' => '_sku',
'value' => $skus,
'compare' => 'IN'
);
}
if ( ! empty( $atts['ids'] ) ) {
$ids = explode( ',', $atts['ids'] );
$ids = array_map( 'trim', $ids );
$args['post__in'] = $ids;
}
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$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;
wp_reset_postdata();
return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
}
/**
* Display a single product
*
* #param array $atts
* #return string
*/
public static function product( $atts ) {
if ( empty( $atts ) ) {
return '';
}
$meta_query = WC()->query->get_meta_query();
$args = array(
'post_type' => 'product',
'posts_per_page' => 1,
'no_found_rows' => 1,
'post_status' => 'publish',
'meta_query' => $meta_query
);
if ( isset( $atts['sku'] ) ) {
$args['meta_query'][] = array(
'key' => '_sku',
'value' => $atts['sku'],
'compare' => '='
);
}
if ( isset( $atts['id'] ) ) {
$args['p'] = $atts['id'];
}
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
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;
wp_reset_postdata();
$css_class = 'woocommerce';
if ( isset( $atts['class'] ) ) {
$css_class .= ' ' . $atts['class'];
}
return '<div class="' . esc_attr( $css_class ) . '">' . ob_get_clean() . '</div>';
}
/**
* Display a single product price + cart button
*
* #param array $atts
* #return string
*/
public static function product_add_to_cart( $atts ) {
global $wpdb, $post;
if ( empty( $atts ) ) {
return '';
}
$atts = shortcode_atts( array(
'id' => '',
'class' => '',
'quantity' => '1',
'sku' => '',
'style' => 'border:4px solid #ccc; padding: 12px;',
'show_price' => 'true'
), $atts );
if ( ! empty( $atts['id'] ) ) {
$product_data = get_post( $atts['id'] );
} elseif ( ! empty( $atts['sku'] ) ) {
$product_id = wc_get_product_id_by_sku( $atts['sku'] );
$product_data = get_post( $product_id );
} else {
return '';
}
$product = wc_setup_product_data( $product_data );
if ( ! $product ) {
return '';
}
ob_start();
?>
<p class="product woocommerce add_to_cart_inline <?php echo $atts['class']; ?>" style="<?php echo $atts['style']; ?>">
<?php if ( 'true' == $atts['show_price'] ) : ?>
<?php echo $product->get_price_html(); ?>
<?php endif; ?>
<?php woocommerce_template_loop_add_to_cart( array( 'quantity' => $atts['quantity'] ) ); ?>
</p><?php
// Restore Product global in case this is shown inside a product post
wc_setup_product_data( $post );
return ob_get_clean();
}
/**
* Get the add to cart URL for a product
*
* #param array $atts
* #return string
*/
public static function product_add_to_cart_url( $atts ) {
global $wpdb;
if ( empty( $atts ) ) {
return '';
}
if ( isset( $atts['id'] ) ) {
$product_data = get_post( $atts['id'] );
} elseif ( isset( $atts['sku'] ) ) {
$product_id = wc_get_product_id_by_sku( $atts['sku'] );
$product_data = get_post( $product_id );
} else {
return '';
}
if ( 'product' !== $product_data->post_type ) {
return '';
}
$_product = wc_get_product( $product_data );
return esc_url( $_product->add_to_cart_url() );
}
/**
* List all products on sale
*
* #param array $atts
* #return string
*/
public static function sale_products( $atts ) {
global $woocommerce_loop;
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'title',
'order' => 'asc'
), $atts );
// Get products on sale
$product_ids_on_sale = wc_get_product_ids_on_sale();
$meta_query = WC()->query->get_meta_query();
$args = array(
'posts_per_page' => $atts['per_page'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'no_found_rows' => 1,
'post_status' => 'publish',
'post_type' => 'product',
'meta_query' => $meta_query,
'post__in' => array_merge( array( 0 ), $product_ids_on_sale )
);
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$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;
wp_reset_postdata();
return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
}
/**
* List best selling products on sale
*
* #param array $atts
* #return string
*/
public static function best_selling_products( $atts ) {
global $woocommerce_loop;
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4'
), $atts );
$meta_query = WC()->query->get_meta_query();
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['per_page'],
'meta_key' => 'total_sales',
'orderby' => 'meta_value_num',
'meta_query' => $meta_query
);
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$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;
wp_reset_postdata();
return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
}
/**
* List top rated products on sale
*
* #param array $atts
* #return string
*/
public static function top_rated_products( $atts ) {
global $woocommerce_loop;
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'title',
'order' => 'asc'
), $atts );
$meta_query = WC()->query->get_meta_query();
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'posts_per_page' => $atts['per_page'],
'meta_query' => $meta_query
);
ob_start();
add_filter( 'posts_clauses', array( __CLASS__, 'order_by_rating_post_clauses' ) );
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
remove_filter( 'posts_clauses', array( __CLASS__, 'order_by_rating_post_clauses' ) );
$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;
wp_reset_postdata();
return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
}
/**
* Output featured products
*
* #param array $atts
* #return string
*/
public static function featured_products( $atts ) {
global $woocommerce_loop;
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'date',
'order' => 'desc'
), $atts );
$meta_query = WC()->query->get_meta_query();
$meta_query[] = array(
'key' => '_featured',
'value' => 'yes'
);
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['per_page'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_query' => $meta_query
);
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$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;
wp_reset_postdata();
return '<div class="woocommerce custom_featured columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
}
/**
* Show a single product page
*
* #param array $atts
* #return string
*/
public static function product_page( $atts ) {
if ( empty( $atts ) ) {
return '';
}
if ( ! isset( $atts['id'] ) && ! isset( $atts['sku'] ) ) {
return '';
}
$args = array(
'posts_per_page' => 1,
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1
);
if ( isset( $atts['sku'] ) ) {
$args['meta_query'][] = array(
'key' => '_sku',
'value' => $atts['sku'],
'compare' => '='
);
}
if ( isset( $atts['id'] ) ) {
$args['p'] = $atts['id'];
}
$single_product = new WP_Query( $args );
ob_start();
while ( $single_product->have_posts() ) : $single_product->the_post(); wp_enqueue_script( 'wc-single-product' ); ?>
<div class="single-product">
<?php wc_get_template_part( 'content', 'single-product' ); ?>
</div>
<?php endwhile; // end of the loop.
wp_reset_postdata();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
/**
* Show messages
*
* #return string
*/
public static function shop_messages() {
ob_start();
wc_print_notices();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
/**
* woocommerce_order_by_rating_post_clauses function.
*
* #param array $args
* #return array
*/
public static function order_by_rating_post_clauses( $args ) {
global $wpdb;
$args['where'] .= " AND $wpdb->commentmeta.meta_key = 'rating' ";
$args['join'] .= "
LEFT JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID)
LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)
";
$args['orderby'] = "$wpdb->commentmeta.meta_value DESC";
$args['groupby'] = "$wpdb->posts.ID";
return $args;
}
/**
* List products with an attribute shortcode
* Example [product_attribute attribute='color' filter='black']
*
* #param array $atts
* #return string
*/
public static function product_attribute( $atts ) {
global $woocommerce_loop;
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'title',
'order' => 'asc',
'attribute' => '',
'filter' => ''
), $atts );
$attribute = strstr( $atts['attribute'], 'pa_' ) ? sanitize_title( $atts['attribute'] ) : 'pa_' . sanitize_title( $atts['attribute'] );
$meta_query = WC()->query->get_meta_query();
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['per_page'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_query' => $meta_query,
'tax_query' => array(
array(
'taxonomy' => $attribute,
'terms' => array_map( 'sanitize_title', explode( ',', $atts['filter'] ) ),
'field' => 'slug'
)
)
);
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$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;
wp_reset_postdata();
return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
}
/**
* #param array $atts
* #return string
*/
public static function related_products( $atts ) {
$atts = shortcode_atts( array(
'posts_per_page' => '2',
'columns' => '2',
'orderby' => 'rand',
'per_page' => ''
), $atts );
if ( ! empty( $atts['per_page'] ) ) {
_deprecated_argument( __CLASS__ . '->' . __FUNCTION__, '2.1', __( 'Use $args["posts_per_page"] instead. Deprecated argument will be removed in WC 2.2.', 'woocommerce' ) );
$atts['posts_per_page'] = $atts['per_page'];
unset( $atts['per_page'] );
}
ob_start();
woocommerce_related_products( $atts );
return ob_get_clean();
}
}
It will remove default Woocommerce shortcodes class action
And add our action.
load our custom shortcodes class which is copy of origional file class-wc-shortcodes.php.
include_once('class-custom_shortcodes.php');
add_action( 'init', 'use_custom_wc_shortcodes' );
function use_custom_wc_shortcodes()
{
remove_action('init', array('WC_Shortcodes', 'init'));
}
// hook in ours
add_action('init', array('WC_Custom_Shortcodes', 'init'));
I am looking to use the Wordpress gallery shortcut but I want to tie the output into the Foundation Orbit plugin (to make a slider). This is the HTML I am looking to output:
<div class="slideshow-wrapper">
<div class="preloader"></div>
<ul data-orbit>
<li>
<img src="img1.png" alt="bla bla bla" />
</li>
<li>
<img src="img2.png" alt="bla bla bla" />
</li>
<li>
<img src="img3.png" alt="bla bla bla" />
</li>
<li>
<img src="img4.png" alt="bla bla bla" />
</li>
</ul>
</div>
Is it possible to put something in functions.php (or similar) to achieve this?
Yes, indeed. Quite a while ago I've found this code and have been using it ever since. It's great to customize WP's default gallery to whatever you want.
There's a filter to post_gallery which you can use to customize all default WP galleries. Here's a sample of the code I use adapted to the template you provided. I've cleared it up as much as possible.
The first part of the function is pretty much gallery attachments handling, so you'll probably just want to change the latter half, the one that determines the output of your gallery template (follow the comments):
add_filter('post_gallery', 'my_post_gallery', 10, 2);
function my_post_gallery($output, $attr) {
global $post;
if (isset($attr['orderby'])) {
$attr['orderby'] = sanitize_sql_orderby($attr['orderby']);
if (!$attr['orderby'])
unset($attr['orderby']);
}
extract(shortcode_atts(array(
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post->ID,
'itemtag' => 'dl',
'icontag' => 'dt',
'captiontag' => 'dd',
'columns' => 3,
'size' => 'thumbnail',
'include' => '',
'exclude' => ''
), $attr));
$id = intval($id);
if ('RAND' == $order) $orderby = 'none';
if (!empty($include)) {
$include = preg_replace('/[^0-9,]+/', '', $include);
$_attachments = get_posts(array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby));
$attachments = array();
foreach ($_attachments as $key => $val) {
$attachments[$val->ID] = $_attachments[$key];
}
}
if (empty($attachments)) return '';
// Here's your actual output, you may customize it to your need
$output = "<div class=\"slideshow-wrapper\">\n";
$output .= "<div class=\"preloader\"></div>\n";
$output .= "<ul data-orbit>\n";
// Now you loop through each attachment
foreach ($attachments as $id => $attachment) {
// Fetch the thumbnail (or full image, it's up to you)
// $img = wp_get_attachment_image_src($id, 'medium');
// $img = wp_get_attachment_image_src($id, 'my-custom-image-size');
$img = wp_get_attachment_image_src($id, 'full');
$output .= "<li>\n";
$output .= "<img src=\"{$img[0]}\" width=\"{$img[1]}\" height=\"{$img[2]}\" alt=\"\" />\n";
$output .= "</li>\n";
}
$output .= "</ul>\n";
$output .= "</div>\n";
return $output;
}
Just paste it to your functions.php file and modify to adapt it to your need. I'm pretty sure it'll work for you as it have worked for me :)
Super answer Mathielo.
However, I needed the option of including a caption, so I've modified your code to use the wp_prepare_attachment_for_js() function as that seems to provide the necessary data.
add_filter('post_gallery', 'my_post_gallery', 10, 2);
function my_post_gallery($output, $attr) {
global $post;
if (isset($attr['orderby'])) {
$attr['orderby'] = sanitize_sql_orderby($attr['orderby']);
if (!$attr['orderby'])
unset($attr['orderby']);
}
extract(shortcode_atts(array(
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post->ID,
'itemtag' => 'dl',
'icontag' => 'dt',
'captiontag' => 'dd',
'columns' => 3,
'size' => 'thumbnail',
'include' => '',
'exclude' => ''
), $attr));
$id = intval($id);
if ('RAND' == $order) $orderby = 'none';
if (!empty($include)) {
$include = preg_replace('/[^0-9,]+/', '', $include);
$_attachments = get_posts(array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby));
$attachments = array();
foreach ($_attachments as $key => $val) {
$attachments[$val->ID] = $_attachments[$key];
}
}
if (empty($attachments)) return '';
// Here's your actual output, you may customize it to your need
$output = "<div class=\"slideshow-wrapper\">\n";
$output .= "<div class=\"preloader\"></div>\n";
$output .= "<ul data-orbit>\n";
// Now you loop through each attachment
foreach ($attachments as $id => $attachment) {
// Fetch all data related to attachment
$img = wp_prepare_attachment_for_js($id);
// If you want a different size change 'large' to eg. 'medium'
$url = $img['sizes']['large']['url'];
$height = $img['sizes']['large']['height'];
$width = $img['sizes']['large']['width'];
$alt = $img['alt'];
// Store the caption
$caption = $img['caption'];
$output .= "<li>\n";
$output .= "<img src=\"{$url}\" width=\"{$width}\" height=\"{$height}\" alt=\"{$alt}\" />\n";
// Output the caption if it exists
if ($caption) {
$output .= "<div class=\"orbit-caption\">{$caption}</div>\n";
}
$output .= "</li>\n";
}
$output .= "</ul>\n";
$output .= "</div>\n";
return $output;
}
I know the original question has been answered but I just wanted to share what I've done with the filter snippet in case it helps anyone else. I've enabled Miro Mannino's 'Justified Gallery' jquery plugin http://miromannino.com/projects/justified-gallery/ to work with Wordpress galleries in Wordpress 3.9 ... Here's the code with the changes I made to get it to work... (img size light thumb is my custom thumbnail to preserve image dimensions but keep page load times down.)
// Custom Gallery
add_filter( 'post_gallery', 'my_post_gallery', 10, 2 );
function my_post_gallery( $output, $attr) {
global $post, $wp_locale;
static $instance = 0;
$instance++;
// We're trusting author input, so let's at least make sure it looks like a valid orderby statement
if ( isset( $attr['orderby'] ) ) {
$attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
if ( !$attr['orderby'] )
unset( $attr['orderby'] );
}
extract(shortcode_atts(array(
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post->ID,
'itemtag' => 'dl',
'icontag' => 'dt',
'captiontag' => 'dd',
'columns' => 3,
'size' => 'light-thumb',
'include' => '',
'exclude' => ''
), $attr));
$id = intval($id);
if ( 'RAND' == $order )
$orderby = 'none';
if ( !empty($include) ) {
$include = preg_replace( '/[^0-9,]+/', '', $include );
$_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
$attachments = array();
foreach ( $_attachments as $key => $val ) {
$attachments[$val->ID] = $_attachments[$key];
}
} elseif ( !empty($exclude) ) {
$exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
$attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
} else {
$attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
}
if ( empty($attachments) )
return '';
if ( is_feed() ) {
$output = "\n";
foreach ( $attachments as $att_id => $attachment )
$output .= wp_get_attachment_link($att_id, $size, true) . "\n";
return $output;
}
$itemtag = tag_escape($itemtag);
$captiontag = tag_escape($captiontag);
$columns = intval($columns);
$itemwidth = $columns > 0 ? floor(100/$columns) : 100;
$float = is_rtl() ? 'right' : 'left';
$selector = "gallery-{$instance}";
$output = apply_filters('gallery_style', "
<style type='text/css'>
#{$selector} {
margin: auto;
}
#{$selector} .gallery-item {
float: {$float};
margin-top: 0px;
text-align: center;
width: {$itemwidth}%; }
#{$selector} img {
border: 0;
}
#{$selector} .gallery-caption {
margin-left: 0;
}
</style>
<!-- see gallery_shortcode() in wp-includes/media.php -->
<div id='$selector' class='gallery galleryid-{$id}'>");
$output = "<div id=\"mygallery\">\n";
$i = 0;
foreach ( $attachments as $id => $attachment ) {
$link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);
$output .= "<{$itemtag} class='gallery-item'>";
$output .= "
<{$icontag} class='gallery-icon'>
$link
</{$icontag}>";
if ( $captiontag && trim($attachment->post_excerpt) ) {
$output .= "
<{$captiontag} class='gallery-caption'>
" . wptexturize($attachment->post_excerpt) . "
</{$captiontag}>";
}
$output .= "</{$itemtag}>";
if ( $columns > 0 && ++$i % $columns == 0 )
$output .= '<br style="clear: both" />';
}
$output .= "
<br style='clear: both;' />
</div>\n";
return $output;
}
It works a treat. Thanks for sharing the filter - it was just what I was looking for.
So if you want output another string like img title or img desc just use this construction
$title = $img['title'];
This is comment to Super answer Mathielo (second answer), and this universal solution, not only zubr foundation
Little note! If not disabled in admin area, this filter will cause gallery not to be visible in admin area. To avoid this, we can run filters main part inside if statement
add_filter('post_gallery', 'my_post_gallery', 10, 2);
function my_post_gallery($output, $attr)
{
// Disable function in admina area.
if (is_admin()) {
return;
} else {
// put main code in here
}
}