Skip Navigation

[Resolved] Nested shortcodes not processing correctly

This support ticket is created 8 years ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Our next available supporter will start replying to tickets in about 1.14 hours from now. Thank you for your understanding.

Sun Mon Tue Wed Thu Fri Sat
- 8:00 – 17:00 8:00 – 17:00 8:00 – 17:00 8:00 – 17:00 8:00 – 17:00 -
- - - - - - -

Supporter timezone: America/Sao_Paulo (GMT-03:00)

This topic contains 24 replies, has 3 voices.

Last updated by Adriano 8 years ago.

Assisted by: Adriano.

Author
Posts
#376794

Ben

I spent much of the afternoon reconfiguring the slider view to use the new wpv-conditional syntax, but with no effect. Bummer.

But I did run into some solid observations. The shortcode will run anywhere other than in an atypical element attribute. So for example in a view loop as follows:

<!-- Will run -->
[srcset size='slider-banner'][wpv-post-featured-src size='slider-banner'][/srcset]

[wpv-conditional if="( NOT(empty($(_thumbnail_id))) ) AND ( $(wpcf-customimage) ne '1' )"]
        <!-- Will run -->  
          [srcset size='slider-banner'][wpv-post-featured-src size='slider-banner'][/srcset]

	<!-- Will NOT run (srcset attribute) -->
	<img src="[wpv-post-featured-src size='slider-banner']" srcset="[srcset size='slider-banner'][wpv-post-featured-src size='slider-banner'][/srcset]" class="featured-slider-image" title="[wpv-post-title]" alt="[wpv-post-title]" />

        <!-- Will run (img attribute - but obviously broken) -->
	<img src="[srcset size='slider-banner'][wpv-post-featured-src size='slider-banner'][/srcset]" class="featured-slider-image" title="[wpv-post-title]" alt="[wpv-post-title]" />

        <!-- Will NOT run (data-custom) -->
	<img src="[wpv-post-featured-src size='slider-banner']" class="featured-slider-image" title="[wpv-post-title]" alt="[wpv-post-title]" data-custom="[srcset size='slider-banner'][wpv-post-featured-src size='slider-banner'][/srcset]"  />
						
[/wpv-conditional]

So this is a breaking change that's been introduced - Where can I follow alerts to these kinds of important changes?

Not only is it breaking but the unsanitized shortcode attribute is making its way to the browser, this breaks Safari 6.2.8 at least.

The RICG team has been working on an implementation of responsive images for WP, literally for more then a year, and now that it's been rolled into core (with much fanfare (https://wordpress.org/news/2015/12/clifford/)) , the srcset attribute should be added to View's whitelist of internal attributes that shortcodes are alowed to run within.

Infact, srcset, sizes, and data-* area all valid HTML5 attributes that need to be white listed –– and sooner the better for me.

I hadn't noticed this regression before as I was working on other areas of this project, but it means rolling back features I literally spent a month on, just as I am trying to go live with this project.

#377293

Well, this change was done on WordPress core, please open the link above and read the HTML section:
https://codex.wordpress.org/Shortcode_API

It's a bit tricky now to render shortcodes inside of HTML attributes, not everything is allowed anymore.

"Full usage of HTML in shortcode attributes was never officially supported, and this will not be expanded in future versions. Starting with version 4.2.3, similar limitations were placed on use of shortcodes inside HTML".

#377924

Ben

Adriano --- I think I see the full impact here. It looks like I'll have to roll my own shortcode which outputs the full image tag with attributes.

This represents a number of chalanges:

1) correct me if I'm wrong but I believe it's not possible to pass shortcodes as attributes to a shortcode?

2) I believe the task would be a lot simpler if types/views had an option to pass back the image post ID instead of the image url. Right now I do a reverse lookup using the image url, but there are times when this doesn't work so well. Knowing the image ID would be far superior.

Perhaps that last one is more of a feature request?

#378041

1. Accordingly the documentation you are right:
"The shortcode parser does not accept square brackets within attributes. Thus the following will fail:"
[tag attribute="[Some value]"]

2. Maybe we do have something here already. Do you need to attachment post ID?

#378073

Ben

Adriano
Yes attachment post ID would be the one.
B

#378126

I'm sorry but unfortunately we don't have a shortcode to get the attachment ID, you will need to create your own shortcode using this: https://codex.wordpress.org/Function_Reference/get_post_thumbnail_id

#378158

Ben

Adriano,

That's what I understood too. However I don't believe there's a toolset shortcode which returns the current post ID either, (from within the views loop) and this is the missing piece required by get_post_thumbnail_id( $post_id). It's because of this that I have had to resort to a reverse lookup of the image url provided from views- which, I've found to be slow and unreliable.

Best,
Ben

#378339

Ben
#378415

Ben

Adriano,

So I've crafted a work arround. One thing I noted is that wpv-post-id returns a string rather than an integer, which is what get_post_thumbnail_id, get_post_status etc. require. My own use case is a bit more complicated and it would be useful if the shortcode for Types image fields could return the attachment post id as an option, but below is a greatly simplified version for anyone who might find it useful.

<?php

add_shortcode( 'srcset', 'views378339_fetch_image_with_srcset' );

/**
 * Output a post's featured image element with responsive image attributes (srcset and sizes)
 * Requires WP 4.4 and or the RICG Responsive Images Plugin
 *
 * @param $atts
 * @param $atts['size']     // the named thumbnail size
 * @param $atts['class']    // any css classes to be added to the image element
 *
 * @param null $content     // The parent post id [wpv-post-id]
 *
 * @use [srcset size='slider-banner' class='featured-slider-image'][wpv-post-id][/srcset]
 * 
 * @return string
 *
 * @author orionrush
 */
function views378339_fetch_image_with_srcset( $atts, $content = null ) {

	$a = shortcode_atts( array(
		'size'  => 'thumbnail',
		'class' => ''
	), $atts );

	// Set up some vars
	$thumbnail_name = ( esc_attr( $a['size'] ) );
	$fallback       = ( esc_url_raw( $a['fallback'] ) );
	$postID_str     = trim( do_shortcode( $content ) ); // [wpv-post-id] produces a string
	$postID         = (int) $postID_str; // cast it to an int
	$error          = '';

	// Do we have a valid published post?
	if ( false === get_post_status( $postID ) ) {
		$error = 'post-id-' . $postID_str . '-is-not-valid';
	} else {
		// We've received a valid post

		// Get the post's featured image attachment id
		$thumb_id = get_post_thumbnail_id( $postID );

		if ( ! $thumb_id ) {
			$error .= ' we-could-not-find-a-featured-image-for-post-' . $postID_str;
		} else {

			// Image attributes
			$img       = wp_get_attachment_image_src( $thumb_id, $thumbnail_name ); // array
			$img_w     = $img[1];
			$img_h     = $img[2];
			$img_title = $alt_text = esc_attr( get_the_title( $postID ) ); // title of post
			$img_alt   = esc_attr( trim( strip_tags( get_post_meta( $thumb_id, '_wp_attachment_image_alt', true ) ) ) );

			if ( ! $img_alt ) {
				$img_alt = esc_attr( get_the_title( $postID ) ); // use the title of post instead
			}

			// Get the srcset of the named thumbnail
			if ( function_exists( 'wp_get_attachment_image_srcset' ) ) {
				$srcset = esc_attr( wp_get_attachment_image_srcset( $thumb_id, $thumbnail_name ) );
				$sizes  = esc_attr( wp_get_attachment_image_sizes( $thumb_id, $thumbnail_name ) );
			}
			if ( ! $srcset ) {
				// we wont force error output because we still have everything but the srcset
				$atts = array(
					'data-error' => 'srcset-could-not-be-constructed-for-' . $thumb_id,
					'class'      => $class,
					'title'      => $img_title,
					'alt'        => $img_alt,
					'width'      => $img_w,
					'height'     => $img_h
				);
			} else {
				$atts = array(
					'srcset' => $srcset,
					'sizes'  => $sizes,
					'class'  => $class,
					'title'  => $img_title,
					'alt'    => $img_alt,
					'width'  => $img_w,
					'height' => $img_h
				);
			}
		}
	}
	if ( $error ) {
		// we could do anything here, but just output a comment for now
		return '<!-- Errors generating image: ' . $error . '-->';
	} else {
		return wp_get_attachment_image( $thumb_id, $thumbnail_name, false, $atts );
	}
}
#378619

Really nice workaround, thanks for sharing.

This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.