I'm currently developing a plugin for wordpress.
My plugin-content gets fired on defined shortcode. I pass a parameter to the shortcode to make some conditionals. I am able to load JS conditionally, but I also need to load CSS conditionally.
Lets say I use the shortcode: [myshortcode css="dark"]
I make a database query and inject the wanted css.
Is this somehow possible?
I have read some threads about it. I know it is because the Code fires after head is loaded. I wasn't able to find a solution.
What options do I have?
Thank you!
Probably you are searching for these functions:
has_shortcode()
get_shortcode_regex() - here you can find nice example, which is close to your request
You can check your post, page or custom post type on hook by add_action ( 'wp', 'yourCustomFunction' ) and test if your get_post_field ( 'post_content' ) contains specified shortcode and conditionally enqueue CSS file based on specified attribute.
There is a better way. You can simply register your css and scripts with wp_enqueue_scripts by wp_register_style or wp_register_script and then enqueue the registered scripts from your shortcode. You will have opportunity to enqueue scripts based on certain condition there.
Here is a code example.
/**
* Register scripts
*/
function my_plugin_scripts() {
wp_register_style( 'dark-css', $css_path );
wp_register_script( 'script-name', $js_path, array(), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'my_plugin_scripts' );
/**
* My Shortcode
*/
function my_plugin_shortcode( $atts ) {
$atts = shortcode_atts( array(
'css' => 'default'
), $atts );
if ( $atts['css'] == 'dark') {
wp_enqueue_style('dark-css')
}
// do shortcode actions here
}
add_shortcode( 'shortcode-id','my_plugin_shortcode' );
If I understand your question correctly, you could do something like this to load one stylesheet or the other:
function aw_shortcode_function($atts) {
$a = shortcode_atts( array(
'css' => 'light', // this is the default value
), $atts );
$colorTheme = $a['css'];
if ($colorTheme == 'dark') {
// load/enqueue/get/do whatever based on the css="dark" shortcode attribute
}
}
Related
In previous when I develop WP shortcode then I load the CSS style depend on the shortcode params like this.
function test_shortcode( $atts ) {
$a = shortcode_atts( array(
'foo' => 'something',
), $atts );
echo "<style>";
.shortcode_unique_id {
//some css property depend on shortcode
}
echo "</style>";
}
But now it did not allow to add any style tag in the body otherwise it will show w3 validation error. We need to load style in the head tag.
Please anyone tell me how to load CSS style depend on shortcode params when calling the shortcode.
Advance Thanks
You can use wp_register_style and wp_enqueue_style to use style which is dependent on shortcode.
Main difference between wp_enqueue_* and respective wp_register_* functions, is that the first adds scripts/styles to the queue, the second prepares scripts/styles to be added.
The typical scenario of using both functions is when you want to register scripts/styles on theme init, and then enqueue them wherever necessary e.g.
add_action('init', 'my_register_styles');
function my_register_styles() {
wp_register_style( 'style1', get_template_directory_uri() . '/style1.css' );
wp_register_style( 'style2', get_template_directory_uri() . '/style2.css' );
wp_register_style( 'style3', get_template_directory_uri() . '/style3.css' );
}
/*This is you shortcode function*/
function test_shortcode( $atts ) {
$a = shortcode_atts( array(
'foo' => 'something',
), $atts );
wp_enqueue_style( 'style1' );
wp_enqueue_style( 'style2' );
wp_enqueue_style( 'style3' );
}
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',*/
},
}
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.
}
Within a wp plugin, I see the following code on the php file of the plugin.
public function register_plugin_scripts() {
/*** Styles ***/
$cyclone_css = add_query_arg(array('cyclone_templates_css' => 1), home_url( '/' ));
wp_register_style( 'cyclone-slider-plugin-styles', $cyclone_css );//contains our combined css from ALL templates
wp_enqueue_style( 'cyclone-slider-plugin-styles' );
/*** Scripts ***/
wp_register_script( 'cycle', $this->plugin_url.'js/jquery.cycle.all.min.js', array('jquery') );
wp_enqueue_script( 'cycle' );
}
Now, I want to alter some of it. Right now, this plugin is used at every single page. Implying both the 1) combined css 2) jquery.cycle.all.min.js is requested each page. However, I only use this plugin for the main page. So how do I fix it, making the css file + js to only be loaded for the main page, nothing else.
Next, I do not want to combine css from all templates. Instead, it should be pinpointed to a selected location. How to do that?. Thanks in advance. Plugin is Cyclone Slider 2.
If you were happy to edit the plugin code directly, it would be a simple matter of making the wp_enqueue_script() calls conditional on being on the home page.
public function register_plugin_scripts() {
/*** Styles ***/
$cyclone_css = add_query_arg(array('cyclone_templates_css' => 1), home_url( '/' ));
wp_register_style( 'cyclone-slider-plugin-styles', $cyclone_css );//contains our combined css from ALL templates
/*** Scripts ***/
wp_register_script( 'cycle', $this->plugin_url.'js/jquery.cycle.all.min.js', array('jquery') );
if (is_front_page()){
wp_enqueue_style( 'cyclone-slider-plugin-styles' );
wp_enqueue_script( 'cycle' );
}
}
However, you almost certainly don't want to edit the plugin, because your changes will get overwritten when the plugin is updated.
I would therefore use wp_dequeue_script and wp_dequeue_style to get stop the scripts loading where you don't want them to.
Per Wordpress Function reference, you could add this code in your theme function.php file or similar:
/**
* Dequeue a queued script.
*
* Hooked to the wp_print_scripts action, with a late priority (100),
* so that it is after the script was enqueued.
*/
function wpcyclone_dequeue_script() {
wp_dequeue_script( 'cycle' );
wp_dequeue_script( 'cyclone-slider-plugin-styles' );
}
if (!is_front_page()){
add_action( 'wp_print_scripts', 'wpcyclone_dequeue_script', 100 );
}
I am embedding my Jplayer code into my website however there is already jquery within the wordpress installation but when I copy my code across the player is broken as it shows no the volume icon with the x over it. When I include an external jquery script it breaks the entrie site but the player works. Is there any better way for me to include jPlayer into my wordpress site?
The jPlayer script enqueueing has to play by WordPress rules. The easiest (and maybe only) way is with a Shortcode. There are lot of developers, mainly Theme developers, that ignore that we don't dequeue the bundled jQuery version and load any version from some CDN (at least, we don't do it without knowing exactly what we're doing).
Here's a rough test, the shortcode callback function has to be polished a lot.
public function plugin_setup() // hooked into plugins_loaded
{
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) );
add_shortcode( 'jplayer', array( $this, 'shortcode' ) );
}
public function enqueue()
{
wp_register_script(
'sj-jplayer',
$this->plugin_url . 'js/jquery.jplayer.min.js',
array( 'jquery' ), // <------- Dependencies
false,
true
);
wp_register_style( 'sj-skin', $this->plugin_url . 'skin/blue.monday/jplayer.blue.monday.css' );
wp_enqueue_script( 'sj-jplayer' );
wp_enqueue_style( 'sj-skin' );
}
public function shortcode( $atts, $content )
{
ob_start();
require_once('html-shortcode.php');
$var = ob_get_clean();
return $var;
}
The file html-shortcode is basically this demo code adapted like:
<?php
/*
* Prints the shortcode
*/
?>
<script type="text/javascript">
jQuery(document).ready(function($) // <------ WP noConflict
{
$("#jquery_jplayer_1").jPlayer({});
});
</script>
<div id="jquery_jplayer_1" class="jp-jplayer"></div>
I tested this jPlayer shortcode inside another that does a jScrollPane, and it worked on the iPad.