How to add category option to shortcode - php

I'm new to creating wordpress shortcodes and have one just about working the way I want. Missing something specific. Currently I am able to put the following on any page - [children] and it pulls a query of all posts from the custom post type "children" I would like to add the option to add the category id within the shortcode - something like [children category="8"] Here is the code I have so far:
add_shortcode( 'children', 'display_custom_post_type' );
function display_custom_post_type(){
$args = array(
'post_type' => 'children',
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
);
$string = '';
$query = new WP_Query( $args );
if( $query->have_posts() ){
while( $query->have_posts() ){
$query->the_post();
$string .= '<div id="childWrapper"><div id="childImage">' . get_the_post_thumbnail() . '</div><div style="clear: both;"></div><div id="childName">' . get_the_title() . '</div><div style="clear: both;"></div></div>';
}
}
wp_reset_postdata();
return $string;
}
Secondary - is it possible for it to show posts in multiple categories, but only where the posts are in each of the categories. For example showing a list of children, who fall under a category for critical care and surgery needed.
Any help would be greatly appreciated.

You should refer Shortcode function from WordPress Codex. Assuming your taxonomy name is category, I made some changes in your current code it should work as per your requirements.
/**
* [children category="5,7,8"]
*/
add_shortcode( 'children' , 'display_custom_post_type' );
function display_custom_post_type($atts) {
$atts = shortcode_atts( array(
'category' => ''
), $atts );
//If category is multiple: 8,9,3
$categories = explode(',' , $atts['category']);
$args = array(
'post_type' => 'children',
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page'=> -1,
'tax_query' => array( array(
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => $categories
) )
);
$string = '';
$query = new WP_Query( $args );
if( ! $query->have_posts() ) {
return false;
}
while( $query->have_posts() ){
$query->the_post();
$string .= '<div id="childWrapper"><div id="childImage">' . get_the_post_thumbnail() . '</div><div style="clear: both;"></div><div id="childName">' . get_the_title() . '</div><div style="clear: both;"></div></div>';
}
wp_reset_postdata();
return $string;
}

Related

Showing list of posts including custom taxonomy terms

I'm working on a WP_Query loop that is suppose to show the list of posts in a following way
+ Custom taxonomy term 1
++ Post 1
++ Post 2
+ Custom taxonomy term 2
++ Post 1
++ Post 2
So in general it will work for CPT called 'career'. In a real life my custom taxonomy (job-category) is like: Drivers, Logistics, HR etc. And to each of such taxonomy/category I've got created specific posts. There is also a custom taxonomy called job-country which suggests the territory.
To achieve the way of showing my posts I am using the following code:
<?php
$terms = get_terms([
'taxonomy' => 'job-category',
'hide_empty' => true,
'orderby' => 'count',
'order' => 'DESC'
]);
usort( $terms, function( $a, $b ) {
$a_ste = (int) get_term_meta( $a->term_id, 'stick_to_end', true );
$b_ste = (int) get_term_meta( $b->term_id, 'stick_to_end', true );
if ($a_ste == $b_ste) return 0;
return ($a_ste < $b_ste) ? -1 : 1;
} );
if ($terms) { //categories exists
foreach ($terms as $category) { ?>
<h2 class="category-title">
<?= $category->name ?>
</h2>
<?php
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'career',
'tax_query' => [
[
'taxonomy' => 'job-category',
'field' => 'term_id',
'terms' => $category->term_id,
]
]
));
if ( $posts ) {
foreach( $posts as $post ) {
setup_postdata( $post );
include 'JobListThumb.php';
};
wp_reset_postdata();
}
}
} else { //no categories
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'career'
));
if ( $posts ) {
foreach( $posts as $post ) {
setup_postdata( $post );
include 'JobListThumb.php';
};
wp_reset_postdata();
}
}
?>
And it works. But because of certain reasons (working on an ajax filtering function) I need to achieve the same thing using traditional wp_query.
This is what I've got:
$args = array(
'orderby' => 'date', // we will sort posts by date
'order' => $_POST['date'], // ASC or DESC
'post_type' => 'career',
);
// for taxonomies / categories
if( isset( $_POST['categoryfilter'] ) && isset( $_POST['taxonomyfilter'] ))
$args['tax_query'] = array(
'relation' => 'AND',
array(
'taxonomy' => 'job-category',
'field' => 'id',
'terms' => $_POST['categoryfilter']
),
array(
'taxonomy' => 'job-country',
'field' => 'id',
'terms' => $_POST['taxonomyfilter']
)
);
// if you want to use multiple checkboxes, just duplicate the above 5 lines for each checkbox
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
echo '<h2>' . $query->post->post_title . '</h2>';
endwhile;
wp_reset_postdata();
else :
echo 'No posts found';
endif;
die();
But I've stucked in a place - how to add those terms / elements to the query? Obviously cannot mix get_terms with wpquery by simply copying instead echo'ing the title.
Do you have any suggestions how to solve this?

How do I apply my filter only to one store/url?

I've been struggling applying filters to my woocommerce shop. I have a website with multiple store pages and I've found a filter to only shop products published within the last 30 days. I want this filter to only apply to the 'new releases' shoppage, not to the whole website. Currently it's filtering everything, so even pages created before last month won't appear for example.
How do I make sure this filter is only applied to 1 store? Can I apply an IF statement and check current URL before the filter works or something?
Any help is appreciated.
Filter: (from https://www.sitepoint.com/community/t/show-latest-30-days-products-in-woocommerce/258276)
function baba_recent_products() {
//return 'This is where the recent products should show up if I get the shortcode working. ';
global $woocommerce_loop;
extract( shortcode_atts( array(
'per_page' => '48',
'columns' => '2',
'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' => $per_page,
'orderby' => $orderby,
'order' => $order,
'meta_query' => $meta_query
);
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$woocommerce_loop['columns'] = $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-' . $columns . '">' . ob_get_clean() . '</div>';
}
add_shortcode( 'baba_recent_products', 'baba_recent_products' );
function filter_where($where = '') {
//posts in the last 30 days
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
return $where;
}
add_filter('posts_where', 'filter_where');
function baba_recent_products() {
//return 'This is where the recent products should show up if I get the shortcode working. ';
global $woocommerce_loop;
extract( shortcode_atts( array(
'per_page' => '48',
'columns' => '2',
'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' => $per_page,
'orderby' => $orderby,
'order' => $order,
'meta_query' => $meta_query
);
ob_start();
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
$woocommerce_loop['columns'] = $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-' . $columns . '">' . ob_get_clean() . '</div>';
}
add_shortcode( 'baba_recent_products', 'baba_recent_products' );
function filter_where($where = '') {
global $post;
if($post->ID === /*Page ID as int here*/){
//posts in the last 30 days
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
}
return $where;
}
add_filter('posts_where', 'filter_where');

Display with a shortcode a dropdown of Woocommerce products for a specific category

i want to display product by category with dropdown
and i made this code but why the value not going inside the ?
function rakitpc() {
$args = array(
'posts_per_page' => -1,
'product_cat' => 'Tshirts',
'hide_empty' => 0,
'post_status' => 'publish',
'post_type' => 'product',
'orderby' => 'title',
'echo' => '0'
);
$products = new WP_Query( $args );
$output = '<select>';
// foreach ( $products as $product ) {
while ( $products->have_posts() ) {
$products->the_post();
$aa = the_permalink($post);
echo $aa;
$bb = the_title($post);
$output .= "<option value=\"<?php the_permalink(); ?>\"> <?php the_permalink(); ?></option>";
}
wp_reset_query();
$output .='</select>';
return $output;
}
add_shortcode( 'gege', 'rakitpc' );
This is the output That I get:
My reference: How do I display a "category products drop down in a wordpress page" in Woocommerce 2.5.2
Try the following that will give you a dropdown with the permalinks as <option> values displaying the product names (see the screenshot at the end).
You will need to set your category name (or categories names) in the array inside the funtion.
function rakitpc() {
// HERE below, define your Product category names
$term_names = array('T-shirts');
// The WP_Query
$query = new WP_Query( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'hide_empty' => 0,
'orderby' => 'title',
'tax_query' => array( array(
'taxonomy' => 'product_cat', // for a Product category (or 'product_tag' for a Product tag)
'field' => 'name', // can be 'name', 'slug' or 'term_id'
'terms' => $term_names,
) ),
'echo' => '0'
) );
$output = '<select>';
// foreach ( $products as $product ) {
if ( $query->have_posts() ) :
while ( $query->have_posts() ) : $query->the_post();
$permalink = get_permalink($query->post->ID);
$title = $query->post->post_title;
$output .= '<option value="' . $permalink . '">' . $title . '</option>';
endwhile;
wp_reset_postdata();
$output .='</select>';
else :
$output = '<p>No products found<p>';
endif;
return $output;
}
add_shortcode( 'gege', 'rakitpc' );
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Get images by a slug in Wordpress

I am fairly new to Wordpress and I am trying to make a function that loads images under a media category. The media category has a slug that I want to pass into the function. If there is an easier way to do this please let me know. Below is my code so far:
Functions.php
function get_image_by_slug($slug) {
$query_images_args = array(
'post_type' => 'attachment',
'post_mime_type' =>'image',
'post_status' => 'inherit',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'attachment_category',
'field' => 'slug',
'terms' => $slug,
),
),
);
$query_images = new WP_Query( $query_images_args );
$images = array();
foreach ( $query_images->posts as $image) {
$images[]= $image->guid;
}
return $images;
}
function display_image_by_slug() {
$imgs = get_image_by_slug($slug);
$html = '<ul class="list-inline">';
foreach($imgs as $img) {
$html .= '<li><img src="' . $img . '" alt="" /></li>';
}
$html .= '</ul>';
return $html;
}
add_filter('display_slugs','display_image_by_slug');
In page
<?php apply_filter('display slugs', 'test_slug');?>
An attachment of image or file is just a post with the post_status = inherit and the post_type = attachment and it is saved into the wp_post & wp_postmeta , so can be queried with WP_Query or get_posts.
Note: The slug (post_name) is unique per post type.
You have to pass your slug in the query by replacing YOUR-SLUG in this place. &name=YOUR-SLUG
$_head = get_posts('post_type=attachment&name=YOUR-SLUG&posts_per_page=1&post_status=inherit');
$header = $_head ? array_pop($_head) : null;
$header_url = $header ? wp_get_attachment_url($header->ID) : '';
Another Method you can build your own custom function with the help that i have provided below.
function get_attachment_url_by_slug( $slug ) {
$args = array(
'post_type' => 'attachment',
'name' => sanitize_title($slug),
'posts_per_page' => 1,
'post_status' => 'inherit',
);
$_head = get_posts( $args );
$header = $_head ? array_pop($_head) : null;
return $header ? wp_get_attachment_url($header->ID) : '';
and then you can call using this function.
$header_url = get_attachment_url_by_slug('YOUR-SLUG');
So after looking around the Wordpress docs and understanding Naresh's answer I was able to come up with my own answer. Here it is...
$id = 'YOUR SLUG';
$args = array(
'post_type' => 'attachment',
'post_status' => 'any',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'media_category', // your taxonomy
'field' => 'slug',
'terms' => $id // term id (id of the media category)
)
)
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<li>'. wp_get_attachment_image( get_the_ID() );
if(empty_content(get_the_content())){
echo '<p>' . get_the_excerpt() . '</p></li>';
} else {
echo '<p>'.get_the_excerpt().'</p></li>';
}
}
} else {
// no attachments found
}
wp_reset_postdata();

WordPress Custom Taxonomies WP_Query

I'm trying to create a query where I create multiple categories (taxonomies) in a custom post type, and then on the homepage query based on specific which is working fine. Currently I have 3 taxonomies:
current-specials
meineke-difference
featured
I have already written code that pulls these. The problem I'm running into is that on the homepage it needs to only pull these posts when they are also attached to the "featured" taxonomy. So an example of standard logic for this would be:
if taxonomy = current-specials AND featured then success else fail
But what it's doing is pulling them all because the current code is OR, and I need AND
Thoughts? (code below)
<?php
$post_type = 'coupons';
$tax = 'coupons_category';
$tax_terms = get_terms($tax);
if ($tax_terms):
foreach ($tax_terms as $tax_term):
echo '<div id="'.$tax_term->slug.'" class="coupon-box '.$tax_term->slug.'">';
$args = array(
'post_type' => $post_type,
"$tax" => array($tax_term->slug, 'featured'),
'post_status' => 'publish',
'posts_per_page' => -1,
'caller_get_posts' => 1
);
$myQuery = null;
$myQuery = new WP_Query($args);
if($myQuery->have_posts()):
while ($myQuery->have_posts()) : $myQuery->the_post();
$price = get_field('price_image', $myQuery->ID);
$print = get_field('print', $myQuery->ID);
$product = get_field('product_box_image', $myQuery->ID);
$title = get_the_title();
$content = get_the_content();
echo '<div class="fourty9 left box center">';
echo '<h1>'.$title.'</h1>';
echo '<p class="center"><img src="'.$price.'" /></p>';
echo '<p>'.$content.'</p>';
echo '<p class="center">Print Coupon</p>';
echo '<p class="center"><img src="'.$product.'" alt="Filter"></p>';
echo '</div>';
endwhile;
endif;
echo '</div>';
wp_reset_query();
endforeach;
endif;
?>
You may try this (tax - use taxonomy slug. Deprecated as of Version 3.1 in favor of 'tax_query')
$args = array(
'post_type' => 'coupons',
'posts_per_page' => -1,
'caller_get_posts' => 1,
'tax_query' => array(
array(
'taxonomy' => 'coupons_category',
'field' => 'slug',
'terms' => array( 'current-specials', 'featured' ),
'operator' => 'AND'
)
)
);
$query = new WP_Query( $args );

Categories