My Woocommerce website shows 3 columns of products in every loop page.
I'm making some custom landing page where i want to show the loop of products in 4 column instead of 3.
I tryed with this code inside function.php:
add_filter('loop_shop_columns', 'loop_columns');
if (!function_exists('loop_columns')); {
function loop_columns() {
if (is_page(91040)){
return 4;
}else{
return 3;
}
}
}
without success.
Is there a way to have in a single or specific page a different number of column compared to the others?
If you are using woothemes theme or any other theme which is already utlisiing the loop_columns filter, then you need to override that with two things, by removing the if !function exit condition, and also adding pririty to filter high enough like 999 so it is applied at the last:
e.g.
// Override theme default specification for product # per row
function loop_columns() {
return 5; // 5 products per row
}
add_filter('loop_shop_columns', 'loop_columns', 999);
You may adjust the function as per you needs like adding page template conditional as you have in your original code.
Source:
https://docs.woothemes.com/document/change-number-of-products-per-row/ Second headline
I solved the issue. The problem was in the is_page function. It can't get the correct ID so i have found a workaround:
function loop_columns() {
global $woocommerce;
$url = explode('?', 'http://'.$_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
$ID = url_to_postid($url[0]);
if ($ID == 91040){
return 4;
}else{
return 3;
}
}
add_filter('loop_shop_columns', 'loop_columns', 999);
I spent a lot of brain matter trying to control the number of columns in a custom template. I am new to WooCommerce and Wordpress so am on a learngin curve. However, I started off with:
<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->
When applied as a template it gave me a custom loop that I could fiddle with. However, from there I wanted 5 columns and just could not figure it out. I tried all the things Google could throw up such as filers and such. However, I finally discovered that the above snippet starts off with the
<ul class="products">
tag. All I did was dd the appropriate colum class:
<ul class="products columns-5">
This might require additional thinking regarding the responsive aspects, but it crosses the immediate barrier of controlling columns with that snippet. However, it does actually seem to respond quite well.
Related
Dear fellow coders and community,
I have really researched this issue for quite a while now, and though I have some coding background, I can't seem to figure out the issue. No links to the topic helped since they all only suggest the code snippet I am using already.
I have a working Word Press installation : Version 4.8.2 & WooCommerce : Version 3.3.5
My Theme consists of essentially 2 Files, since I had to breakdown the whole thing in order to find the issue.
The functions.php
<?php
add_filter('loop_shop_columns', 'loop_columns');
if (!function_exists('loop_columns')) {
function loop_columns() {
return 5; // 3 products per row
}
}
add_filter( 'loop_shop_per_page', 'new_loop_shop_per_page', 999999999999 );
function new_loop_shop_per_page( $cols ) {
// $cols contains the current number of products per page based on the value stored on Options -> Reading
// Return the number of products you wanna show per page.
//
var_dump($cols);
$cols = 3;
return $cols;
}
?>
The code is just supposed to limit the amount of products displayed on the product category page to 3.
And the index.php
<?php
get_header();
?>
<div class="container content pr-0 pl-0" >
<div class="index">
<?php if ( have_posts() ) : the_post(); ?>
<?php the_content(); ?>
<?php endif; ?>
</div>
</div>
<?php
get_footer();
?>
This is just the essential index file needed by any wordpress installation.
Now I tried changing backend settings already with the default 2017 theme and it worked just fine...so it cannot be some backend thing.
What could be the issue here?
Any help or leads will be much appreciated! Thanks!
The loop_shop_columns filter doesn't effect the number of posts shown, just the number of columns on the page (number of products going across before a new line is started).
The number of products shown on any page is actually taken from the WordPress Settings > Reading "Blog pages show at most" setting.
You can also change the number programatically by using the pre_get_posts filter.
add_action( 'pre_get_posts', 'rc_modify_query_exclude_category' );
// Create a function to excplude some categories from the main query
function rc_modify_query_exclude_category( $query ) {
// Check if on frontend and main query is modified
if ( ! is_admin() ) {
$query->set( 'posts_per_page', '-1' );
} // end if
}
I am trying to create a custom search results page where Woocommerce product results are displayed separately to blog / general posts.
My aim is to display them as separate blocks with different styling.
[Block 1] - Woocommerce results
[Block 2] - Blog / Post results
I have managed to display the products in one loop, but I am struggling to exclude products from the post loop.
I have tried creating a custom loop, however this just displays all the posts within those terms, rather than the posts returned in the search.
The loop I usually use is:
<?php $loop = new WP_Query( array( 'post_type' => 'post' ?>
<p>Something here</p>
<?php endwhile; wp_reset_query(); ?>
However I believe this just isn't compatible and suitable for my needs.
If there's a better solution to separating these I would absolutely love to hear more.
The problem you are having is that you have one main query, where you actually want to do two queries. You could of course modify the main query to contain both post types, but you would end up with a random number of both post types where you actually want to fill both columns.
If you modify the main query to only return one of the columns, you end up with a situation where it is awful to run the other query to get the rest of the posts. I think you should be able to use the posts_join and posts_where filters if you need them, but I am unsure about posts_search. You can use either WP_Query or get_posts to finally do the two queries you need.
<?php
// Since we are searching, we probably should get the search keyword
$search = get_query_var('s');
// Since we want to be able to navigate, we probably should figure out on which page we are
$paged = get_query_var('paged');
// Anything else we want to do in search queries we should be able to do in
// a posts_join or posts_where filter by checking if is_search() is true
// With that out of the way, we can construct our queries
$query_posts_page = new WP_Query([
's' => $search,
'paged' => $paged,
'post_type' => ['post', 'page']
]);
$query_woocommerce = new WP_Query([
's' => $search,
'paged' => $paged,
'post_type' => 'product'
]);
?>
<div class="col">
<?php
if ( $query_posts_page->have_posts() ) {
while ( $the_query->have_posts() ) {
$query_posts_page->the_post();
echo get_the_title();
}
/* Restore original Post Data */
wp_reset_postdata();
} else {
echo 'Nope, no more data';
}
?>
</div>
<div class="col">
<?php
if ( $query_woocommerce->have_posts() ) {
while ( $query_woocommerce->have_posts() ) {
$query_posts_page->the_post();
echo get_the_title();
}
/* Restore original Post Data */
wp_reset_postdata();
} else {
echo 'Nope, no more data';
}
?>
</div>
There is however still another problem. we can't automatically generate pagination, considering we are running two custom queries instead of the main query. Furthermore, we are unlikely to have an equal number of normal page/posts and products.
We can figure out what the maximum number of pages is for each of the loops by using max_num_pages. You can generate something yourself using that.
<?php
$maximum_page = max($query_posts_page->max_num_pages, $query_woocommerce->max_num_pages);
for( $i = 1; $i < $maximum_page; $i++) {
echo "{$i} ";
}
I’m having a little problem understanding what (my) PHP is doing when I’m trying to display different Custom Posts and Advanced Custom fields on the same page.
I have added different Advanced Custom Fields to a page, and I have custom posts that I am trying to display using the template.
I’m calling my custom fields throughout the template using:
<?php the_field(‘field-name’) ?>
My custom posts are called through loops like this (somewhere around the middle of the template):
<?php
$args = array(
'post_type' => ‘foo’
);
$foo = new WP_Query( $args );
if( $foo->have_posts() ) {
while( $foo->have_posts() ) {
$foo->the_post();
?>
<?php the_content() ?>
<?php
}
}
else {
// SOME MESSAGE
}
?>
The content of the Advanced Custom Fields is showing fine, above those loops. Below the loops it just doesn’t display.
I can’t figure out why the content is not showing up.
I assume it has to do with the while or if statements of the loops. If I remove the loops, the content of any Advanced Custom Field below does display.
When you use WP_Query(), you are changing the default $post variable on the page each time you loop through a post. You need to call wp_reset_postdata() after your loop to reset that $post variable so it corresponds to the current page again. You can call the function after your 'while' loop -
<?php
$args = array(
'post_type' => ‘foo’
);
$foo = new WP_Query( $args );
if( $foo->have_posts() ) {
while( $foo->have_posts() ) { $foo->the_post();
the_content();
} wp_reset_postdata();
}
else {
// SOME MESSAGE
}
?>
I'm using this code to show recent posts with a shortcode that I found at smashingmagazine site. It's not working the correct way, I mean when I specify the number of posts to show, it just shows one post with every number I specify.
Here's the code:
function recent_posts_function() {
query_posts(array('orderby' => 'date', 'order' => 'DESC' , 'showposts' => 1));
if (have_posts()) :
while (have_posts()) : the_post();
$return_string = ''.get_the_title().'';
endwhile;
endif;
wp_reset_query();
return $return_string;
}
function register_shortcodes(){
add_shortcode('recent-posts', 'recent_posts_function');
}
add_action( 'init', 'register_shortcodes');
I've changed the showposts number, but nothing happens. What's wrong?
Any suggestions?
Just before I start, never use query_posts to construct or modify any type of query. It outright fails in many scenarios, specially pagination, and breaks the main query, which you should never do.
If you need to construct custom queries, rather use WP_Query
Also, showposts have been deprerciated long time ago and have been replaced with posts_per_page
You should read the Shortcode API, this should give you an overview of what is happening and how shortcodes should be used and created. One important thing to remember here, shortcode content should be returned, not echo'ed. Here is also a tutorial that help me a lot.
Just a quick tip here, shortcodes should always go into a plugin. If you haven't yet created one, go and read MU-Plugin (must-use-plugin)
The correct way of constructing your shortcode would be as follows: (Your shortcode will be [my-shortcode]) This is untested though
add_shortcode( 'my-shortcode', 'my_custom_query_shortcode' );
function my_custom_query_shortcode( $atts ) {
ob_start();
$query = new WP_Query(array('orderby' => 'date', 'order' => 'DESC' , 'posts_per_page' => 1));
if ( $query->have_posts() ) :
while($query->have_posts()) : $query->the_post();
//YOUR LOOP ELEMENTS
<?php
endwhile;
$myvariable = ob_get_clean();
return $myvariable;
endif;
}
Just replace your code with mine, and make sure that you add your loop elements.
Just one more thing, remember, if you run any custom query on a page, and you have not reset that query, it will influence any other query on that page, even this shortcode, so always make sure that you reset all custom queries once you've done
My code is
I have written this code for pagination before my loop
$arrangement = get_cat_ID('arrangement');
$antiquarianism = get_cat_ID('antiquarianism');
$paged = (get_query_var('page')) ? get_query_var('page') : 1;
print_r($paged);
$query = query_posts(array(
'page' => intval($paged),
'category__not_in' => array($arrangement, $antiquarianism ) ));
every time its printing 1.
Have you tried a var_dump of $paged? Or resetting the get_query_var('page') as suggested here : worpress support
I have had a similar issue before. Unfortunately it could be a number of things.
One possibility is the treatment of the page query in relation to the Wordpress 'loop'. I was just reading through the documentation for query_posts and spotted this:
Preserving the Original Query (Pagination etc.)
By default running query_posts will completely overwrite all existing query variables on the current page. Pagination, categories dates etc. will be lost and only the variables you pass into query_posts will be used.
If you want to preserve the original query you can merge the original query array into your parameter array:
global $wp_query;
query_posts(
array_merge(
array( 'cat' => 1 ),
$wp_query->query
)
);
http://codex.wordpress.org/Function_Reference/query_posts
I'm not sure if this affects you, but it's worth shot.
EDIT: you could also try running a seperate get_post loop after 'the loop' has closed (i.e. after the main endwhile). This has solved issues for me in the past
<?php
// custom pagination improvements
//http://codex.wordpress.org/Template_Tags/get_posts
$lastposts = get_posts('numberposts=50&order=DESC&orderby=ID');
setup_postdata($lastposts);
$valid_posts = array ();
$lastposts = (array) $lastposts;
foreach ($lastposts as $post) {
$post = (array) $post;
// Sort through arrays here - get the next valid post
switch (true) {
case ($post['post_status'] == 'publish' && $post['ID'] < $curr_pid[0]):
array_push($valid_posts, $post);
break;
default:
break;
}
}
$nextArray = $valid_posts[0];
?>
<ul class="pagination">
<li class="next"><?php echo ($nextArray['post_title']); ?></li>
</ul>
This is some code I wrote for the front page so it would just show "next", and then link to the next post according to my filter (rather than what Wordpress thought should go next). You could of course echo out multiple links with numbers using a foreach loop. This will complicate thing a little, but it gives you very granular control over what is happening in the pagination.
Does that help you?