Skip Navigation

[Resolved] custom shortcode is causing not valid JSON response error

This support ticket is created 4 years, 10 months 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.

Sun Mon Tue Wed Thu Fri Sat
- 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 -
- 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 -

Supporter timezone: Europe/London (GMT+00:00)

This topic contains 7 replies, has 2 voices.

Last updated by martinE-4 4 years, 9 months ago.

Assisted by: Nigel.

Author
Posts
#1485951

After writing this ticket I think I have two separate issues:
1. I can't get the same block in the block editor to render an embedded media field with either an image or a video - ie. I can get it to work only with one or the other
2. my shortcode throws an error in the back-end when I try to update the block editor - but the front-end looks fine no error.

If it is true that I need this shortcode because of a 'bug' with embedded field display please help!

Background:
The reason I developed this shortcode in the first place to test on my Types embedded media field is that although a youtube VIDEO presents just fine with (in a shortcode block)- this code only renders a linked url to an IMAGE:

[types field='common_featured_media'][/types]

I cannot get my IMAGES in the embedded media field to display unless using an html block: (I'm using the block editor)- but of course this code will not render a VIDEO:

<img src="[types field='common_featured_media' output='raw'][/types]">

So I therefore went down the road of designing a shortcode to test for a '.jpg' in the embedded media field to allow me to present different code depending on the field content. (since my embedded media custom field contains url's to both video and images - in around 1000 posts!)

However even though my shortcode appears to work, this outputs the URL only, not the image:

[wpv-conditional if="( '[testforimage]' eq '1' )" debug="true"]<img src="[wpv-post-field name="wpcf-common_featured_media"]" > [/wpv-conditional]

This also just outputs the URL:

[wpv-conditional if="( '[testforimage]' eq '1' )" debug="true"]<img src="[types field='common_featured_media' output='raw'][/types]">[/wpv-conditional]

Without the conditional the code does accurately render the image...very inconsistent.

I receive this error if the shortcode [testforimage] is included in any block (even though the front-end appears fine with no errors):

"Updating failed. Error message: The response is not a valid JSON response."

when I use the following custom shortcode I wrote:

/**
 * Tests if url is an image
 *
 * @var	string $text  The value of my custom field to be tested (in this case =common_featured_media).
 * @return	True=url is image, or False=url is not image (does not contain jpg, jpeg, png, gif)
 *
 * @author M.Elliott
 */

function test_url_for_image( ) {
 
$text = types_render_field( "common_featured_media", array("output" => "raw") );

if ( strpos( $text , 'jpg') == false ) {
	$answer = '0';
	 return $answer;
	}
	$answer = '1';
	return $answer; 
}
add_shortcode('testforimage', 'test_url_for_image');

The shortcode works when I echo messages to at different logic points and it works when I use it in a wpv-conditional.

However, I cannot get my embedded image field (the one I am testing here, ie. common_featured_media) to render. Only the linked url is output?

I'm puzzled as to why it throws this error in the block editor but appears to work on the front end except the embedded image is not being displayed.

#1486487

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

Looking at your objective, it is to output an img tag in cases where an embedded field contains the URL of an image instead of video URL from a site such as youtube.

Where are the images hosted? On an external site, or on this site?

The embedded field simply uses WordPress's in-built embedded media handling, which has a white-list of external sources that are supported: https://wordpress.org/support/article/embeds/#okay-so-what-sites-can-i-embed-from

If your images were coming from a site such as imgur then they would be handled automatically.

Evidently they are not.

But in that case then the correct way to handle this situation is to register a handler for where the images are hosted, including if that is from your own site.

You can see details and an example in the official documentation:

https://codex.wordpress.org/Function_Reference/wp_embed_register_handler

You can register your own site, for example, and return the HTML of an img tag with the src the URL itself.

#1487595

Ok, here is my register code (from the oEmbed providers generator at hidden link ):

// Register oEmbed providers
function custom_oembed_icasc() {

	wp_oembed_add_provider( '<em><u>hidden link</u></em>', '<em><u>hidden link</u></em>', false );

}
add_action( 'init', 'custom_oembed_icasc' );

It's still not displaying an image, just the link with:
[types field='common_featured_media'][/types]

I must be having an error in the url to my images. Can you see it? I tried it with regex=true as well. Here is an example url of one of my self-hosted images (same website as the one I'm developing on):

hidden link

many thanks!

#1488345

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

Your website is likely not configured to be an oembed provider—to automatically return the required markup whenever a particular URL is reached—and that's not what I was directing you to do.

You need to register your own handler, where the URL refers to your own site, and you register a function that will spit out the markup you need, in this case an image tag.

It does require some familiarity with regular expressions.

You might want to browse the WordPress stackexchange site where others have been asking for help with that function (or ask a question yourself): https://wordpress.stackexchange.com/search?q=wp_embed_register_handler

#1488953

Ok, sorry I went down the wrong path. I'll try what you suggest. Thanks so much Nigel for pointing me in the right direction.

#1489081

I posted my question here:
https://wordpress.stackexchange.com/questions/357635/register-an-embed-handler-for-self-hosted-images
and I've only so far got a comment suggesting I go back to testing the URL to see if it is an image and put an img tag on it otherwise put an iframe on it. Sounds like my original approach here...

#1490731

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

OK, registering the embed handler is a valid option, but you could try registering the following shortcode instead:

add_shortcode('is-local', function ($atts = [], $content = null) {

    if ( !is_null($content) ){

        $site_url = get_bloginfo( 'url' );
        $content = do_shortcode( $content );

        $is_local = strpos( $content, $site_url );
    }

    return ( $is_local === 0 ) ? 1 : 0;
});

I'm working on the same principle, i.e. checking that the URL corresponds to the current site URL (is local) rather than is some external URL (e.g. youtube).

You use it like so:

Local: [is-local][types field='embeds' output='raw'][/types][/is-local]

It will return 1 for local files (your local images, whether they are jpg, png etc.) and 0 for external files, which you can then use in wpv-conditional shortcodes.

#1491303

Shortcode works perfectly. I found I had to omit the closing [/types] though. Actually can't seem to include that anywhere in the short code blocks I use in the block editor. It doesn't seem to parse. But works perfectly without it? Bit weird but I'm moving on... Thanks so much for this.

My issue is resolved now. Thank you!