wordpress shortcode that embeds iframe executes only once per page - wordpress

I have the following wordpress shortcode
function wiki_show( $atts ) {
// Attributes
$atts = shortcode_atts(
array(
'name' => '',
'height' => '500',
),
$atts,
'wiki'
);
// Return custom embed code
return '<div><iframe src="https://en.wikipedia.org/wiki/' . '&name=' . $atts['name'] . '" height="' . $atts['height'] . '"/></div> ';
}
add_shortcode( 'wiki', 'wiki_show' );
I use it within a wordpress page like so:
AAAAAAAA
[wiki name="Wolfenstein_3D" height="500"]
BBBBBBB
[wiki name="Nelson_Mandela" height="800"]
CCCCCCCC
The problem is that after the first iframe, no content is displayed (not even the BBBB.... that is after the first iframe)
If I change the shortcode code to tag some "foo" instead of "iframe" it shows all the code correctly.
If I embed the 2 iframes manually (without the shortcode) it works fine.
How do I make the shortcode work? What am I doing wrong?
(*credit: this code was adapted from: https://generatewp.com/shortcodes/?clone=video-embed-shortcode)

The <iframe> element isn't a self closing element. You should change it to
return '<div><iframe […]></iframe></div>';
Also check out HTML validators, it would have catched this issue. ;-)

Related

Override the gallery shortcode (WordPress) if has a given parameter

I want to "override" the default "gallery" shortcode (WordPress), but only if I have used a given parameter to that gallery shortcode.
For example:
[gallery ids="1,2,3"]
It has no parameter, so it will output the standard gallery code.
[gallery mode="custom" ids="1,2,3"]
It has my "mode" parameter, so it will output another shortcode.
To achieve it, I have created a "gallery" shortcode in functions.php file:
function get_new_gallery( $atts ) {
extract( shortcode_atts( array(
'mode' => '',
'ids' => '',
), $atts ) );
$code ="";
if ($mode == "custom") {
//* Output custom shortcode
$code = '[custom_gallery ids="' . $ids . '"]';
} else {
//* Need to do nothing...but don't know how to do it
$code = '[gallery ids="' . $ids . '"]'; /* Here's the problem, it causes a loop */
}
return do_shortcode($code);
}
add_shortcode( 'gallery', 'get_new_gallery' );
It works fine when I use the mode="custom" parameter. It just output the new shortcode: [custom_gallery...]
However, when not using the parameter it breaks because it enters in an infinite loop. In the code, there's a comment with the line that breaks it.
What I want is to execute the standard "gallery" shortcode if no parameter is entered. But given I've overwritten it...don't know how to "scape" from the loop and just execute the gallery.
Any help?
Thanks in advance.
Maybe an alternative approach can help? What about a filter on the gallery shortcode. See references:
https://codex.wordpress.org/Plugin_API/Filter_Reference/post_gallery
and:
https://wpbeaches.com/filtering-gallery-image-output-wordpress/

Remove Wordpress Native Audio Player Skin [duplicate]

I frequently use the Wordpress audio shortcode to embed my podcast episodes in my posts:
[audio src="http://podcastsourcefile"]
Unfortunately, the default audio player looks terrible. I would like to have it restyled with CSS. I have a mockup I can send to show you what it should look like, but here's the basic gist:
background color: #B27D47
replace play button image (I can provide the .png file)
make the player 75 pixels tall, 100% width
round the corners of the player
Here's what I would like the player to look like:
(I have the .png file of the play button.)
Consider this:
// Deactivate default MediaElement.js styles by WordPress
function remove_mediaelement_styles() {
if( is_home() ) {
wp_dequeue_style('wp-mediaelement');
wp_deregister_style('wp-mediaelement');
}
}
add_action( 'wp_print_styles', 'remove_mediaelement_styles' );
// Add own custom CSS file to reskin the audio player
function add_audio_player_styles () {
if( is_home() ) {
wp_enqueue_style('mini-audio-player', get_stylesheet_directory_uri() . '/assets/mediaelement/mediaelementplayer.css', array(), null );
}
}
add_action( 'wp_enqueue_scripts', 'add_audio_player_styles');
This way, you can now copy the whole mediaelement folder out of wp-include, enqueue your copy instead of the original and then fiddle with the .css there. The lines marked with //optional show how you can use different styles depending on the page your visitor is in. Found it here
There are two filter hooks to deal with this. One at the beginning, with very few info, with it we shortcut the whole shortcode and return our own custom HTML code:
add_filter( 'wp_audio_shortcode_override', 'short1_so_23875654', 10, 4 );
function short1_so_23875654( $return = '', $attr, $content, $instances )
{
# If $return is not an empty array, the shorcode function will stop here printing OUR HTML
// $return = '<html code here>';
return $return;
};
The parameters that arrive are:
Array
(
[0] => ''
[1] => Array
(
[src] => http://example.com/wp-content/uploads/file.mp3
)
[2] => ''
[3] => 1
)
And the other one that runs at the end of the shortcode function:
add_filter( 'wp_audio_shortcode', 'short2_so_23875654', 10, 5 );
function short2_so_23875654( $html, $atts, $audio, $post_id, $library )
{
return $html;
}
The parameters that arrive are:
Array
(
[0] => <audio class="wp-audio-shortcode" id="audio-715-1" preload="none" style="width: 100%" controls="controls"><source type="audio/mpeg" src="http://example.com/wp-content/uploads/file.mp3?_=1" />http://plugins.dev/wp-content/uploads/2013/10/04_discipline_64kb.mp3</audio>
[1] => Array
(
[class] => wp-audio-shortcode
[id] => audio-715-1
[preload] => none
[style] => width: 100%
)
[2] =>
[3] => 715
[4] => mediaelement
)
I just did it by styling my custom.css in the theme editor.
The values of the audio shortcode are the following. In my case, I changed it so it won't be affected by any Wordpress update (even if it's dirtier than the PHP solution on the other comment). You could use the developper tools and style the player your own way (my problem was that i didn't need a 100% width player).
:
.mejs-mute,
.mejs-duration-container,
.mejs-time,
.mejs-duration-container,
... {...}
I added my stylesheet additionally to the existing one, like I explained in this post:
function enqueue_mediaelement(){
wp_enqueue_style( 'wp-mediaelement' );
//enqueue '/wp-content/my-theme/audio-player-styles.css'
wp_enqueue_style('my-audio-player', get_stylesheet_directory_uri() . '/audio-player-styles.css', array(), null );
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );
For example if you want to color the players background, you could add now the following to audio-player-styles.css:
.mejs-container, .mejs-container .mejs-controls, .mejs-embed, .mejs-embed body {
background-color: #B27D47;
}

Use Wordpress shortcode function to render Gutenberg block, sending the attributes as parameters

I have a shortcode that generates a gallery, given the gallery ID.
function rb_scroll_gallery_shortcode( $atts, $content ) {
$a = shortcode_atts( array(
'id' => -1,
), $atts );
$gallery_ID = $a['id'];
$output = '';
if($gallery_ID != -1){
ob_start();
$gallery = new RB_Scroll_Gallery($gallery_ID);
$gallery->render();
$output = ob_get_clean();
}
return $output;
}
add_shortcode( 'rb_scroll_gallery', 'rb_scroll_gallery_shortcode' );
Now, I've made a Gutenberg block that works perfectly in the editor. You can select a gallery and it will save. However, I dont want to repeat code and have the html in the save property and in the php code.
So I was wondering if there is a way to use that same rb_scroll_gallery_shortcode function to render the block in the front end.
I've seen that you can use register_block_type and set the render_callback to rb_scroll_gallery_shortcode, but I need the ID selected in the block to send it to the function in the $atts array
//This uses the shortcode funtion, but doesn't gives the gallery ID
register_block_type( 'cgb/block-rb-scroll-gallery-block', array(
'render_callback' => 'rb_scroll_gallery_shortcode',
) );
You can try to Convert a Shortcode to a Gutenberg Block and after use in your theme,
Registering the Dynamic Block Callback in PHP
/**
* Register the GitHub Gist shortcode
*/
function gggb_init() {
add_shortcode( 'github-gist', 'gggb_render_shortcode' );
register_block_type( 'github-gist-gutenberg-block/github-gist', array(
'render_callback' => 'gggb_render_shortcode',
) );
}
add_action( 'init', 'gggb_init' );
When your block is rendered on the frontend, it will be processed by your render callback:
function gggb_render_shortcode( $atts ) {
if ( empty( $atts['url'] )
|| 'gist.github.com' !== parse_url( $atts['url'], PHP_URL_HOST ) ) {
return '';
}
return sprintf(
'<script src="%s"></script>',
esc_url( rtrim( $atts['url'], '/' ) . '.js' )
);
}
**Note:** this render callback is intentionally different than the Gutenberg block’s edit callback. Our preference is to use GitHub’s provided JavaScript embed code because this lets GitHub change the embed’s behavior at a future date without requiring a developer to make changes.
Refer link for get more information, https://pantheon.io/blog/how-convert-shortcode-gutenberg-block
I've found out the little thing that messed up my code. The problem wasn't that the render_callback() wasn't getting any attributes (though it wasn't), but it was that the editor wasn't saving them because I forgot to remove some testing data from the attribute galleryID
In the registerBlockType:
The save() method should return null.
The attribute should not have a selector data, since it is used to find the value on the markup return by the save(), wich in this case returns null. I've forgot to remove this data, thats why the attribute wasn't being saved.
attributes: {
galleryID: {
type: 'string',
//This data should only be set if the value can be found in the markup return by save().
//Since save() returns null, we let it out
/*source: 'attribute',
/*attribute: 'data-gallery-id',
/*selector: '.rb-scroll-gallery-holder',*/
},
}

Insert a Plugin Setting Value as Shortcode Attribute

I wrote a plugin.
One of the plugin's settings is a URL/page.
I want my client to be able to continue to use the theme's page builder, to create any buttons that will link to the URL that is entered in the plugin's settings.
The client could enter the URL manually for every button they create, but this would be tedious, and will become a massive pain should the URL in the plugin's settings change.
So, I want to be able to use the plugin's URL setting value as the URL attribute of a third-party button shortcode.
Is this possible? Something like:
[button url="{get the plugin's URL setting}"][/button]
Yes definitely possible.
You would need to add the shortcode functionality to your plugin. Best to use a unique name to avoid conflicts (not 'button').
in your plugin php file add the function and register it with the add_shortcode function like so:
function shortcodeName_function( $atts ) {
// add attribute handling and get the 'url' parameter
$output = '<button a href="'. $url . '" class="button">';
return $output;
}
add_shortcode( 'shortcodeName', 'shortcodeName_function');
Now u can use now a short code with this name, when the plugin is activated.
[shortcodeName]
See the link of the wordpress documentation for more info on parameter handling: wordpress shortcode api
EDIT: ah sorry, I think I missed the point a bit. What you could do is - store the plugin url setting in a cookie and check for the cookie value in the short code.
When shortcode have not attribute url you can provide default settings url in shortcode return output.
Like this
add_shortcode( 'button', 'shortcode_function_button');
function shortcode_function_button( $atts ){
$attr = shortcode_atts( array(
'url' => get_option( 'button_default_url' ) , // get your setting default url if shortcode have not
), $atts ); // attr url="http://example.com" then it use default
// setting url
return 'Button';
}
If already build shortcode in plugin or theme then find shortcode callback function and change atts in this way.
If probleming in find third party shortcode callback name check in your plugin file all registered shortcodes with callback.
global $shortcode_tags;
print_r( $shortcode_tags );
// show all shortcodes with callback
/*Array
(
[embed] => __return_false
[wp_caption] => img_caption_shortcode
[caption] => img_caption_shortcode
[gallery] => gallery_shortcode
[playlist] => wp_playlist_shortcode
[audio] => wp_audio_shortcode
[video] => wp_video_shortcode
[button] => button_shortcode
)*/
If do you not want to any change in thired party shortcode and manage in your plugin
Remove shortcode previously declared thired party plugin and add in your plugin top of file.
remove_shortcode('button'); // https://developer.wordpress.org/reference/functions/remove_shortcode/
Recreate same shortcode tag after remove but use own callback name and work same as thired party shortcode like this
add_shortcode( 'button', 'your_own_callback' );
function your_own_callback( $atts, $content ){
$attr = shortcode_atts( array(
'url' => get_option( 'button_default_url' ) , // Use same atts thired party using atts
), $atts );
return button_shortcode( $attr, $content); // Use thired party callback function name.
}

How to add a button or box below Post Title?

I'm writing a Wordpress plug-in that will add a button (or any HTML element) below the post title (or above if below is not possible). How can I do that?
You want to use the filter responsable for printing titles. I'm not sure exactly which one it is, but here's the function (it's likely single_post_title as demonstrated):
add_filter( 'single_post_title', 'the_post_title', 10, 2 );
function my_more_link( $post_title ) {
$button_code = "your_button_HTML_here";
return str_replace( $post_title, $post_title . $button_code );
}

Resources