Reputation: 476
So here's what I'm doing:
I have a post which contains only a shortcode with an embedded video:
[video width="1280" height="720" mp4="http://myurl/wp-content/uploads/2016/01/VID_20160114_202806.mp4"][/video]
All I want is that "mp4" variable, except it might have a different name depending on the encoding so let's say that I only need the [2]
value.
Remember, the above shortcode is all there is inside the post. Here's what i do:
$atts = array();
$atts = shortcode_parse_atts( $post->post_content );
//then I use $atts[2];
this fails miserably.
I get the following notice: Undefined offset: 2
If I run a print_r
, this is the twisted array I get:
Array
(
[0] => [video
[width] => 1280
[height] => 720
[1] => mp4=" http:="" myurl="" wp-content="" uploads="" 2016="" 01="" vid_20160114_202806.mp4"][="" video]
(admittedly, this is made worse by the fact that it was printed within an html tag, which accounts for all those quotes; point is, the extraction of arguments fails)
I figure $post->post_content
is NOT what shortcode_parse_atts
wants. It wants a string of attributes. But then, how do I get the string of attributes? (I know, regex, right?)
Upvotes: 0
Views: 1027
Reputation: 471
Late, but for someone else trying to solve this...
I created my own version of shortcode_parse_atts
like so:
function eri_shortcode_parse_atts( $shortcode ) {
// Store the shortcode attributes in an array heree
$attributes = [];
if (preg_match_all('/\w+\=\".*?\"/', $shortcode, $key_value_pairs)) {
// Now split up the key value pairs
foreach($key_value_pairs[0] as $kvp) {
$kvp = str_replace('"', '', $kvp);
$pair = explode('=', $kvp);
$attributes[$pair[0]] = $pair[1];
}
}
// Return the array
return $attributes;
}
Returns: Array ( [width] => 1280 [height] => 720 [mp4] => http://myurl/wp-content/uploads/2016/01/VID_20160114_202806.mp4 )
Then I created the following function to search the page for all shortcodes and return them in an array:
function eri_get_shortcode_on_page( $post_id, $shortcode ) {
// Get the post content once
$content = get_the_content( null, false, $post_id );
// $content = apply_filters( 'the_content', get_the_content( null, false, $post_id ) ); // Alternative if get_the_content() doesn't work for whatever reason
// Double check that there is content
if ($content) {
// Shortcode regex
$shortcode_regex = '/\['.$shortcode.'\s.*?]/';
// Get all the shortcodes from the page
if (preg_match_all($shortcode_regex, $content, $shortcodes)){
// Store them here
$final_array = [];
// Extract the attributes from the shortcode
foreach ($shortcodes[0] as $s) {
$attributes = eri_shortcode_parse_atts( $s );
// The return the post
$final_array[] = $attributes;
}
// Return the array
$results = $final_array;
// Otherwise return an empty array if none are found
} else {
$results = [];
}
// Return it
return $results;
} else {
return false;
}
}
Upvotes: 2
Reputation: 30
I think you should first use the shortcode regex to match the shortcode from the post content, then use function shortcode_parse_atts()
to parse the attributes in each shortcode string.
Also, note that the correct way to call this function is to pass the string of the shortcode's arguments into the function, not the entire shortcode string.
Take this shortcode as an example.
[video width="1280" height="720" mp4="http://myurl/wp-content/uploads/2016/01/VID_20160114_202806.mp4"][/video]
You should:
shortcode_parse_atts( 'width="1280" height="720" mp4="http://myurl/wp-content/uploads/2016/01/VID_20160114_202806.mp4"' );
instead of
shortcode_parse_atts( '[video width="1280" height="720" mp4="http://myurl/wp-content/uploads/2016/01/VID_20160114_202806.mp4"][/video]' );
Back to your question, I think you can refer to this code snippet:
$shortcode_pattern = get_shortcode_regex( ['video'] );
if ( preg_match_all( '/' . $shortcode_pattern . '/s', $post->post_content, $m ) ) {
// $m[3] – The shortcode argument list
foreach( $m[3] as $atts_string ) {
$atts = shortcode_parse_atts( $atts_string );
}
}
Ref:
Upvotes: 0
Reputation: 476
Thanks Ohgodwhy, I realize that's the way to go. However it creates a problem because the third value could have a different name depending on the encoding of the video.
However I solved with regex (I didn't want to... because lazy...)
if (preg_match('%\[video \w+="\w+" \w+="\w+" \w+="(.*)"\]\[/video\]%', $post->post_content)) {
preg_match_all('%\[video \w+="\w+" \w+="\w+" \w+="(.*)"\]\[/video\]%', $post->post_content, $result);
// now I can use $result[1][0] to get the video url; (I figured [1][0] by trial and error so don't ask why)
Upvotes: 1
Reputation: 50787
This is how the shortcode should be setup:
function my_shortcode($atts){
$atts = shortcode_parse_atts(array(
//default values go here.
), $atts);
}
Now you should correctly receive the values as you intend and can access them with $atts['width']
, $atts['height']
, $atts['mp4']
.
Upvotes: 2