Get Woocommerce product by slug - wordpress

I have a function to grab products by their category and return specific data about them using their category slug like so:
$itemArgs = array(
'post_type' => 'product',
'posts_per_page' => 1000,
'product_cat' => $request['id'],
'include_children' => false
);
$loop = new WP_Query( $itemArgs );
if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post();
//DO STUFF
endwhile; endif;
Which works fantastically. What I need now is to get a product by its own slug. Where the one above might get every product for "Cookies" category, this one should return just the "Chocolate Chip" product.
I've tried replacing 'product_cat' with 'slug' and 'product_slug' but those don't appear to work. This seems like a fairly straightforward thing to do... there's documentation on finding a product by 48 different properties... slug is not one for some reason. I just get the entirety of the product collection returned.

If you look at the Wordpress codex post about the WP_Query You will see a part which talks about Page and Posts Parameters. There you will see you can use the name parameter.
Assuming your product slug is chocolate-chip, you can use this to retrieve your product with the post_type and name parameters:
$itemArgs = array(
'post_type' => 'product',
'name' => 'chocolate-chip'
);
$query = new WP_Query($itemArgs);

$product_obj = get_page_by_path( $slug, OBJECT, 'product' );
https://wordpress.stackexchange.com/questions/206886/get-product-details-by-url-key-in-wordpress-woocommerce

Related

Render WooCommerce Handpicked Products Block from a plugin

In the plugin code I have:
add_action( 'wp_loaded', 'show_widget');
function show_widget(){
$block_name = 'woocommerce/handpicked-products';
$converted_block = new WP_Block_Parser_Block( $block_name, array(
'query' => new WP_Query( array (
'post__in' => $products, // $products is a given array of product IDs
'post_type' => 'product'
) )
), array(), '', array() );
$serialized_block = serialize_block( (array) $converted_block );
echo $serialized_block;
}
as a result, i see a commented out wp:query when I view source:
yet nothing is actually painted on the page. Notice there is one product in the result set and I expected it to be rendered to the screen.
Why doesn't it? What am I missing?
switched serialize_block with render_block and it works...

Sort posts with custom post type on custom taxonomy page

Ok, here is the deal. I have a custom post type paints, also I registered a custom taxonomy lkm for these products. I have a taxonomy-lkm.php template, where I can get all posts from a specific custom category(taxonomy). For example, on page /lkm/polyurethane/ I can get all posts from this custom category.
But I want to sort these posts ASC, not DESC. How can I do this, if I'm using while(have_posts) ?
I found the solution. Since I'm using the custom taxonomy lkm with custom post type paints, I've created a custom page for that taxonomy-lkm.php.
On this page I can catch a query of custom posts paints with specific taxonomy, like: on page /acrilyc I'll get all paints in category acrilyc. But the issue was that this array sorted by date in DESC order, but I need ASC.
So, there is solution:
Template taxonomy-lkm.php
<?php
get_header();
$termId = get_term_by( 'slug', get_query_var( 'term' ), get_query_var('taxonomy' ) )->term_id; //get the ID of current taxonomy
$query = new WP_Query( array(
'post_type' => 'paints', // name of post type.
'orderby' => 'date',
'order' => 'ASC',
'tax_query' => array(
array(
'taxonomy' => 'lkm', // taxonomy name
'field' => 'term_id',
'terms' => $termId, // term id, term slug or term name
)
)
) );
if ( $query -> have_posts() ) :
while ( $query -> have_posts() ) :
$query -> the_post(); ?>
.................HTML TEMPLATE
<?php endwhile;
wp_reset_query();
endif;
?>
Now all posts are sorted as ASC.

WordPress: All posts are rendering instead of rendering only assigned taxonomy posts on taxonomy page

I have a products post type and it has a various categories. Currently there are around fifty plus posts assigned to different categories. Note: I am using a custom taxonomy called product_categories.
Scenario:
I have a category named food-products and it has a sub categories as chocolates, dairy, grocery.
Now when user goes to the category page eg site.com/product-category/food-products at that time all other categories posts are also displaying but when i click on the sub category tabbing menu at that time it displays the correct assigned sub category posts
So, my question is how can the only the respected category of subcategory posts will be displayed on page load ?
<?php $loop = new WP_Query(array('post_type' => 'product', 'posts_per_page' => -1));
$count =0; ?>
<div class="row portfolio-container">
<?php if ( $loop ) : while ( $loop->have_posts() ) : $loop->the_post();
$url = get_the_post_thumbnail_url( $post_id, 'thumbnail_size' );
$terms = get_the_terms( $post->ID, 'product_categories' );
if ( $terms && ! is_wp_error( $terms ) ) :
$links = array();
foreach ( $terms as $term ) { $links[] = $term->name; }
$links = str_replace(' ', '-', $links);
$tax = join( " ", $links );
else :
$tax = '';
endif; ?>
<div class="col-lg-4 col-md-6 portfolio-item <?php echo strtolower($tax); ?>">
<div class="portfolio-wrap">
<img src="<?php echo $url;?>" class="img-fluid" alt="">
<div class="portfolio-info">
<h4><?php the_title();?></h4>
<div class="portfolio-links">
<i class="ion ion-eye"></i>
<i class="ion ion-android-open"></i>
</div>
</div>
</div>
</div>
<?php endwhile;?>
<?php wp_reset_query();?>
<?php endif;?>
</div>
JQuery:
$(window).on('load', function () {
var portfolioIsotope = $('.portfolio-container').isotope({
itemSelector: '.portfolio-item'
});
$('#portfolio-flters li').on( 'click', function() {
$("#portfolio-flters li").removeClass('filter-active');
$(this).addClass('filter-active');
portfolioIsotope.isotope({ filter: $(this).data('filter') });
});
});
Here is my working demo video for review.
Your WP_Query is returning all products, so that is why they are all getting shown on page load. You need to change the query so it only gets the ones in the category/categories you want.
You want to get products in a certain category, e.g. food-products and all it's sub categories, (e.g. chocolates).
To do this, you can change your WP_Query to specify the category to use like this :
$loop = new WP_Query(
array('post_type' => 'product',
'posts_per_page' => -1,
array( 'category_name' => 'food-products' ) // <-- THIS!! Also note that it is in an array
));
This tells WP_Query to get all product posts that belong to the food-products category, so it will return any products with the food-products category as well as any products in any of the child categories, e.g. chocolates
WP_Query has a number of different ways you can query by category... take a look at the category section of the WP_Query documentation for more information.
UPDATE: Custom Taxonomies
You can do the same thing for custom taxonomies, but you need to use tax_query in the arguments instead of category_name. Your WP_Query should be something like this:
// you don't need to create a variable for the args, if just makes it clearer in the example
$args = array (
'post_type' => 'product',
'posts_per_page' => -1,
'tax_query' => array(
array( // note the nested arrays
'taxonomy' => 'product_categories', // this is the name of your custom taxonomy
'field' => 'slug', // you can search by slug, name, term_id or term_taxonomy_id
'terms' => 'food-products' // the taxonomy slug to search for
)
)
);
$loop = new WP_Query($args);
You might need to change the values for taxonomy and term to match your custom taxonomy. I've also assumed you are searching by slug, but you can search by name or id either.
There is an include_children parameter for the tax_query that you use to say whether or not to include children (e.g. chocolates) in the results, but this defaults to true so you only need to use it if you don't want to include children.
Here's the taxonomy section of the WP_Query documentation for more information.
UPDATE 2: Getting the products for the current category
You say in the comments that you have one template for all of the terms taxonomy-product_categories.php, each category shows in its own page using this template but you only want to show the products with the current term.
What you need to do is use just the current term in the WP_Query, not all of them. You should be able to use get_queried_object() to get the current term and use it in your tax_query instead of hard coding the specific terms.
// get the term of the current page
// We can then use $currentterm->slug in tax_query to dynamically search for this term instead of hard coding a specific term
$currentterm = get_queried_object();
$args = array (
'post_type' => 'product',
'posts_per_page' => -1,
'tax_query' => array(
array( // note the nested arrays
'taxonomy' => 'product_categories', // this is the name of your custom taxonomy
'field' => 'slug', // you can search by slug, name, term_id or term_taxonomy_id
'terms' => $currentterm->slug // search for the slug of the current term
)
)
);
$loop = new WP_Query($args);
So what this should do is: if you are on e.g. site.com/product-category/food-products, it will get the current term which is food-products and then only search for products with that category.
When you go to e.g. site.com/product-category/home-decor, it will dynamically pick up the new term as home-decor and use it in the query.

Getting list of all custom post type posts and regular posts from a certain category

I'm trying to get a list of all posts from a custom post type called social, and any normal posts within the category social. I currently am using the following:
$posts = get_posts(
array(
'post_type' => array('social', 'post'),
'category_name' => 'social',
'post_status' => 'publish'
)
);
This seems to only be returning posts within the social category, not the social post type. Anyway to return both post_types?
The generated query expects all the conditions to be true: post_typeto be either social or post AND category_name to be social AND post_status to be publish.
One simple solution is to use WP_Query instead:
$query = new WP_Query(array(
'post_type' => array('social', 'post'),
'category_name' => 'social',
'post_status' => 'publish'
));
$posts = $query->posts;
Then, you may use a posts_where filter to modify the where part of the query:
add_filter( 'posts_where', 'my_posts_where', 10, 2 );
function my_posts_where( $where, $query ) {
...modify $where...
return $where;
}
I'll skip the string manipulation part, because there is nothing specific there. Anyhow, $where will look something like this (tested with my WordPress installation):
"AND ( wp_term_relationships.term_taxonomy_id IN (<number>))
AND wp_posts.post_type IN ('social', 'post') AND
((wp_posts.post_status = 'publish'))"
You need to convert it to something like this:
"AND ( ((wp_term_relationships.term_taxonomy_id IN (<number>)
AND wp_posts.post_type = 'post') OR (wp_posts.post_type = 'social'))
AND (wp_posts.post_status = 'publish'))"
Finally, you need to make sure that my_posts_where does not break the other queries. I might just add some indicator to the $query object to identify this particular query in the filter.

how to get latest posts from all custom post types in the site

I have defined multiple custom post types in my wordpress installation. I want to get latest posts from all the custom post types. all resources and tutorials I look into describes only getting latest post from one custom post type, not multiple.
is there any way to do this? for example assigning multiple values to post_type attribute in WP_Query objects or wp_get_recent_posts() function? if answer is yes exactly how to do this.
any help would be appreciated.
It will fetch posts from multiple custom post type.
query_posts( array(
'post_type' => array( 'custom_post1', 'custom_post2', 'custom_post3',
'custom_post4' ),
'cat' => 3,
'showposts' => 5 )
);
First thing I want to clear here I do not know about WordPress but I can help you with the SQL query
I assume you have date time column in your table .
select * from table name
where column name in (here write all your different types followed by comma )
order by your date time column name desc;
E.g.
select * from posts where type in(1,2,3,4) order by created_on desc;
Let's fetch your all custom post types.
$args = array('public' => true, '_builtin' => false);
$output = 'names'; // names or objects, note names is the default
$operator = 'and'; // 'and' or 'or'
$post_types = get_post_types( $args, $output, $operator );
The $post_types is now an array containing all the custom post type names. Your all posts query should be like this
$allposts = array( 'posts_per_page' => -1,
'post_type'=> $post_types,
'orderby' => 'date',
'order' => 'DESC'
);
$query = new WP_Query( $allposts );
if ( $query->have_posts() ) :
while ($query-> have_posts()) : $query -> the_post()
the_permalink();
the_title();
the_content();
endwhile;
endif;

Resources