I've got this function:
<?php
$categories = []; //array to store all of your category slugs
$category_list_items = get_terms( 'product_cat' );
foreach($category_list_items as $category_list_item){
if(! empty($category_list_item->slug) ){
array_push($categories, $category_list_item->slug);
}
}
foreach ($categories as $category) {
$args = array( 'post_type' => 'product', 'posts_per_page' => 100, 'product_cat' => $category, 'orderby' => 'rand' );
?>
This is good, it returns the slug of a category for me in a loop. The problem is, now I can't get the category name anymore. I've tried adding another array: '$names = [];' and with that copied the if statement in which I replaced slug with name. But that didn't take. Out all of the solutions that i've tried, I only get returned 'Array' of just the whole list of names. Does anyone have a solution?
Thanks!
<?php
$categories = array();
$names = array();
$category_list_items = get_terms( 'product_cat' );
foreach($category_list_items as $category_list_item){
if(! empty($category_list_item->slug) ){
$categories[] = $category_list_item->slug;
$names[] = $category_list_item->name;
}
}
foreach ($categories as $key=>$category) {
echo "Category Name :".$names[$key];
echo "Category Slug :".$category;
$args = array( 'post_type' => 'product', 'posts_per_page' => 100, 'product_cat' => $category, 'orderby' => 'rand' );
?>
Related
I don't know how to explain my problem but I like to echo the specific category/ slug inside the specified section (sorting off by categories). I don't know which Wordpress function should be use? is it get_category or get_post?
so far I have this code to echo all the categories in one section:
<?php
$args = array(
'post_type' => 'allproducts',
'posts_per_page' => 9,
);
$posts = get_posts( $args );
foreach ( $posts as $post ):
setup_postdata( $post );
?>
basically my goal is to get all the post from specific category:
I have these list of categories with specific slugs and ID:
Category Name | Slug | ID
Shoes | cat01| 2
Pants | cat02| 3
Tops | cat03| 4
$categories = get_categories( array(
'orderby' => 'name',
) );
foreach($categories as $category)
{
$cateid = $category->term_id;
$args = array(
'post_type' => 'allproducts',
'category' => $cateid,
'posts_per_page' => 9,
);
$posts = get_posts( $args );
foreach ( $posts as $post ){
// here rest of code of posts.
}
}
I figure it out. here's my code:
<?php
$args1 = array( 'posts_per_page' => 9, 'offset'=> 0, 'category' => array(1));
$myposts1 = get_posts( $args1 );
foreach ( $myposts1 as $post ) : setup_postdata( $post );
?>
array (1) --> is the id of my category
closed it with this code
<?php endforeach;
wp_reset_postdata();?>
I'm using polylang plugin to having multi-languages website.
Using WooCommerce with polylang demands duplicating each product for each language, so assuming I have Hebrew and English, that means 2 duplications for each products.
It works fine with WooCommerce plugin, but when I'm displaying "related products" at the end of the product page, it's mixing products in English and Hebrew together.
I expect to filter the related product by website current language (if(get_locale() == 'en_US') - to check website current locale state, else will represent Hebrew).
Polylang functions
Here is what I have tried, but I got stuck on the part of filtering the product by language:
add_filter( 'woocommerce_product_related_posts', 'custom_related_products' );
function custom_related_products($product){
global $woocommerce;
// Meta query
$meta_query = array();
$meta_query[] = $woocommerce->query->visibility_meta_query();
$meta_query[] = $woocommerce->query->stock_status_meta_query();
$meta_query = array_filter( $meta_query );
// Get the posts
$related_posts = get_posts( array(
'orderby' => 'rand',
'posts_per_page' => '4',
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query
) );
if ( $related_posts->have_posts() ) {
while ( $related_posts->have_posts() ) : $related_posts->the_post();
if(pll_get_post_language(get_the_ID())){
//Not sure its the right approach for this..
}
endwhile;
}
$related_posts = array_diff( $related_posts, array( $product->id ), $product->get_upsells() );
return $related_posts;
}
How can I filter Woocommerce related product section by language?
Edit
So after a little bit of research and help in the comments I found out that 'lang' => 'en' argument does exist, but even when I use it, there is no change on related products language display.
Any ideas?
add_filter( 'woocommerce_product_related_posts', 'custom_related_products' );
function custom_related_products($product){
global $woocommerce;
// Meta query
$meta_query = array();
$meta_query[] = $woocommerce->query->visibility_meta_query();
$meta_query[] = $woocommerce->query->stock_status_meta_query();
$meta_query = array_filter( $meta_query );
// Get the posts
$related_posts = get_posts( array(
'orderby' => 'rand',
'posts_per_page' => '4',
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query,
'suppress_filters' => false
) );
if ( $related_posts->have_posts() ) {
while ( $related_posts->have_posts() ) : $related_posts->the_post();
if(pll_get_post_language(get_the_ID())){
//Not sure its the right approach for this..
}
endwhile;
}
$related_posts = array_diff( $related_posts, array( $product->id ), $product->get_upsells() );
return $related_posts;
}
suppress_filters There is a way to make get_posts cache the results however, the suppress_filters option is true by default, but if you set it to false, the caching mechanisms inside WordPress will do their work, and results will be saved for later.
You can try this code:
$related_posts = get_posts( array(
'orderby' => 'rand',
'posts_per_page' => '4',
'post_type' => 'product',
'meta_query' => $meta_query,
'lang' => 'en'
) );
if ($related_posts) {
foreach ($related_posts as $post) {
setup_postdata($post);
// something like <li><?php the_title(); ?></li>
}
}
wp_reset_postdata();
This code correctly returns code in selected language on my site
While working on a custom WordPress REST Api end point to fetch post by selected language or device language, this worked. See if it can help you out.
function mycustomplugin_posts($params) {
// get the url params
$page = $params->get_param('page') ? $params->get_param('page') : 0;
$per_page = $params->get_param('per_page') ? $params->get_param('per_page') : 10;
$offset = $params->get_param('offset') ? $params->get_param('offset') : 0;
$order = $params->get_param('order') ? $params->get_param('order') : 'desc';
$order_by = $params->get_param('order_by') ? $params->get_param('order_by') : 'date';
$lang = array_search($params->get_param('lang'),polylang_json_api_languages(), true) ? $params->get_param('lang') : pll_default_language();
$args = [
'post_type' => 'post',
'page' => $page,
'numberposts' => $per_page,
'offset' => $offset,
'order' => $order,
'orderby' => $order_by,
'tax_query' => [
[
'taxonomy' => 'language',
'field' => 'slug',
'terms' => $lang
]
]
];
$posts = get_posts($args);
$data = [];
$i = 0;
foreach($posts as $post) {
// Extract the post data
$data[$i]['id'] = $post->ID;
$data[$i]['title'] = $post->post_title;
$data[$i]['content'] = $post->post_content;
$data[$i]['excerpt'] = e42_the_short_content($post->post_content, 300);
$data[$i]['slug'] = $post->post_name;
$data[$i]['date'] = $post->post_date;
$data[$i]['link'] = get_permalink($post->ID);
$data[$i]['author'] = get_the_author_meta('display_name', $post->post_author);
$data[$i]['categories'] = array();
$data[$i]['featured_image']['thumbnail'] = get_the_post_thumbnail_url($post->ID, 'thumbnail');
$data[$i]['featured_image']['medium'] = get_the_post_thumbnail_url($post->ID, 'medium');
$data[$i]['featured_image']['large'] = get_the_post_thumbnail_url($post->ID, 'large');
foreach(get_the_category($post->ID) as $category){
array_push($data[$i]['categories'],$category->term_id);
}
$i++;
}
// Create the response object
$response = new WP_REST_Response( $data );
// Add a custom status code
$response->set_status( 200 );
return $response;
}
/plugins/woocommerce/templates/single-product/related.php
Move this to child theme
yourtheme/woocommerce/single-product/related.php
And add the following line to the foreach loop
if (pll_current_language()!=pll_get_post_language($post_object->ID)) {
continue;
}
Basically if current language does not match product language we skip over it.
I have this situation that I'm trying to figure out.
I've created a custom product taxonomy named cities, each product can belong to a product_cat taxonomy and/or city taxonomy.
On a shop product category I want to create a widget that displays available cities for current category.
I've managed to do this but it's not a optimized code that I'm looking for.
right now this is how it looks like
// get current category
$cate = get_queried_object();
$catID = $cate->term_id;
$catID;
$link = get_term_link( $catID, 'product_cat' );
$args = array(
'post_type' => 'product',
'tax_query' => array(
'taxonomy' => 'product_cat',
'field' => 'id',
'term' => $catID
)
);
$products = new WP_Query( $args );
$cities = array();
foreach ($products->posts as $product) {
echo('<ul>');
$terms = get_the_terms($product->ID,'city');
if (is_array($terms)) {
foreach ($terms as $term) {
if (!in_array($term->slug, $cities)) {
$cities[] = $term->slug;
$city_link = get_term_link( $term->term_id, 'city' );
echo "<li><a href='{$link}city/{$term->slug}'>{$term->name}</a></li>";
}
}
}
echo('</ul>');
}
This if not by the WP_Query function I think it could be done by a SQL query but this is out of my league.
I am displaying only 6 sub categories of a Parent Category, this is the code I am using
$taxonomy = 'category';
$param_type = 'category__in';
$cat_id = get_cat_ID('Makeup');
$term_args=array(
'orderby' => 'name',
'order' => 'ASC',
'child_of' => $cat_id,
'limit' => 6 );
$terms = get_terms($taxonomy,$term_args);
if ($terms) {
foreach( $terms as $term ) { ?>
<h4><?php echo $term->name;?></h4>
Here results are coming limit less.
Please help me
Solved. I limited the categories using 'number' => 6;
I've been searching high and low for and answer to this, but I'm not actually sure it's possible!
I have a WP_Query that pulls posts from almost everything, however, I wish to exclude a specific category and/or all it's sub categories.
Searching around people are yet to find a solution for this.
Here's my query so far:
$args = array(
'post_type' => 'sell_media_item',
'cat' => -98,
'orderby' => 'desc',
'paged' => $paged,
'posts_per_page' => 20
); ?>
<?php $loop = new WP_Query( $args ); ?>
I thought just excluding cat 98 would grab all the sub categories too, but apparently not.
I've tried using:
category__not_in, depth=0, parent=0 and even an adaptation of this, with no luck.
Any ideas?
[EDIT]
I'm using a custom taxonomy called Collections, so putting 'collection' => 'vip' into the query means it will only show this collection. I'm thinking if there's a way of reversing this so it excludes the collection instead?
As it's not possible to list all of the categories that will appear here as they will be changing all of the time.
[EDIT 2]
After the discussion in the comments below, here's the updated code.
$ex = array(
'taxonomy' => 'collection',
'child_of' => 98,
'hide_empty' => 0
);
$categories = get_categories($ex);
$categoriesToExclude = array();
foreach ($categories as $category) {
$categoriesToExclude[] = $category->cat_ID;
}
echo('<pre>'); var_dump($categories);
$args = array(
'post_type' => 'sell_media_item',
'category__not_in' => $categoriesToExclude,
'orderby' => 'desc',
'paged' => $paged,
'posts_per_page' => 20
); ?>
<?php echo('<br /><pre>'); var_dump($args); ?>
<?php $loop = new WP_Query( $args ); ?>
I would get the list of all sub categories with get_categories() and then build a 'cat' exclusion array based on the results.
$args = array('parent' => 98);
$categories = get_categories($args);
$categoriesToExclude = array();
foreach ($categories as $category) {
$categoriesToExclude[] = $category->cat_ID;
}
$args = array(
'post_type' => 'sell_media_item',
'category__not_in' => $categoriesToExclude,
'orderby' => 'desc',
'paged' => $paged,
'posts_per_page' => 20
); ?>
<?php $loop = new WP_Query( $args ); ?>
This is just an example, you may have to modify it slightly to fit your needs.
So!
It appears I was trying to do the impossible. I couldn't get this script working for the life of me. So I tried a different angle. Instead of excluding a custom taxonomy and its terms, I decided to move all of my other terms into a parent term and just called that instead.
Here's the code if anyone's interested...
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'sell_media_item',
'taxonomy' => 'collection',
'term' => 'clubs',
'orderby' => 'desc',
'paged' => $paged,
'posts_per_page' => 20
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) : while ($loop->have_posts()) : $loop->the_post(); ?>
I wrote my own function in order to exclude subcategory posts from the loop, using tips from the above post and elsewhere.
In my theme archive.php file, above the loop, I list the subcategories (optional):
<?php
$current_cat = get_queried_object();
$args = array( 'parent'=>$current_cat->term_id, 'child_of' => $current_cat->term_id, );
$categories = get_categories( $args );
foreach($categories as $category) { ?>
<h2><?php echo $category->name ;?></h2>
<p> etc....</p>
<?php } ?>
In my functions.php file, I've added the following custom function using pre_get_posts:
add_action( 'pre_get_posts', 'main_query_without_subcategory_posts' );
function main_query_without_subcategory_posts( $query ) {
if ( ! is_admin() && $query->is_main_query() ) {
// Not a query for an admin page.
// It's the main query for a front end page of your site.
if ( is_category() ) {
//Get the current category
$current_category = get_queried_object();
//get the id of the current category
$current_cat_id = $current_category->term_id;
//find the children of current category
$cat_args = array( 'parent'=>$current_category->term_id, 'child_of' => $current_category->term_id, );
$subcategories = get_categories( $cat_args );
//Get a list of subcategory ids, stick a minus sign in front
$subcat_id = array();
foreach($subcategories as $subcategory) {
$subcat_id[] = " -". $subcategory->term_id;
}
//join them together as a string with a comma seperator
$excludesubcatlist = join(',', $subcat_id);
//If you have multiple parameters, use $query->set multiple times
$query->set( 'posts_per_page', '10' );
$query->set( 'cat', ''.$current_cat_id.','.$excludesubcatlist.'' );
}
}
}
Then in the archive.php, below the subcategories, I've added the regular WordPress loop which is now being modified by the above function:
<?php while (have_posts() ) : the_post(); ?>
<h2><?php the_title();?></h2>
<p> etc....</p>
<?php endwhile;?>
Though the WordPress codex says that using "category__in" will exclude posts from subcategories, that didn't work for me and subcategory posts were still showing.
https://codex.wordpress.org/Class_Reference/WP_Query#Category_Parameters
https://developer.wordpress.org/reference/hooks/pre_get_posts/