There is a way to enqueue a script only if a widget is used (pay attention, not if is active, but if it is present inside a sidebar in a page/post)? Or even better: there is a way to enqueue a script only if a particular string appears inside a sidebar?
Just enqueue the script or stylesheet in the widget function. This is the easiest and best approach.
public function widget( $args, $instance ) {
// outputs the content of the widget
// Enqueue a script needed for
// the Widget's output
wp_enqueue_script( 'your_script', $path, $deps );
// Rest of widget output goes here...
}
I haven't actually tested, this but one possible solution would be to enqueue your script to the footer.
If widget is used
When you build the widget, you can add some code to the widget() function of your widget's class (the function at actually outputs the widget to the screen). You could call wp_enqueue_script() from here, just make sure you flag it to be used in the footer.
This will print your script where wp_footer() is called rather than where wp_head() is called, but only if the widget is invoked on the page.
If a string appears in the sidebar
Basically, just filter the sidebar for your string. If the string is present, enqueue your script to the footer the same way you would with a widget.
(Update) Alternatives
There are two other things you can do. First, you can use jQuery to namespace your functionality. Basically, give your widget a unique ID (say "my-unique-id"), then download your script asynchrounously:
jQuery(document).ready(function() {
if( jQuery('#my-unique-id').length > 0 ) {
jQuery.getScript( [your-script-url] );
}
}
This code will check to see if your widget ID is on the page ... if so, it downloads your script from the server, if not, it does nothing. You can also build this code in PHP to include either a relative or absolute reference to your script file. It's up to you.
Alternatively, you could just include your script in an inline <script> block in your widget's code. This will work the way you want it to, but it breaks all kinds of standard coding practices. Code should typically be in the <header> or placed directly before the closing </body> tag ... but you can really put it anywhere you want.
Yes.
I considered 'wp_footer' hook because this hook is executed at footer,and is probably the best way to add scripts only where the widget is used.
class Your_Widget extends WP_Widget{
function widget( $args, $instance ) {
add_action('wp_footer',array($this,'front_end_scripts'));
}
function front_end_scripts(){
?><script type="text/javascript">
console.log('this works!');
/*
Or if you need external scripts then you may use
$.getScript([your-script-url] );
*/
</script> <?php
}
}
Related
I have a plugin, it has many css theme files. Of course I do not want to load all of them, only one. It depends on config. For post I use has_shortcode function, but how todo the same thing with template that use do_shortcode function.
Note:
I found a good solution, I use
$this->loader->add_action( 'init', $plugin_public, 'register_scripts');
$this->loader->add_action( 'wp_footer', $plugin_public, 'print_scripts');
Inside shortcode handle I set a global var to true
global $imagelink_plugin_shortcode_used;
$imagelink_plugin_shortcode_used = true;
The function print_scripts add my scripts if my global var is true
public function print_scripts() {
global $imagelink_plugin_shortcode_used;
if ( ! $imagelink_plugin_shortcode_used )
return;
wp_print_scripts($this->plugin_name . '-imagelinks');
}
Thanks for answers.
Instead of using has_shortcode function, what you can do is register and enqueue those files when that shortcode is rendered.
First, register your css files with wp_register_script. Make sure to hook this into wp_enqueue_scripts
Now, inside your shortcode function, enqueue the files.
wp_enqueue_style('theme-css')
Using this way you can use the shortcode anywhere you want and the script is loaded only when shortcode is present on the page whether it is on content or template.
I want to add my JQuery script into single Wordpress page, but I dont know how. Example of script I'd like to inject:
<script type="text/javascript">
$(document).ready(function() {
$("html, body").animate({ scrollTop: $(window).height() }, 600);
return false;
});
</script>
This code works fine when injected in plain HTML, but how can I do the same for Wordpress?
Personally I feel the best way for adding a JavaScript to a particular page/post is to use ShortCode
Add this:
function add_my_script() {
return "<script>
//your jQuery here
</script>";
}
add_shortcode( 'myCustomShortCode', 'add_my_script' );
to your function.php file. Your function.php file is location at /wp-content/themes/<name of theme>/
NOTE: Use ' instead of " in your <script> to continue inside the return statement.
Now simply add the shortcode [myCustomShortCode] in your page.
you have a couple of options, the function you created above will add it to all pages (you were registering the script but not actually calling it, thats why its not working. see correction below).
If you want you can simply place the wp_enqueue_script() function below in your template (without add action and the custom() function
or directly write it into the template file (lots of arguments about whether this is acceptable coding practice, but it works)
or require_once / include_once the file in the correct sequence (you are using document.ready so you can do this anywhere below the header (if you already have jquery loaded in the header, if in the footer, must be below the footer) same rules apply for directly writing into the file.
function custom() {
wp_enqueue_script('jquery');
wp_enqueue_script('add-custom-js' , get_template_directory_uri() . '/js/custom.js' , array('jquery'),'',true );
}
add_action('wp_enqueue_scripts' . 'custom' );
also WP uses non conflict jquery so you need to use jQuery instead of the the shorthand vers $. there are a few alternative ways to use the shorthand if you google it.
just edit a page in wordpress, select text view (not formatted text) and paste your script wherever you like.
I'm developing a WordPress widget following Dave Clements tutorial. It works well. Now I want to add some styles to it. I want the styles to be in an extra css file which will be loaded during runtime. I'm calling this function
function myprefix_add_my_stylesheet() {
wp_register_style( 'myprefix-style', plugins_url('mystyle.css', __FILE__) );
wp_enqueue_style( 'myprefix-style' );
}
right before "// Widget output //" using this statement.
add_action( 'wp_enqueue_scripts', 'myprefix_add_my_stylesheet' );
But nothing seems to happen. What am I doing wrong?
Your wp_enqueue_scripts action do not work because you call it too late, in widget() function (widget output). It's too late because Wordpress already print/send head of page.
For example, you can add this action on widget construct function.
I'm looking for a solution to check is_active_widget on particular page.
I got this https://wordpress.stackexchange.com/questions/2302/loading-scripts-only-if-a-particular-shortcode-or-widget-is-present
However the second way of sorich87 still loads the the scripts of a widget on every page where there's no certain active widget on the running/active page. Even when the sidebar of each page has different id & name.
For example:
I have page 'A' (with sidebar 'A1') which consists 'X' active widget and x_scripts in it.
Then when I check on page 'B' (with sidebar 'B1') which doesnt consist 'X' widget, it still loads the x_scripts of 'X' widget. Seems that this is_active_widget function only check for general activated widget, not on the running page.
This is my code:
class X extends WP_Widget
{
function X(){
$widget_ops = array('description' => 'X widget');
$control_ops = array('width' => 200, 'height' => 500);
parent::WP_Widget(false,$name='X-widget',$widget_ops,$control_ops);
if ( is_active_widget(false, false, $this->id_base, true) ){
add_action('wp_head', 'x_styles',0);
add_action( 'wp_footer', 'x_scripts' );
}
}
//rest of functions here
}
How to prevent this?
Yes it does, is_active_widget() get the value from options saved on database. Therefore it will return true for any widgets that is active. The is_active_sidebar() behaves the same, even though the sidebar is not loaded in specific pages, the returned value will always be true as long as the sidebar is registered.
Both functions check the global $wp_registered_widgets, $_wp_sidebars_widgets, $sidebars_widgets which values are generated from register_sidebar() and widgets that has been added to the sidebar.
Unfortunately, there's no workaround for this. Since dynamic_sidebar() is loaded after wp_head(), it's impossible to hook a script or stylesheet conditionally to it. The script or styles or anything you hook to wp_head will always there even the sidebar is loaded or not, unless widget is inactive.
Maybe, logically, a different possibility is there for adding a script on wp_footer() for a widget, in this case, you can set a global variable or define a constant in your widget function. Therefore, the scripts will be loaded only if widget is active.
Well, there's my two cents
I think the easiest solution to this problem would be to simply edit the sidebar widgets themselves. Just use wp_enqueue_script() & wp_enqueue_style() in the plugin files and it'll load them only on the pages where the separate widgets are displayed.
Thanks to AriePutranto, who pushed me in the right direction. The same way you tell if there's an active widget in the widget($instance) function is how you decide whether to include your js/css files.
If you're fine with your includes being in the footer, then this works!
// Create the widget output.
public function widget($args, $instance)
{
if (! empty($instance)) {
add_action('wp_footer', array(&$this, 'enqueueWidgetIncludes'));
$this->printWidget();
}
}
private function enqueueWidgetIncludes() {
//css:
wp_enqueue_style(/*[code removed]*/);
wp_enqueue_script(/*[code removed]*/);
}
In Wordpress I have a page template called designers.php.
When loading, it reads the slug to get a uniqe ID, then calls the DB to retrieve designer information.
I want to use this information to alter the page title, using the designer name in the title tag.
I've tried using the add_filter in my designers.php file, but it's not working:
add_filter('wp_title', 'set_page_title');
function set_page_title($title) {
global $brand;
return 'Designer '.$brand['name'].' - '.get_bloginfo('name');
}
I'm, guessing the add_filter must either be located inside a plugin or in functions.php file.
How can I achieve what I'm trying to do?
UPDATE
The function is never fired as long as I use wp_title. If I change it to init (for testing), the function is fired.
So why does the add_filternor work for wp_title?
You are almost right. The filter must reside in function.php, and is called to modify the title. You can add the filter conditionally. Use this function is_page_template() to determine if wordpress is rendering your template
Try to modify your function like this:
add_filter('wp_title', 'set_page_title');
function set_page_title($title) {
global $brand;
if (is_page_template('designer.php'))
return 'Designer '.$brand['name'].' - '.get_bloginfo('name');
else
return $title;
}
First of all add_filter must either be located inside a plugin or in functions.php file.
Then, maybe you have to set the priority for the filter :
add_filter('wp_title', 'set_page_title',1);
function set_page_title() {
global $brand;
return 'Designer '.$brand['name'].' - '.get_bloginfo('name');
}
And check the <title> meta in your header.php theme.
<title><?php wp_title(); ?></title>