Create custom post slider using slick - javascript

I have been trying to create a recent post slider using slick-slider for my wordpress page. I want to be able to add the slider into elementor by using a shortcode. I don't have a lot of experience in coding. So I am not sure where I am going wrong. I managed to compose the following piece of coding based on some examples that I found online and I added the javascript file using a custom js plugin for wordpress. I obviously have done something wrong, because if I activate this file, elementor will not load because of a critical error. I have been trying to create custom post slider for a while now without any success. I would really appreciate any help I can get. Thanks!
//Enqueue Slick
function add_slick() {
wp_enqueue_style( 'slider', get_stylesheet_directory_uri() . '/assets/css/slick.css' );
wp_enqueue_style( 'slider-theme', get_stylesheet_directory_uri() . '/assets/css/slick-theme.css');
wp_enqueue_script( 'slick-script', get_stylesheet_directory_uri() . '/assets/js/slick.min.js');
}
add_action( 'wp_enqueue_scripts', 'add_slick' );
//Build Shortcode to Loop Over Testimonials
function recentpost_loop_func( $atts ) {
ob_start();
$query = new WP_Query( array(
'post_type' => 'post',
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'date',
) );
if ( $query->have_posts() ) { ?>
<div class="recentpost-slider">
<?php while ( $query->have_posts() ) : $query->the_post(); ?>
<div class="single-post">
<a class="single-post-image" href="<?php the_permalink(); ?>"><?the_post_thumbnail(); ?></a>
<a class="single-post-title" href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</div>
<?php endwhile;
wp_reset_postdata(); ?>
</div>
<?php $myvariable = ob_get_clean();
return $myvariable;
}
};
add_shortcode( 'recentpostSlider', 'recentpost_loop_func' );
//Initiliaze Slick
jQuery(document).ready(function(){
$('.recentpost-slider').slick({
centerMode: true,
centerPadding: 50px,
});
});

Related

Speed up admin-ajax.php request in CPT filters

I have custom post types with JS filtering (based on category). There are simple html boxes + php code with ACF fields what display after select category.
Problem is it take 1 second or more to load all this html boxes so its not so smooth.
This is my JS (file filters.js):
(function($){
$(document).ready(function(){
$(document).on('click', '.js-filter-item > a', function(e){
e.preventDefault();
var category = $(this).data('category');
$.ajax({
url:wp_ajax.ajax_url,
data: { action: 'filter', category: category },
type: 'post',
success: function(result) {
$('.js-filter').html(result);
},
error: function(result) {
console.warn(result);
}
});
});
});
})(jQuery);
This is html of box what is loaded (file content_pozice_box.php)
<a href="<?php echo get_permalink();?>"><div class="vypis_pozice">
<div class="projekt-wrapper">
<?php
$projekt = get_field('projekt');
if( get_field('projekt') == 'XXX' ) {
?>
<div class="logo-wrapper">
<img src="https://YYY.png" class="logo-wrapper-img">
</div><?php
}
if( get_field('projekt') == 'YYY' ) {
?>
<div class="logo-wrapper">
<img src="https://XXX.png" class="logo-wrapper-img">
</div>
<?php
}
?>
<div class="field_projekt"><h3><?php the_field('projekt');?></h3><div class="field_AAA">AAA:
<?php if ( get_field( 'AAA' ) ): ?>
<?php the_field('AAA');?>
<?php else: // field_name returned false ?>
dohodou
<?php endif; // end of if field_name logic ?>
</div></div>
</div>
<?php the_title('<h3>', '</h3>'); ?>
<div class="location-wrapper">
<div class="BBB"><img src="https://BBB.png"><?php the_field('BBB');?></div>
<div class="CCC"><img src="https://CCC.png"><?php the_field('CCC');?></div>
</div>
<div class="DDD"><?php $cat = get_the_category(); echo $cat[0]->cat_name; ?></div><div class="job-button">Otevřít</div>
</div></a>
PHP (loading JS, Ajax, function)
function load_scripts() {
wp_enqueue_script('ajax', get_stylesheet_directory_uri() . '/' . 'template-parts/' .'filters.js', array('jquery'), NULL, true);
wp_localize_script('ajax' , 'wp_ajax',
array('ajax_url' => admin_url('admin-ajax.php'))
);
}
add_action( 'wp_enqueue_scripts', 'load_scripts');
add_action( 'wp_ajax_nopriv_filter', 'filter_ajax' );
add_action( 'wp_ajax_filter', 'filter_ajax' );
function filter_ajax() {
$category = $_POST['category'];
$args = array(
'post_type' => 'pozice',
'posts_per_page' => -1
);
if(isset($category)) {
$args['category__in'] = array($category);
}
$query = new WP_Query($args);
if($query->have_posts()) :
while($query->have_posts()) : $query->the_post();
include("content_pozice_box.php");
endwhile;
endif;
wp_reset_postdata();
die();
}
This won't solve all your problems but the first thing you should do is reduce your database calls. get_field('projekt') is called 4 times, which runs for every iteration of your loop. Oddly, you've already set it to a variable:
$projekt = get_field('projekt');
But you're not using the variable anywhere. So try replacing that first, so that it only runs once per iteration:
if ( $projekt ) {...}
While you're at it you should always escape output for security's sake. I.E. Instead of <h3><?php the_field('projekt');?></h3> replace with <h3><?php echo esc_html( $projekt ); ?></h3>.
To find other sources of inefficiencies you might try the Query Monitor plugin, as well as your browser's dev tools. I'm not sure about your JS. It looks fine to me but perhaps someone else here will notice something.

AJAX Interfering with if statement in while loop?

I am trying to load my sidebars in my while loop by using if statements that call them after a certain number of posts. It's important to note that I am using AJAX code (provided below) to load in posts on scroll and I believe it may be causing the issue.
Though they are sidebars, they are not physically a sidebar but rather content loaded between posts.
I've tried for a week to locate the problem but I cannot seem to get the sidebars to load with AJAX as a if statement in the while loop.
Important to note: The sidebar will load after the number of posts if it's not loaded through AJAX. So if it's in the initial load, the sidebars load. But when you continue to scroll to say the third or fourth bar it will not load and the AJAX will only load the (parts/content).
I need to either be able to resolve the if statement so it works within the while loop that loads through AJAX or I'm open to an alternate solution as long as it doesn't remove the AJAX.
A lot of work has been put into making this loop work and help is greatly appreciated!
front-page.php
<?php
$current_page = max( 1, get_query_var( 'paged' ) );
$the_query = new WP_Query( array(
'cat' => '-21',
'post_type' => 'post',
'posts_per_page' => 5,
'paged' => $current_page,
'tax_query' => array(
array(
'taxonomy' => 'topics',
'operator' => 'NOT EXISTS',
'field' => 'term_id',
'terms' => $term_id
)
)
) );
wp_localize_script( 'my_loadmore', 'misha_loadmore_params', array(
'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ),
'posts' => json_encode( $the_query->query_vars ),
'current_page' => $current_page,
'max_page' => $the_query->max_num_pages
) );
?>
<div id="main" class="container-fluid">
<?php if ($the_query->have_posts()) : ?>
<?php $count = 0; ?>
<?php while ($the_query->have_posts()) : $the_query->the_post(); get_template_part( 'parts/content', get_post_format() ); ?> <!-- This parts/content loads -->
<?php $count++; ?>
<!-- the dynamic_sidebar does not load -->
<?php if ($count == 2 && is_active_sidebar('sidebar1') ) : ?>
<div class="side-container first-side">
<?php dynamic_sidebar('sidebar1'); ?>
</div>
<?php endif; ?>
<?php if ($count == 10 && is_active_sidebar('sidebar2') ) : ?>
<div class="side-container first-side">
<?php dynamic_sidebar('sidebar2'); ?>
</div>
<?php endif; ?>
<?php if ($count == 20 && is_active_sidebar('sidebar3') ) : ?>
<div class="side-container third-side">
<?php dynamic_sidebar('sidebar3'); ?>
</div>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
<?php get_footer(); ?>
</div><!-- END CONTAINER -->
parts/content -- this loads as expected including code if it's helpful
<div class="row post"> <!-- Post is mentioned in the below JS to load -->
<div class="col-sm-5">
<h2>Text</h2>
</div>
<div class="col-sm-7">
<h3>text</h3>
</div>
</div><!-- END ROW-->
sidebar code - works when initially loaded but doesn't when AJAX calls on this code such as the last two sidebars in front-page.php
<?php
$term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); ?>
<?php while( $flexible_posts->have_posts() ) : $flexible_posts->the_post(); global $post; ?>
<div class="sidebar-area">
//sidebar code here
}
endwhile;
?>
myloadmore.js - AJAX Call
jQuery(function($){
var canBeLoaded = true,
bottomOffset = 2000;
$(window).scroll(function(){
if ( misha_loadmore_params.current_page >= misha_loadmore_params.max_page ) {
return;
}
var data = {
'action': 'loadmore',
'query': misha_loadmore_params.posts,
'page' : misha_loadmore_params.current_page
};
if( $(document).scrollTop() > ( $(document).height() - bottomOffset ) && canBeLoaded == true ){
$.ajax({
url : misha_loadmore_params.ajaxurl,
data: data,
type: 'POST',
beforeSend: function( xhr ){
// AJAX call is in process, we shouldn't run it again until complete
canBeLoaded = false;
},
success:function(data){
if( data ) {
$('#main').find('div.post:last-of-type').after( data ); // where to insert posts
canBeLoaded = true; // the ajax is completed, now we can run it again
misha_loadmore_params.current_page++;
bottomOffset = ( $( '#main > div.post:last' ).offset() || {} ).top
}
}
});
}
});
});
functions.php - Added for further context
function misha_my_load_more_scripts() {
wp_register_script( 'my_loadmore', get_stylesheet_directory_uri() . '/js/myloadmore.js',
array( 'jquery' ), '', true );
wp_enqueue_script( 'my_loadmore' );
}
add_action( 'wp_enqueue_scripts', 'misha_my_load_more_scripts' );
function misha_loadmore_ajax_handler() {
$args = json_decode( wp_unslash( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1; // load the next page
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
get_template_part( 'parts/content', get_post_format() );
endwhile;
endif;
wp_die();
}
add_action( 'wp_ajax_loadmore', 'misha_loadmore_ajax_handler' ); // Authenticated users
add_action( 'wp_ajax_nopriv_loadmore', 'misha_loadmore_ajax_handler' ); // Non-authenticated users
The trick here was to add the if statements inside of the AJAX handlers as well. Perhaps someone with AJAX experience can add to this one day to explain why it works, but all I know is that it does. All the code from my question is the same below is the difference from the functions.php ajax handler function.
function misha_loadmore_ajax_handler() {
$args = json_decode( wp_unslash( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1; // load the next page
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
get_template_part( 'parts/content', get_post_format() );
<?php if ($count == 2 && is_active_sidebar('sidebar1') ) : ?>
<div class="side-container first-side">
<?php dynamic_sidebar('sidebar1'); ?>
</div>
<?php endif; ?>
<?php if ($count == 10 && is_active_sidebar('sidebar2') ) : ?>
<div class="side-container first-side">
<?php dynamic_sidebar('sidebar2'); ?>
</div>
<?php endif; ?>
<?php if ($count == 20 && is_active_sidebar('sidebar3') ) : ?>
<div class="side-container third-side">
<?php dynamic_sidebar('sidebar3'); ?>
</div>
<?php endif;
endwhile;
endif;
wp_die();
}

AJAX handler throws 400 (Bad request) - why?

I am trying to apply a "Load more posts" function to a post loop, but I am dealing with a 400 Bad request, when admin-ajax.php is referred to.
The reference I used is this - https://rudrastyh.com/wordpress/load-more-posts-ajax.html
Following function (in functions.php) is passing query parameters to javascript:
function wordpress_my_load_more_scripts()
{
global $wp_query;
wp_enqueue_script('jquery');
wp_register_script( 'my_loadmore', get_stylesheet_directory_uri() . '/myloadmore.js', array('jquery') );
wp_localize_script( 'my_loadmore', 'wordpress_loadmore_params', array(
'ajaxurl' => admin_url() . 'admin-ajax.php',
'posts' => json_encode( $wp_query->query_vars ),
'current_page' => get_query_var( 'paged' ) ? get_query_var('paged') : 1,
'max_page' => $wp_query->max_num_pages
) );
wp_enqueue_script( 'my_loadmore' );
}
add_action( 'wp_enqueue_scripts', 'wordpress_my_load_more_scripts' );
Parameters are passed to following jQuery script named "myloadmore.js":
jQuery(function($){
$('.wordpress_loadmore').click(function()
{
var button = $(this),
data = {
'action': 'loadmore',
'query': wordpress_loadmore_params.posts,
'page' : wordpress_loadmore_params.current_page
};
console.log(wordpress_loadmore_params.ajaxurl);
$.ajax({
url : wordpress_loadmore_params.ajaxurl, // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr )
{
button.text('Loading...');
},
success : function( data ){
if( data ) {
button.text( 'More posts' ).prev().before(data);
wordpress_loadmore_params.current_page++;
if ( wordpress_loadmore_params.current_page == wordpress_loadmore_params.max_page )
button.remove(); // if last page, remove the button
} else {
button.remove(); // if no data, remove the button as well
}
}
});
});
});
Following function inside functions.php is expected to provide three more posts inside while loop:
function wordpress_loadmore_ajax_handler()
{
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1;
$args['post_status'] = 'publish';
query_posts( $args );
if(have_posts() ) :
echo "We have post(s)!";
while( have_posts() ): the_post();
echo "A post!";
endwhile;
endif;
die;
}
add_action('wp_ajax_loadmore', 'wordpress_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmore', 'wordpress_loadmore_ajax_handler');
The post loop is this:
<ul class="products columns-3">
<?php
$query_params = array(
'post_type' => 'post',
'posts_per_page' => 3
);
$wp_query = new WP_Query( $query_params);
if( $wp_query->have_posts() ) :
while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
<li class="product post-item">
<span class="post-image">
<a href="<?php the_permalink(); ?>">
<?php
if ( has_post_thumbnail())
{
the_post_thumbnail();
}
?>
</a>
</span>
<h2 class="post-title"><?php the_title(); ?></h2>
<span class="post-category"><?php the_category(', ');?></span>
</li>
<?php endwhile; ?>
<?php endif; ?>
</ul>
<nav>
<?php
global $wp_query; // you can remove this line if everything works for you
// don't display the button if there are not enough posts
if ( $wp_query->max_num_pages > 1 )
echo '
<div class="wordpress_wrapper">
<div class="wordpress_loadmore">More posts</div>
</div>'; // you can use <a> as well
?>
</nav>
<?php wp_reset_postdata(); ?>
Clicking the button to load more posts results in following message:
https://www.uvjagtpro.dk/wp-admin/admin-ajax.php
jquery.js?ver=1.12.4:4 POST https://www.uvjagtpro.dk/wp-admin/admin-ajax.php 400 ()
send # jquery.js?ver=1.12.4:4
ajax # jquery.js?ver=1.12.4:4
(anonymous) # myloadmore.js:13
dispatch # jquery.js?ver=1.12.4:3
r.handle # jquery.js?ver=1.12.4:3
Why can't I parse variable in Array named "wordpress_loadmore_params.ajaxurl" without it causing a 400 bad request?
Link to page is here - https://www.uvjagtpro.dk/arkiv/
There are only 3 cases where WordPress will return a 400 on an AJAX request to
.../wp-admin/admin-ajax.php
$_REQUEST['action'] variable is empty
has_action( 'wp_ajax_' . $_REQUEST['action'] ) is false
has_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] ) is false
So, you should verify that your code
add_action('wp_ajax_loadmore', 'wordpress_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmore', 'wordpress_loadmore_ajax_handler');
is really executed and the query does contain a $_REQUEST['action'] with contents 'loadmore'. This is easiest to do if you know how to use a PHP debugger otherwise I would use error_log() to display relevant messages after the add_action statements. You can also display the value of the has_action() functions.
Your code looks correct to me so I think the error is not the code itself but maybe its location.

slick slider not working on dynamically generated li

After not finding a solution for this:
Wordpress doesn't execute jquery code correctly
I have decided to change to slick slider hoping it woul work but seems it's impossible to create a proper slider with wordpress and jquery for dynamic content.
What I'm doing: getting all the custom posts in php and rendering it as an array then called to be rendered in my google map. I then try to render a list on the side of all locations.
More Info: I do not get console errors.
Problem: Slick classes get applied to the ul but dont apply to the li
How slick renders:
functions.php:
add_shortcode('render-map', 'renderMap');
function renderMap(){
wp_enqueue_style( 'slick_css', get_template_directory_uri() . '/css/slick.css');
wp_enqueue_style( 'slick_style', get_template_directory_uri() . '/css/slick-theme.css');
wp_enqueue_style( 'mapStyle', get_template_directory_uri() . '/css/mapStyle.css');
wp_register_script( 'googleMap', 'https://maps.googleapis.com/maps/api/js?key=mykey&callback=initMap', false, false, false );
wp_enqueue_script( 'googleMap' );
wp_enqueue_script( 'slick_js', get_template_directory_uri() . '/js/slick.min.js');
wp_enqueue_script( 'markerClusterer', get_template_directory_uri() . '/js/markerClusterer.js');
wp_enqueue_script( 'mapRenderer', get_template_directory_uri() . '/js/mapRenderer.js', array(), false, true );
echo '<div class="interactiveMap"><div class="rowMap">';
echo '<div id="map-canvas"></div>';
echo '<div class="sidebarLocation">
<div class="recentArticles">
<div class="recentArticlesHeader">
<i class="fas fa-chevron-up"></i>
</div>
<ul id="sidebarLocation" class="recentArticlesGroup sidebarLocationUl">';
global $post;
$args = array(
'post_type' => 'map-location',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$map_locations = get_posts( $args );
$myResult = renderLocation($map_locations);
echo '</ul>
<div class="recentArticlesFooter">
<i class="fas fa-chevron-down"></i>
</div>
</div>
</div>';
echo '</div></div>';
echo "<script type='text/javascript'>";
echo '$( document ).ready(function() {';
$js_array = json_encode($myResult);
echo "var javascript_array = ". $js_array . ";\n";
echo 'gmaps_results_initialize(javascript_array);});';
echo "</script>";
wp_enqueue_script( 'slick_call', get_template_directory_uri() . '/js/slick-call.js', array( 'jquery' ), false, false );
}
slick-call.js
jQuery(document).ready(function($){
$('#sidebarLocation').slick({
arrows: true,
vertical: true,
slide: 'li',
slidesToShow:3,
slidesToScroll:1,
});
});
After writing many console.log I noticed that even I was calling slick on
jQuery(document).ready
it was executing before everything finished loading. Thus I have wrapped it in a function and added a delay ans it works fine:
jQuery(document).ready(function($){
function start_slick(){
$('#sidebarLocation').slick({
arrows: true,
vertical: true,
slide: 'li',
slidesToShow:3,
slidesToScroll:1,
prevArrow: $('.ca_goUp'),
nextArrow: $('.ca_goDown'),
infinite:false,
});
}
window.setTimeout( start_slick, 2000 );
});

WP get_post_thumbnail with Backstretch JS

I am using a javascript that's called 'Backstretch' to display an image on the back of my website that resizes when the viewport is getting bigger or smaller. Now I would like to combine it with the get_post_thumbnail function from WordPress so I can set a background image as featured image.
I tried the standard WP function but that doesn't work because it adds tags:
$.backstretch("<?php echo get_the_post_thumbnail( $post_id, $size, $attr ); ?>");
So I need to strip off those tags.. I'm getting close because i'm now getting an url (and image) but it's always the same one even though I set a different featured image on every page
<?php $url = wp_get_attachment_url( get_post_thumbnail_id($post_id, $size, $attr ) ); ?>
<script>$.backstretch("<?php echo $url; ?>");</script>
You get the answer to your question in this tutorial: http://sridharkatakam.com/set-featured-image-full-sized-background-posts-pages-wordpress/
Create a backstretch-set.js-file and include
jQuery(document).ready(function($) {
$("body").backstretch([BackStretchImg.src],{duration:3000,fade:750});
});
and then enqueue both js-files (backstretch.js and your backstretch-set.js) in your functions.php
//* Enqueue Backstretch script
add_action( 'wp_enqueue_scripts', 'enqueue_backstretch' );
function enqueue_backstretch() {
//* Load scripts only on single Posts, static Pages and other single pages and only if featured image is present
if ( is_singular() && has_post_thumbnail() )
wp_enqueue_script( 'backstretch', get_bloginfo( 'stylesheet_directory' ) . '/js/jquery.backstretch.min.js', array( 'jquery' ), '1.0.0' );
wp_enqueue_script( 'backstretch-set', get_bloginfo('stylesheet_directory').'/js/backstretch-set.js' , array( 'jquery', 'backstretch' ), '1.0.0' );
wp_localize_script( 'backstretch-set', 'BackStretchImg', array( 'src' => wp_get_attachment_url( get_post_thumbnail_id() ) ) );
Try using the global $post object like so:
<?php global $post; $url = wp_get_attachment_url( get_post_thumbnail_id($post->ID, 'full' ) ); ?>
<script>$.backstretch("<?php echo $url; ?>");</script>

Categories

Resources