Woocommerce Custom shop page with infinte load - wordpress

Hi currently I am creating a woocommerce custom shop page template .
For this, I have created a new template inside my theme page called custom-shop & I have created new page called my shop and assign custom-shop template.
I have 3 main category called car , bus, boat . Now I am going to display each category with its description and product details
So I write the following code in my cutom-shop template(custom-shop.php)
custom-shop.php
/*
Template name: custom-shop
*/
BLOCKS OF CODE
<div class="category-block">
<h2>Car</h2>
<p class="description">Car Description</p>
<?php echo do_shortcode('[products limit="40" columns="4" category="car"]'); ?>
</div>
<div class="category-block">
<h2>Bus</h2>
<p class="description">Bus Description</p>
<?php echo do_shortcode('[products limit="40" columns="4" category="bus"]'); ?>
</div>
<div class="category-block">
<h2>Boat</h2>
<p class="description">Boat Description</p>
<?php echo do_shortcode('[products limit="40" columns="4" category="boat"]'); ?>
</div>
Here Everything is working fine . But the problem is the page load time is high , because every product is loading together . How can i solve this issue , how can i implement infinite load ?
What I need is first display car and it's 4 products then user scroll down display other products in car . After car products finished then display bus and it's 4 products , like this
what I tried is
After searching I found a plugin https://wordpress.org/plugins/ajax-load-more/ and i t help to resolve some issue and i used this plugin code
<div class="category-block">
<h2>Car</h2>
<p class="description">Car Description</p>
<?php do_shortcode('[ajax_load_more post_type="product" columns="4" css_classes="products" posts_per_page="4" transition="fade" taxonomy="product_cat" taxonomy_terms="car" taxonomy_operator="IN" button_label=""]'); ?>
</div>
<div class="category-block">
<h2>Bus</h2>
<p class="description">Bus Description</p>
<?php do_shortcode('[ajax_load_more post_type="product" columns="4" css_classes="products" posts_per_page="4" transition="fade" taxonomy="product_cat" taxonomy_terms="car" taxonomy_operator="IN" button_label=""]'); ?>
</div>
<div class="category-block">
<h2>Car</h2>
<p class="description">Boat Description</p>
<?php do_shortcode('[ajax_load_more post_type="product" columns="4" css_classes="products" posts_per_page="4" transition="fade" taxonomy="product_cat" taxonomy_terms="car" taxonomy_operator="IN" button_label=""]'); ?>
</div>
But here the problem is that when I scroll down it will first show car and it's 4 products , then bus and it's 4 products again load other products for car . So it's not also proper solution .
Please help , to solve this issue .

actually if you want to do it by yourself, I will just suggest you to follow this guide, cmmon click me! -> It will be lots more helpful than any huge reply in here.
This guy goes trough all the ajax proceses that you will need to use. Also you can just parse a piece of his code and get it all done. Shortly, you just need ajax. more explicit -> you can see in this video
I will paste in here the code result of the guide bypassing all the small procedures for a better understanding
First of all he created a template to output the content wich looks like this
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header text-center">
<?php the_title( '<h1 class="entry-title">', '</h1>'); ?>
<div class="entry-meta">
<?php echo sunset_posted_meta(); ?>
</div>
</header>
<div class="entry-content">
<?php if( sunset_get_attachment() ): ?>
<a class="standard-featured-link" href="<?php the_permalink(); ?>">
<div class="standard-featured background-image" style="background-image: url(<?php echo sunset_get_attachment(); ?>);"></div>
</a>
<?php endif; ?>
<div class="entry-excerpt">
<?php the_excerpt(); ?>
</div>
<div class="button-container text-center">
<?php _e( 'Read More' ); ?>
</div>
</div><!-- .entry-content -->
<footer class="entry-footer">
<?php echo sunset_posted_footer(); ?>
</footer>
</article>
Next step was to validate in wp the ajax function
add_action( 'wp_ajax_nopriv_sunset_load_more', 'sunset_load_more' );
add_action( 'wp_ajax_sunset_load_more', 'sunset_load_more' );
function sunset_load_more() {
$paged = $_POST["page"]+1;
$prev = $_POST["prev"];
$archive = $_POST["archive"];
if( $prev == 1 && $_POST["page"] != 1 ){
$paged = $_POST["page"]-1;
}
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'paged' => $paged
);
if( $archive != '0' ){
$archVal = explode( '/', $archive );
$type = ( $archVal[1] == "category" ? "category_name" : $archVal[1] );
$args[ $type ] = $archVal[2];
$page_trail = '/' . $archVal[1] . '/' . $archVal[2] . '/';
} else {
$page_trail = '/';
}
$query = new WP_Query( $args );
if( $query->have_posts() ):
echo '<div class="page-limit" data-page="' . $page_trail . 'page/' . $paged . '">';
while( $query->have_posts() ): $query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
echo '</div>';
else:
echo 0;
endif;
wp_reset_postdata();
die();
}
function sunset_check_paged( $num = null ){
$output = '';
if( is_paged() ){ $output = 'page/' . get_query_var( 'paged' ); }
if( $num == 1 ){
$paged = ( get_query_var( 'paged' ) == 0 ? 1 : get_query_var( 'paged' ) );
return $paged;
} else {
return $output;
}
}
And the last step will be the AJAX function itself.
/* Ajax functions */
$(document).on('click','.sunset-load-more:not(.loading)', function(){
var that = $(this);
var page = $(this).data('page');
var newPage = page+1;
var ajaxurl = that.data('url');
var prev = that.data('prev');
var archive = that.data('archive');
if( typeof prev === 'undefined' ){
prev = 0;
}
if( typeof archive === 'undefined' ){
archive = 0;
}
that.addClass('loading').find('.text').slideUp(320);
that.find('.sunset-icon').addClass('spin');
$.ajax({
url : ajaxurl,
type : 'post',
data : {
page : page,
prev : prev,
archive : archive,
action: 'sunset_load_more'
},
error : function( response ){
console.log(response);
},
success : function( response ){
if( response == 0 ){
$('.sunset-posts-container').append( '<div class="text-center"><h3>You reached the end of the line!</h3><p>No more posts to load.</p></div>' );
that.slideUp(320);
} else {
setTimeout(function(){
if( prev == 1 ){
$('.sunset-posts-container').prepend( response );
newPage = page-1;
} else {
$('.sunset-posts-container').append( response );
}
if( newPage == 1 ){
that.slideUp(320);
} else {
that.data('page', newPage);
that.removeClass('loading').find('.text').slideDown(320);
that.find('.sunset-icon').removeClass('spin');
}
revealPosts();
}, 1000);
}
}
});
});
/* scroll function */
$(window).scroll( function(){
var scroll = $(window).scrollTop();
if( Math.abs( scroll - last_scroll ) > $(window).height()*0.1 ) {
last_scroll = scroll;
$('.page-limit').each(function( index ){
if( isVisible( $(this) ) ){
history.replaceState( null, null, $(this).attr("data-page") );
return(false);
}
});
}
});
/* helper functions */
function revealPosts(){
var posts = $('article:not(.reveal)');
var i = 0;
setInterval(function(){
if( i >= posts.length ) return false;
var el = posts[i];
$(el).addClass('reveal').find('.sunset-carousel-thumb').carousel();
i++
}, 200);
}
function isVisible( element ){
var scroll_pos = $(window).scrollTop();
var window_height = $(window).height();
var el_top = $(element).offset().top;
var el_height = $(element).height();
var el_bottom = el_top + el_height;
return ( ( el_bottom - el_height*0.25 > scroll_pos ) && ( el_top < ( scroll_pos+0.5*window_height ) ) );
}
});
I would suggest you to follow the guide created by alecadd because it will be much easier to understand the process and suit it for your purposes. Hope it's enough now!
Cheers.

Related

The page reloads when I add my codes to functions.php in sage (wordpress)

The page reloads when I use get_transient function.
The below statement shows my codes:
I'm using sage and below codes placed in a blade file like feature.blade.php
<div class="popular-products-holder">
<?php
$products = get_remote_product('home');
if( ! empty( $products['data'] ) ) :
foreach( $products['data'] as $product) :
if($product->images[0]->src) :
?>
<div id="<?php echo $product->id; ?>" style="background-image:url();" data-srcset="<?php echo $product->images[0]->src; ?>" class="lazy-bg col-12 col-sm-6 col-md-6 col-lg-6 col-xl-3 pp">
<div class="title-select row align-items-end">
<div class="col-12 col-sm-7 align-self-center product-info">
<h4>{{ $product->name }}</h4>
</div>
<div class="col-12 col-sm-5 align-self-center">
<a id="select{{ $product->id }}" class="btn btn-black btn-block product-sel" href="/find-what-you-need-where-ever-you-are/#filter-block-start">Select</a>
</div>
</div>
</div>
<?php
endif; endforeach; endif;
?>
</div>
I used the below codes in function php:
function get_remote_product($page = null){
// source url
$remote_url = 'https://woocommerce-490897.com/wp-json/wc/v3/products';
// check the transient
$body = get_transient('prospray_product_'.$page);
// fetch data from source if not exist transient
if(empty($body)){
$data = config_get_remote($page,$remote_url);
$body = wp_remote_retrieve_body( $data['result'] );
set_transient('prospray_product_'.$page,$body,86400);
}
return ['data' => json_decode($body) , 'reference_site'=>$remote_url];
}
function config_get_remote($page = null, $remote_url){
// per page
$count = 12;
// per page for home
if($page == 'home'){
$count=4;
$page=1;
}
// check language
$lang = weglot_get_current_language() == 'no' ? 'nb' : 'en';
// set paginiation
$page = $page != null ? "&page={$page}" : '' ;
// make query
$params = "?per_page={$count}&orderby=menu_order&order=asc&lang={$lang}".$page;
// set headers
$auth = array(
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( 'ck_a442a87286a6f9269e54dd47cbf:cs_8b3a4ff671e46843a88415e4214' )
)
);
// get data
$result = wp_remote_get( $remote_url.$params ,$auth);
if( is_wp_error( $result ) ) :
return FALSE;
endif;
// get total pages for next/prev links
$totalpages = wp_remote_retrieve_header($result,'x-wp-totalpages');
return [
'result'=>$result,
'totalpages'=>$totalpages
];
}
How can I fix it? ( I see the reload page in waterfall whenever I use the transient )
I checked the plugins and without any plugins I had same result.
Thanks in advance.
I removed the style="background-image:url();" from html and it fixed!

Pagination on an Advanced Custom Fields Repeater Stopped Working

Not sure if this was since upgrading to PHP 7.2 or the latest WordPress version but the following code used to allow me to add pagination for repeater values. Now what seems to happen is that the page just reloads the page. The pagination link shows as /example/2/, this used to load the page but now it is just reloading example.
Any ideas?
<?php
/*
* Paginatation on Advanced Custom Fields Repeater
*/
if ( get_query_var('paged') ) {
$page = get_query_var('paged');
} elseif ( get_query_var('page') ) {
$page = get_query_var('page');
} else {
$page = 1;
}
// Variables
$row = 0;
$images_per_page = 10; // How many images to display on each page
$images = get_field( 'image_gallery' );
$total = count( $images );
$pages = ceil( $total / $images_per_page );
$min = ( ( $page * $images_per_page ) - $images_per_page ) + 1;
$max = ( $min + $images_per_page ) - 1;
// ACF Loop
if( have_rows( 'image_gallery' ) ) : ?>
<?php while( have_rows( 'image_gallery' ) ): the_row();
$row++;
// Ignore this image if $row is lower than $min
if($row < $min) { continue; }
// Stop loop completely if $row is higher than $max
if($row > $max) { break; } ?>
<?php $img_obj = get_sub_field( 'image' ); ?>
<a href="<?php echo $img_obj['sizes']['large']; ?>">
<img src ="<?php echo $img_obj['sizes']['thumbnail']; ?>" alt= "Your ALT Tag" />
</a>
<?php endwhile;
// Pagination
echo paginate_links( array(
'base' => get_permalink() . '%#%' . '/',
'format' => '?paged=%#%',
'current' => $page,
'total' => $pages
) );
?>
<?php else: ?>
<p>No images found</p>
<?php endif; ?>
There was a bug tracker after 5.5:
https://core.trac.wordpress.org/ticket/50976#comment:7
You might check some of the solutions there. It seems to be an issue with the query var "page" which is reserved in WordPress core, since it normally uses ?p and ?page to redirect to a certain page.
So you might use something else.

Thumbnail and price not showing on related products section

Well, I'm trying to create a module with the related products I have in my shop. My template has a file in the route /theme-name/woocommerce/single-product/related.php. In this we can see some code of how it call to the related product. It use the template as the listing product page (same template), but when I tried to shpw the thumbnail or the price it doesn't work. It only show me the title of the product, nothing else.
This is the code I have in my template for the file /related.php
<?php
if ( $related_products ) : ?>
<section id="nm-related" class="related products">
<div class="nm-row">
<div class="col-xs-12">
<h2><?php esc_html_e( 'Related products', 'woocommerce' ); ?></h2>
<?php woocommerce_product_loop_start(); ?>
<?php foreach ( $related_products as $related_product ) : ?>
<?php
$post_object = get_post( $related_product->get_id() );
setup_postdata( $GLOBALS['post'] =& $post_object );
wc_get_template_part( 'content', 'product' ); ?>
<?php endforeach; ?>
<?php woocommerce_product_loop_end(); ?>
</div>
</div>
</section>
<?php endif;
After that I use the "content-product" template like the listing page, where I don't have any problem.
For example, to show the product thumbnail I tried this:
<div class="nm-shop-loop-thumbnail nm-loader">
<a href="<?php echo esc_url( get_permalink() ); ?>" class="nm-shop-loop-thumbnail-link woocommerce-LoopProduct-link">
<?php
$id_pro = get_the_ID();
$pro_2 = get_post_thumbnail_id($id_pro);
$featured_image_url = wp_get_attachment_url( $pro_2 );
if(! empty( $featured_image_url )) { ?>
<?php
/**
* Hook: woocommerce_before_shop_loop_item_title.
*
* #hooked woocommerce_show_product_loop_sale_flash - 10
* #hooked woocommerce_template_loop_product_thumbnail - 10
*/
do_action( 'woocommerce_before_shop_loop_item_title' );
} else { ?>
<img src="https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg" data-src="https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg" data-srcset="https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 350w, https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 250w, https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 400w" alt="" sizes="(max-width: 350px) 100vw, 350px" width="350" height="420" class="attachment-woocommerce_thumbnail size-woocommerce_thumbnail wp-post-image lazyloaded" srcset="https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 350w, https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 250w, https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 400w">
<?php
}
?>
</a>
</div>
And as I said, it works for the listing page but not inside single page product in related products section.
The $id_pro variable work in both pages, it shows the id of the product, but when I try to get the thumbnail URL with this id it return me "".
In the first image you can see the example for the listing page, on the other hand, in the second image you can see the example for the related products for the single product page:
I change the functionality and I created a new related product module, but still not working I don't know why...
I tried this:
In my related.php:
// Same category products query
$mproduct = new WP_Query(array(
'post_type' => 'product',
'product_cat' => $cat_slug,
'posts_per_page' => -1,
));
// Get query data
$posts = $mproduct->get_posts();
$num = $mproduct->post_count;
// Create new array with the actual product in it
$array_pro = [];
$array_pro[] = $product_id;
// Function for check if product is in array
function test_function($rand_pro, $array_pro, $posts, $num) {
if (in_array($rand_pro, $array_pro)) {
$new_pro_id = $posts[rand(0,$num-1)]->ID;
return true;
} else {
return false;
}
}
// If array is not full insert next elements
while (count($array_pro) < 5) {
$rand_pro = $posts[rand(0,$num-1)]->ID;
$pro_in_array = test_function($rand_pro, $array_pro, $posts, $num);
if ($pro_in_array == false) {
$array_pro[] = $rand_pro;
}
}
// Remove first element of array
array_shift($array_pro);
?>
<div class="related-products-row">
<?php
foreach( $array_pro as $post ) {
$rel_product_id = $post;
$rel_product_title = get_the_title($rel_product_id);
$rel_product_link = get_the_permalink($rel_product_id);
$rel_product_img_url = get_the_post_thumbnail($rel_product_id);
$_product = wc_get_product( $rel_product_id );
$rel_product_ref = $_product->get_attribute( 'reference' );
?>
<div class="col-md-3">
<p><?php echo $rel_product_img_url; ?></p>
</div>
<?php
}
?>
</div>
If you can see, when I try to getthe name I don't have problems but when I try to get the post_thumbnail_url or ref_number it doesn't show anything I don't know why.

using isotope library with square layout library

My problem is to create layout as in example http://www.jqueryscript.net/demo/Responsive-Square-Grid-Layout-jQuery/ and use isotop filtering.
And I use also isotope library for filtering,
here is a code for filtering:
var $grid = jQuery('.mansory_wrapper').isotope({
itemSelector: '.grid-item1',
percentPosition: true,
masonry: {
columnWidth: 100
}
});
But I have a gap. When I use only this library, the filtering fails.
Has any idea to do it?
Do you have try using isotope library from Masonry? I think this is great, i have try created in my project you can check in here.
This is my code for display Filtered button in WordPress
<div class="button-group filters-button-group">
<?php
$taxonomy = 'category-produk';
$terms = get_terms($taxonomy);
foreach ( $terms as $term ) {
echo '<button class="button" data-filter=".'.$term->slug.'">'.$term->name.'</button>';
}
?></div>
Also this for display the Grid in WordPress
<div class="grid">
<?php
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'produk',
'posts_per_page' => -1
);
$product = new WP_Query($args);
if( $product-> have_posts() ){
while ( $product->have_posts() ) : $product->the_post();
$categories = get_the_terms(get_the_ID(), 'category-produk');
$class = "";
foreach($categories as $cat){
$class .= $cat->slug . " ";
}
?>
<div class="col-md-4 <?php echo $class; ?>">
<div class="side-module text-center">
<a class="img-module clearfix" href="<?php echo get_the_permalink(); ?>">
<?php
$id = get_the_ID();
$url = wp_get_attachment_url( get_post_thumbnail_id($id), 'biofarma-featured-image' );
//echo 'Image '.$url;
if ( !empty($url) ) {
echo '<img src="' . $url . '" />';
}
else {
echo '<img src="' . get_template_directory_uri() . '/img/dummy.png" />';
}
?>
</a>
<a class="view-prod" href="<?php echo get_the_permalink(); ?>"> <h4><?php the_title(); ?></h4> </a>
<p><?php echo get_post_meta($id, 'meta_data', true); ?></p>
</div>
</div>
<?php
endwhile;
wp_reset_postdata();
}
?>
</div>
Also in my jQuery script like this:
(function($) {
"use strict"; // Start of use strict
$(function(){
var $grid = $('.grid').isotope({
itemSelector: '.col-md-4',
layoutMode: 'masonry'
});
$grid.imagesLoaded().progress( function() {
$grid.isotope('layout');
});
var filterFns = {
// show if name ends with -ium
ium: function() {
var name = $(this).find('.name').text();
return name.match( /ium$/ );
}
};
$('.filters-button-group').on( 'click', 'button', function() {
var filterValue = $( this ).attr('data-filter');
// use filterFn if matches value
filterValue = filterFns[ filterValue ] || filterValue;
$grid.isotope({ filter: filterValue });
});
// change is-checked class on buttons
$('.button-group').each( function( i, buttonGroup ) {
var $buttonGroup = $( buttonGroup );
$buttonGroup.on( 'click', 'button', function() {
$buttonGroup.find('.is-checked').removeClass('is-checked');
$( this ).addClass('is-checked');
});
});
});
});
Hopefully this is clear and helping you.

Categories and Sub Categories in custom taxonomies

I find and use the following code to display sub categories for default taxonomy 'category' on my site, but I created a custom taxonomy , and can not alter the code so that he was doing the same thing for the new taxonomy, help please
<?php
if(is_category()) {
$subcategories = get_terms('category', 'parent='.get_query_var('cat'));
if(empty($subcategories)) {
$thiscat = get_term(get_query_var('cat'),'category');
$subcategories = get_terms('category', 'parent='.$thiscat->parent.'');
}
if(empty($subcategories)) $subcategories = array();
if(!empty($subcategories)) {
echo '<ul>';
foreach($subcategories as $subcat) {
if(get_query_var('cat') == $subcat->term_id) $current = ' current-cat'; else $current = '';
echo '
<li class="cat-item cat-item-'.$subcat->term_id.$current.'">
'.$subcat->name.'
</li>';
}
echo '</ul>';
}
}
else {
// If no current cat query, just get the top level ones using wp_list_categories.
?>
<ul>
<?php wp_list_categories('title_li=&depth=1');?>
</ul>
<?php
}
?>
It turned out, the code works as I wanted, but if it can be optimize I'll be glad to help ... This code displays the subcategories to the main categories of taxonomies.
If anyone should use, just change 'auto' to the name of your taxonomy. my custom taxonomy is 'auto'
<?php
if(is_tax()) {
$subcategories = get_terms('auto', 'parent='.get_queried_object()->term_id);
if(empty($subcategories)) {
$thiscat = get_term(get_queried_object()->term_id,'auto');
$subcategories = get_terms('auto', 'parent='.$thiscat->parent.'');
}
if(empty($subcategories)) $subcategories = array();
if(!empty($subcategories)) {
echo '<ul>';
foreach($subcategories as $subcat) {
if(get_queried_object()->term_id == $subcat->term_id) $current = ' current-cat'; else $current = '';
echo '
<li class="cat-item cat-item-'.$subcat->term_id.$current.'">
'.$subcat->name.'
</li>';
}
echo '</ul>';
}
}
else {
// If no current cat query, just get the top level ones using wp_list_categories.
?>
<ul>
<?php wp_list_categories('taxonomy=auto&title_li=&depth=1');?>
</ul>
<?php
}
?>
Thanks for the corrected code.
I have added a bit for people who want to exit of the loop once they come to any end. Instead of showing the parent categories tree i modified a bit to display the image and title of the of the products or services under that specific category. Following is the code
if(is_tax()) {
$subcategories = get_terms('product_categories', 'parent='.get_queried_object()->term_id);
// this is the change which display all the products in the specific category if it does not have child categories
if(empty($subcategories)) {
$thiscat = get_term(get_queried_object()->term_id,'product_categories');
if (have_posts('thiscat')):while (have_posts('thiscat')) : the_post('thiscat');{?>
<div class="box cat-item-<?php $subcat->name.$current ;?>" style="min-height: 231px; margin-bottom:10px">
<?php the_post_thumbnail('thumbnail');?>
<h5><a title="<?php the_title(); ?>" href="<?php the_permalink($post->ID); ?>"><?php the_title(); ?></a></h5></h5></div>
<?php }
endwhile;
else : {
?>
<div class="box cat-item cat-item-<?php $subcat->name.$current; ?>" style="min-height: 231px; margin-bottom:10px">
<h5>Products will be upadated later. Do visit Later </h5 >
</div>
<?php }
endif;
}
if(empty($subcategories)) $subcategories = array();
if(!empty($subcategories)) {
echo '<div class="fixed-row clearfix dynamic-fixedRow-735" id="row_order_2">';
foreach($subcategories as $subcat) {
if(get_queried_object()->term_id == $subcat->term_id) $current = ' current-cat'; else $current = '';
echo '
<div class="box cat-item cat-item-'.$subcat->name.$current.'" style="min-height: 231px; margin-bottom:10px"><h5>
'.$subcat->name.'
</h5></div>';
}

Resources