Hi @mihail-chepovskiy
The issue here is that the Smush Lazy Load injects this “.no-lazyload” class after your shortcode has already been processed.
Shortcodes are processed by the “do_shortcode()” as a default filter on ‘the_content’ with a priority of 11. This is how WordPress core does it.
Smush also uses filter on “the_content” to inject the “no-lazyload” class but it’s doing it way later – with priority of 100.
So the moment it does it, your $content variable content is already json_encoded.
Theoretically, you could change priority for Smush filter (example code below) but this will make it applied before your shortcode is processed, resulting in your $content variable content having most likely either no “no-lazyload” class applied at all or having “lazyload” class added anyway. So still not escaped.
However, the “hybrid” approach seems to be working here:
1. use this code to make Smush filter callback executed earlier (before shortcodes are processed by WordPress):
add_action( 'init', function(){
global $wp_filter;
$tag = 'the_content';
$hook_method = 'exclude_from_lazy_loading';
$hook_class = 'Smush\Core\Modules\Lazy';
$new_priority = 9;
if ( ! isset( $wp_filter[$tag] ) ) {
return;
}
foreach ( $wp_filter[$tag]->callbacks as $key => $callback_array ) {
foreach ( $callback_array as $c_key => $callback ) {
if ( substr_compare( $c_key, $hook_method, strlen( $c_key )-strlen( $hook_method ), strlen( $hook_method ) ) === 0 ) {
if ( $callback['function'][0] instanceof $hook_class ){
$original_callback = $wp_filter[$tag]->callbacks[$key];
unset( $wp_filter[$tag]->callbacks[$key][$c_key] );
$wp_filter[$tag]->callbacks[ $new_priority ] = $original_callback;
}
}
}
}
}, 11 );
2. and then manually add .no-lazyload class in your shortcode code:
$content = '<img src="https://image.jpg" class="no-lazyload>';
Note please: this is custom development so that’s as far as we can go with it. I tested it on my end and it seems to do the trick as expected.
Best regards,
Adam