get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), // 'caption' => $attachment->post_excerpt, // 'description' => $attachment->post_content, // 'href' => get_permalink( $attachment->ID ), // 'src' => $attachment->guid, // 'title' => $attachment->post_title $img_post = get_post( $item['img'] ); if ( is_int( $item['img'] ) ) { $img_post = get_post( $item['img'] ); if ( !is_wp_error( $img_post ) && is_object( $img_post ) && 'attachment' === $img_post->post_type ) { switch( $requested_img_attr ) { case 'caption' : $img_attr = $img_post->post_excerpt; break; case 'description' : $img_attr = $img_post->post_content; break; case 'title' : $img_attr = $img_post->post_title; break; } } } return $img_attr; } } if ( !function_exists( 'Nimble\sek_slider_parse_template_tags') ) { // fired @filter 'nimble_parse_template_tags' function sek_slider_parse_template_tags( $val, $item = array() ) { //the pattern could also be '!\{\{(\w+)\}\}!', but adding \s? allows us to allow spaces around the term inside curly braces //see https://stackoverflow.com/questions/959017/php-regex-templating-find-all-occurrences-of-var#comment71815465_959026 return is_string( $val ) ? preg_replace_callback( '!\{\{\s?(\w+)\s?\}\}!', function( $matches ) use( $item ) { return sek_slider_find_pattern_match( $matches, $item ); }, $val) : $val; } } if ( !function_exists('Nimble\sek_maybe_parse_slider_img_html_for_lazyload') ) { // @return html string function sek_maybe_parse_slider_img_html_for_lazyload( $attachment_id, $is_first_img, $lazy_load_on, $size = 'thumbnail' ) { // Skip when : // - is customizing // - slider lazy loading is not active // - global Nimble lazy load is active, and this is the first image ( in this case we want to lazy load the first image of the slider if offscreen ) if ( skp_is_customizing() || !$lazy_load_on || ( sek_is_img_smartload_enabled() && $is_first_img ) ) { // Nov 2020 : removes any additional styles added by a theme ( Twenty Twenty one ) or a plugin to the image add_filter( 'wp_get_attachment_image_attributes', '\Nimble\sek_remove_image_style_attr', 999 ); $img_html = wp_get_attachment_image( $attachment_id, $size ); remove_filter( 'wp_get_attachment_image_attributes', '\Nimble\sek_remove_image_style_attr', 999 ); return $img_html; } // If lazy loaded, preprocess the image like wp_get_attachment_image() // added in dec 2019 for https://github.com/presscustomizr/nimble-builder/issues/570 $html = ''; $image = wp_get_attachment_image_src( $attachment_id, $size, $icon = false ); if ( $image ) { list($src, $width, $height) = $image; $hwstring = image_hwstring( $width, $height ); $size_class = $size; if ( is_array( $size_class ) ) { $size_class = join( 'x', $size_class ); } $attachment = get_post( $attachment_id ); $default_attr = array( 'src' => $src, 'class' => "attachment-$size_class size-$size_class swiper-lazy",// add swiper class for lazyloading @see https://swiperjs.com/api/#lazy 'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ), ); $attr = $default_attr; // Generate 'srcset' and 'sizes' if not already present. if ( empty( $attr['srcset'] ) ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); if ( is_array( $image_meta ) ) { $size_array = array( absint( $width ), absint( $height ) ); $srcset = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id ); $sizes = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id ); if ( $srcset && ( $sizes || !empty( $attr['sizes'] ) ) ) { $attr['srcset'] = $srcset; if ( empty( $attr['sizes'] ) ) { $attr['sizes'] = $sizes; } } } } /** * Filters the list of attachment image attributes. * * @since 2.8.0 * * @param array $attr Attributes for the image markup. * @param WP_Post $attachment Image attachment post. * @param string|array $size Requested size. Image size or array of width and height values * (in that order). Default 'thumbnail'. */ // Nov 2020 : removes any additional styles added by a theme ( Twenty Twenty one ) or a plugin to the image add_filter( 'wp_get_attachment_image_attributes', '\Nimble\sek_remove_image_style_attr', 999 ); $attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment, $size ); remove_filter( 'wp_get_attachment_image_attributes', '\Nimble\sek_remove_image_style_attr', 999 ); // add swiper data-* stuffs for lazyloading now, after all filters // @see https://swiperjs.com/api/#lazy if ( !empty( $attr['srcset'] ) ) { $attr['data-srcset'] = $attr['srcset']; unset( $attr['srcset'] ); } // april 22 : deactivated when implementing late escape for #885 because it breaks data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 // No idea how to escape this without breaking it for now // if ( !empty( $attr['src'] ) ) { // $attr['data-src'] = $attr['src']; // $attr['src'] = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; // //unset( $attr['src'] ); // } if ( !empty( $attr['sizes'] ) ) { $attr['data-sek-img-sizes'] = $attr['sizes']; unset( $attr['sizes'] ); } $attr = array_map( 'esc_attr', $attr ); $html = rtrim( " $value ) { $html .= " $name=" . '"' . $value . '"'; } $html .= ' />'; } return $html; } } if ( !function_exists( 'Nimble\sek_get_img_slider_module_img_html') ) { function sek_get_img_slider_module_img_html( $item, $lazy_load_on, $index ) { $html = ''; $is_first_img = 0 == $index; if ( is_int( $item['img'] ) ) { // don't parse the first image of the carousel for lazyloading // @see https://github.com/presscustomizr/nimble-builder/issues/596 ( Lazy load break layout of first slide ) // if ( $lazy_load_on && !$is_first_img ) { // $html = sek_maybe_parse_slider_img_html_for_lazyload( // $item['img'], // empty( $item['img-size'] ) ? 'large' : $item['img-size'], // $is_first_img//<= // when lazy load is active, we want to lazy load the first image of the slider if offscreen by adding 'data-sek-src' attribute // ); // $html .= '
';//this element is removed by swiper.js once the image is loaded @see https://swiperjs.com/api/#lazy // } else { // $html = wp_get_attachment_image( $item['img'], empty( $item['img-size'] ) ? 'large' : $item['img-size']); // } $html = sek_maybe_parse_slider_img_html_for_lazyload( $item['img'], $is_first_img,//<= // when lazy load is active, we want to lazy load the first image of the slider if offscreen by adding 'data-sek-src' attribute $lazy_load_on, empty( $item['img-size'] ) ? 'large' : $item['img-size'] ); if ( $lazy_load_on && !$is_first_img ) { $html .= '
';//this element is removed by swiper.js once the image is loaded @see https://swiperjs.com/api/#lazy } } else if ( !empty( $item['img'] ) && is_string( $item['img'] ) ) { // the default img is excluded from the Nimble Builder smart loading parsing @see nimble_regex_callback() // => this is needed because this image has no specific dimensions set. And therefore can create false javascript computations of other element's distance to top on page load. // in particular when calculting if is_visible() to decide if we smart load. $html = sprintf( 'default img', esc_url( $item['img'] ) ); } return $html; } } if ( !function_exists( 'Nimble\sek_print_img_slider' ) ) { function sek_print_img_slider( $img_collection, $slider_options, $model ) { $img_collection = is_array( $img_collection ) ? $img_collection : array(); $is_multislide = count( $img_collection ) > 1; $autoplay = ( !skp_is_customizing() && true === sek_booleanize_checkbox_val( $slider_options['autoplay'] ) ) ? "true" : "false"; // don't authorize value < 300 ms $autoplay_delay = intval( $slider_options['autoplay_delay'] ) < 300 ? 1000 : intval( $slider_options['autoplay_delay'] ); $pause_on_hover = true === sek_booleanize_checkbox_val( $slider_options['pause_on_hover'] ) ? "true" : "false"; $loop_on = true === sek_booleanize_checkbox_val( $slider_options['infinite_loop'] ) ? "true" : "false"; $lazy_load_on = true === sek_booleanize_checkbox_val( $slider_options['lazy_load'] ) ? "true" : "false"; $nav_type = ( is_string( $slider_options['nav_type'] ) && !empty( $slider_options['nav_type'] ) ) ? esc_attr($slider_options['nav_type']) : 'arrows_dots'; $hide_nav_on_mobiles = true === sek_booleanize_checkbox_val( $slider_options['hide_nav_on_mobiles'] ); ?> ', esc_attr($model['id']), esc_attr($autoplay), esc_attr($autoplay_delay), esc_attr($pause_on_hover), esc_attr($loop_on), esc_attr($slider_options['image-layout']), esc_attr($nav_type), $is_multislide ? 'true' : 'false', $hide_nav_on_mobiles ? 'true' : 'false', esc_attr($lazy_load_on), wp_kses_post(apply_filters('nb_slider_wrapper_custom_attributes', '', $slider_options, $model )) ); ?> 0 ) : ?>
$item ) { $is_text_enabled = true === sek_booleanize_checkbox_val( $item['enable_text'] ); $text_content = $is_text_enabled ? $item['text_content'] : ''; $has_text_content = !empty( $text_content ); // Feb 2021 : now saved as a json to fix emojis issues // see fix for https://github.com/presscustomizr/nimble-builder/issues/544 // to ensure retrocompatibility with data previously not saved as json, we need to perform a json validity check $text_content = sek_maybe_decode_richtext( $text_content ); $text_content = sek_strip_script_tags( $text_content ); $text_html = sprintf('
%1$s
', $text_content ); if ( !skp_is_customizing() ) { $text_html = !$has_text_content ? '' : $text_html; } $has_overlay = true === sek_booleanize_checkbox_val( $item['apply-overlay'] ); // Put them together $to_render = sprintf( '
%3$s
', sek_slider_parse_template_tags( strip_tags( esc_attr( $item['title_attr'] ) ), $item ), sek_get_img_slider_module_img_html( $item, "true" === $lazy_load_on, $index ), sek_slider_parse_template_tags( $text_html, $item ), esc_attr($item['id']), true === sek_booleanize_checkbox_val( $has_overlay ) ? 'true' : 'false', esc_attr( apply_filters('nb_single_slide_custom_attributes', '', $item, $model ) ) ); echo skp_is_customizing() ? wp_kses_post($to_render) : apply_filters( 'nimble_parse_for_smart_load', wp_kses_post($to_render) ); }//foreach ?>
'; } ?> model; $value = array_key_exists( 'value', $model ) ? $model['value'] : array(); $img_collection = !empty($value['img_collection']) ? $value['img_collection'] : array(); $slider_options = !empty($value['slider_options']) ? $value['slider_options'] : array(); if ( !empty( $img_collection ) ) { sek_print_img_slider( $img_collection, $slider_options, $model ); sek_emit_js_event('nb-needs-swiper'); } else { if ( skp_is_customizing() ) { printf( '

%1$s

', __('Click to start adding images.', 'text_doma'), 'background: url(' . esc_url(NIMBLE_MODULE_ICON_PATH) . 'Nimble_slideshow_icon.svg) no-repeat 50% 75%;background-size: 200px;' ); } }