global post variable not working in wordpress plugin - php

I understand that the Wordpress global $post may not work until a certain point because it hasnt been loaded, but Im wondering is there a workaround for this.
Basically Im building a plugin specifically for a client. At the moment the variable is showing nothing.
This code is in a plugin in the plugins folder.
Im looking to make sure it only loads javascript (Ive left out that bit) when on specific pages (selected by the user), at the moment its loading on all pages.
My other option is to do it all on a php template, but to be honest I wanted to write it as a plugin with a view to customizing it for more generic use in the future, plus I have little experience with plugins so Im trying to improve that side of things also.
function include_js() {
global $post;
print_r($post);
if(is_object($post) && $post->ID == 14 ){
// do stuff
wp_enqueue_script('include-map', plugin_dir_url( __FILE__ ) . 'map.js');
}
}
add_action( 'init', 'include_js' );
EDIT: I realised my main issue is that I want to include the javascript and because of that I need wp_enqueue_script , but I can only seem to get that work if you use the init action, which happens before the loop.

After seeing your edit, try hooking to wp_enqueue_scripts instead of init. Like this:
function include_js() {
global $post;
print_r( $post );
if ( is_object( $post ) && $post->ID == 14 ) {
// do stuff
wp_enqueue_script( 'include-map', plugin_dir_url( __FILE__ ) . 'map.js' );
}
}
add_action( 'wp_enqueue_scripts', 'include_js' );
Ref: http://codex.wordpress.org/Plugin_API/Action_Reference/wp_enqueue_scripts

You should test $wp_query->queried_object_id instead of $post->id:
function include_js() {
global $wp_query;
if ( $wp_query->queried_object_id == 14 ) {
// do stuff
//...
}
}
add_action( 'wp_enqueue_scripts', 'include_js' );

There is no need for any globals etc. You can simply use is_single($post) to check if you are on a specific single post and then enqueue your script. You should always always use the wp_enqueue_scripts hook to hook your function to to enqueue scripts and styles
function include_js() {
if(is_single(14)) {
// do stuff
wp_enqueue_script('include-map', plugin_dir_url( __FILE__ ) . 'map.js');
}
}
add_action( 'wp_enqueue_scripts', 'include_js', 999 );
Remeber also, always add priority when adding custom scripts/styles. See add_action( $hook, $function_to_add, $priority, $accepted_args )

Related

Deregistering a script in Wordpress seems impossible

I tried everything. I even removed all content in functions.php and created a whole new file with just this:
function wpdocs_dequeue_script() {
if (is_singular()) {
wp_dequeue_script( 'gdrts-rating' );
}
}
add_action( 'wp_print_scripts', 'wpdocs_dequeue_script', 100 );
The idea is to remove some Javascript files from my custom post type. I thought I was doing something wrong so I first tried with is_page() and even is_home(), but even that is not working for me. It seems like the code is not fired or so.
This is my plugin:
wp_enqueue_script('gdrts-events', $this->file('js', 'events'), array(), gdrts_settings()->file_version(), false);
wp_enqueue_script('gdrts-rating', $this->file('js', 'rating'), $depend_js, gdrts_settings()->file_version(), true);
So, I also tried to do it like this:
function wpdocs_dequeue_script() {
wp_dequeue_script( 'gdrts-rating' );
}
add_action( 'wp_enqueue_scripts', 'wpdocs_dequeue_script', 100 );
Not working!

Disable Jetpack Carousel on specific pages in WordPress

I'm trying to disable Jetpack Carousel on a specific post ID using the following code in my functions.php
function djcoh_disable_carousel( $value ) {
wp_reset_query();
if ( is_page( 614 ) ) {
$value = true; // true to disable Carousel
}
// Return original or changed value
return $value;
}
add_filter( 'jp_carousel_maybe_disable', 'djcoh_disable_carousel' );
Here's the reference for jp_carousel_maybe_disable on GitHub
It seems that I'm unable to use is_page() within functions.php - though I thought I'd be able to by using wp_reset_query() as mentioned in the codex
What am I missing?!
The code you have is from a tutorial which is intended for running as a simple plugin. The reason your code doesn't currently work is because you are using it in the functions.php.
In it's current form your function is called as soon as it is read as part of the functions.php file. This is usually some time before the page is formed, and so you can't grab the page id with is_page{}.
Instead you should query the page and get it's id as follows:
function djcoh_disable_carousel( $value ) {
//get the global
global $post
echo "TEST PAGE ID: ".$post->ID;
//wp_reset_query();
if ( $post->ID == 614 ) {
$value = true; // true to disable Carousel
}
wp_reset_query();
// Return original or changed value
return $value;
}
add_filter( 'jp_carousel_maybe_disable', 'djcoh_disable_carousel' );
if that doesn't work try this:
function djcoh_disable_carousel( $value ) {
//get the global
global $wp_query;
$post_ID = $wp_query->post->ID;
echo "TEST PAGE ID: ". $post_ID;
//wp_reset_query();
if ( $post_ID == 614 ) {
$value = true; // true to disable Carousel
}
wp_reset_query();
// Return original or changed value
return $value;
}
add_filter( 'jp_carousel_maybe_disable', 'djcoh_disable_carousel' );
If none of the above work then your script is being called far too early in the process to grab the page id. So, the easiest option would be to simply place this script in it's own .php file and then upload that to the plugins root folder. Then activate it from the plugins menu.
The final option would be to create this as a filter or script and add the function call in the actual page template.
I managed this by using REQUEST_URI within a plugin file:
<?php
// No direct access
if ( ! defined( 'ABSPATH' ) ) exit;
if ( $_SERVER["REQUEST_URI"] === '/PAGE-SLUG/' ) {
add_filter( 'jp_carousel_maybe_disable', '__return_true' );
}
Change PAGE-SLUG for your slug and you are all set.
You can find info on REQUEST_URI in PHP's manuals:
'REQUEST_URI'
The URI which was given in order to access this page; for instance, '/index.html'.
It seems simplest to conditionally dequeue the Jetpack carousel script and stylesheet. The conditionals that you would typically use to control output would be available at the point in the request when the wp_footer action fires.
add_action( 'wp_footer', function() {
if ( is_page( $page ) ) {
wp_dequeue_script( 'jetpack-carousel' );
wp_dequeue_style( 'jetpack-carousel' );
}
}
Be certain to modify the is_page function to include the $page parameter or the condition will match all pages. Place the code in your theme's functions.php file and the Jetpack carousel should be disabled.

Wordpress dequeue scripts without handle?

I'm currently using Foobox lightbox (free) plugin, and apparently the plugins' files are loaded on every page regardless of whether it's used or not. However I would like to change this, but I can't seem to find any handles to dequeue the scripts through.
It seems that the scripts are called by the code beneath, which to me at least, doesn't show any handles. I've tried using remove_action(...) to "counter" them as well as various inputs in wp_dequeue_script() to try and target the files directly - e.g. wp_dequeue_script('foobox.free.min.js')
class Foobox_Free extends Foo_Plugin_Base_v2_1 {
const JS = 'foobox.free.min.js';
const CSS = 'foobox.free.min.css';
const CSS_NOIE7 = 'foobox.noie7.min.css';
const FOOBOX_URL = 'http://fooplugins.com/plugins/foobox/?utm_source=fooboxfreeplugin&utm_medium=fooboxfreeprolink&utm_campaign=foobox_free_pro_tab';
const BECOME_AFFILIATE_URL = 'http://fooplugins.com/affiliate-program/';
private static $instance;
public static function get_instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Foobox_Free ) ) {
self::$instance = new Foobox_Free();
}
return self::$instance;
}
/**
* Initialize the plugin by setting localization, filters, and administration functions.
*/
private function __construct() {
//init FooPluginBase
$this->init( FOOBOXFREE_FILE, FOOBOXFREE_SLUG, FOOBOX_BASE_VERSION, 'FooBox FREE' );
if (is_admin()) {
add_action('admin_head', array($this, 'admin_inline_content'));
add_action('foobox-free-settings_custom_type_render', array($this, 'custom_admin_settings_render'));
new FooBox_Free_Settings();
add_action( FOOBOX_ACTION_ADMIN_MENU_RENDER_GETTING_STARTED, array( $this, 'render_page_getting_started' ) );
add_action( FOOBOX_ACTION_ADMIN_MENU_RENDER_SETTINGS, array( $this, 'render_page_settings' ) );
add_action( 'admin_notices', array( $this, 'admin_notice_foogallery_lightboxes' ) );
add_action( 'wp_ajax_foobox_foogallery_lightboxes_ignore_notice', array( $this, 'admin_notice_foogallery_lightboxes_ignore' ) );
add_action( 'wp_ajax_foobox_foogallery_lightboxes_update', array( $this, 'admin_notice_foogallery_lightboxes_update' ) );
add_action( 'admin_print_scripts', array( $this, 'admin_notice_foogallery_lightboxes_inline_js' ), 999 );
add_filter( 'foobox-free-has_settings_page', '__return_false' );
} else {
// Render JS to the front-end pages
add_action('wp_enqueue_scripts', array($this, 'frontend_print_scripts'), 20);
add_action('foobox-free_inline_scripts', array($this, 'inline_dynamic_js'));
// Render CSS to the front-end pages
add_action('wp_enqueue_scripts', array($this, 'frontend_print_styles'));
if ( $this->is_option_checked('disable_others') ) {
add_action('wp_footer', array($this, 'disable_other_lightboxes'), 200);
}
}
}
How, if possible, do I dequeue these scripts (and styles) without editing the plugin file directly?
Edit
Below I've added the things I've tried doing to remove the scripts (all added to functions.php):
add_action( 'wp_enqueue_scripts', 'remove_foobox_scripts', 100 );
function remove_foobox_scripts() {
if ( !is_page('my-page') ) {
wp_deregister_script( 'foobox.free.min.js' );
wp_dequeue_script( 'foobox.free.min.js' );
}
}
Also tried the below, which is just a straight copy from the foobox file:
remove_action('wp_enqueue_scripts', array($this, 'frontend_print_scripts'), 20);
remove_action('foobox-free_inline_scripts', array($this, 'inline_dynamic_js'));
remove_action('wp_enqueue_scripts', array($this, 'frontend_print_styles'));
Also tried the below, where the array( part is removed:
remove_action('wp_enqueue_scripts','frontend_print_scripts', 20);
remove_action('foobox-free_inline_scripts', 'inline_dynamic_js');
remove_action('wp_enqueue_scripts', 'frontend_print_styles');
The problem with the way you are trying to do this stems from the order in which things happen in Wordpress.
You are relying on the conditional tags like is_page('my-page') to determine whether or not to load the plugin. These conditional tags do not become available until Wordpress has parsed the URL for the current query, and at this point all the plugins and your theme have already been loaded. Even if you parse the URL yourself instead of using the conditional tags you cannot be sure your code will run before the plugins are loaded.
The solution is to add your code as an mu-plugin. These are loaded before normal plugins so you can use an option (option name) filter here to alter the plugins you want to be loaded.
Option filters pass an array to your function containing the values which are set for that option, so in this case you want to hook option_active_plugins.
You can find the values to use for by running print_r(get_option('active_plugins')); or look through the plugins folder of your wordpress install.
The following example is specific to your question, but you could modify it to make a more comprehensive set of rules, adding and removing multiple plugins on different pages based on many conditions.
My function checks you are not in wp-admin and then has 2 conditions. The first disables a normally active plugin on the specified pages, the second enables a normally disabled plugin on the specified pages.
<?php
add_filter( 'option_active_plugins', 'add_or_remove_plugins' );
function add_or_remove_plugins( $plugins ) {
if (strpos( $_SERVER['REQUEST_URI'], '/wp-admin/' ) !== 0) { // Disable in admin pages or admin plugin settings stop working properly
if (strpos( $_SERVER['REQUEST_URI'], '/remove-plugin-here/' ) === 0) { // Conditonal tags still unavailable so you have to parse urls yourself
$k = array_search( 'foobox-image-lightbox/foobox-free.php', $plugins ); // This will stop an active plugin from loading
if( false !== $k ){
unset( $plugins[$k] );
}
}
if (strpos( $_SERVER['REQUEST_URI'], '/add-plugin-here/' ) === 0) {
$plugins[] = 'foobox-image-lightbox/foobox-free.php'; // This will load the plugin along with all the active plugins
}
}
return $plugins;
}
?>
To install just change the values to suit, paste into a file and upload into your mu-plugins folder
EDIT
Looks like your inline js is added to wp_head during the constructor of the Foobox_Free class. You could try adding this to your functions.php:
add_action( 'wp_head', 'remove_dynamic_js' );
function remove_dynamic_js(){
$foo = Foobox_Free::getInstance();
remove_action('wp_head', array($foo, 'inline_dynamic_js'));
}
or if that doesn't work then maybe this:
add_action( 'wp_head', 'remove_dynamic_js' );
function remove_dynamic_js(){
remove_action('wp_head', array('Foobox_Free', 'inline_dynamic_js'));
}
The action is added inside a private function, so I don't know if either of those will actually work. Give it a shot. If not my first answer will as it stops the plugin from loading at all on the specified pages.
UPDATE
Well, I was close... Here's the code to remove the scripts, as supplied by the plugin author.
$foobox = Foobox_Free::get_instance();
remove_action('foobox-free_inline_scripts', array($foobox, 'inline_dynamic_js'));

Why add_action works only from functions.php not plugin?

When I put my code to functions.php
starting with
add_action( 'woocommerce_order_status_completed', 'do_something' );
here is my code
It Works! But when I put it in plugin
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
if ( ! class_exists( 'WC_Some_class' ) ) {
class WC_Some_class {
public function __construct() {
add_action( 'woocommerce_order_status_completed', 'do_something' );
}
script ...
}
}
// finally instantiate our plugin class and add it to the set of globals
$WC_Some_class = new WC_Some_class();
}
}
This does not work. Why is it?
This is one of those instances where by removing bits of your code and being a little over enthusiastic with the delete key, has led to pretty important information being lost.
However i'll take a stab in the dark and presume you're moving the function from functions.php INTO the class. Therefore your add_action has to know that it needs to call the function (method) of a class, NOT a globally defined function.
Try:
add_action( 'woocommerce_order_status_completed', array(&$this, 'do_something') );

How to add custom javascript to WordPress Admin?

I want to add some custom jquery code to the Edit Post page, something really simple like showing a div when someone presses Publish.
The only restriction is that I want to achieve this through the use of a plugin, not hacking the admin template files.
I've tried echoing some script tags using some actions but it doesn't seem to be the way.
Use the admin_enqueue_scripts action and the wp_enqueue_script method to add custom scripts to the admin interface.
This assumes that you have myscript.js in your plugin folder. Change accordingly. The my_custom_script handle should be unique for your module and script.
function my_enqueue($hook) {
// Only add to the edit.php admin page.
// See WP docs.
if ('edit.php' !== $hook) {
return;
}
wp_enqueue_script('my_custom_script', plugin_dir_url(__FILE__) . '/myscript.js');
}
add_action('admin_enqueue_scripts', 'my_enqueue');
There is a snippet for Your functions.php file :
function custom_admin_js() {
$url = get_bloginfo('template_directory') . '/js/wp-admin.js';
echo '"<script type="text/javascript" src="'. $url . '"></script>"';
}
add_action('admin_footer', 'custom_admin_js');
Works fine on Wordpress 3.2.1.
<?php
function add_jquery_data() {
global $parent_file;
if ( isset( $_GET['action'] ) && $_GET['action'] == 'edit' && isset( $_GET['post'] ) && $parent_file == 'edit.php') {
// Do some stuff.
}
}
add_filter('admin_head', 'add_jquery_data');
?>
admin_enqueue_scripts and wp_enqueue_script are the preferred way to add javascript files to the dashboard.
// I'm using an anonymous function for brevity.
add_action( 'admin_enqueue_scripts', function() {
wp_enqueue_script( 'handle', plugin_dir_url( __FILE__ ) . '/script.js' );
} );
If you want to output the javascript using your PHP function however, wp_add_inline_script doesn't seem to work. Instead, you can use admin_print_scripts to directly echo out the script, including the script tags themselves. Just ensure to set the priority high so that it loads after any required libraries, such as jQuery.
add_action( 'admin_print_scripts', function() {
// I'm using NOWDOC notation to allow line breaks and unescaped quotation marks.
echo <<<'EOT'
<script type="text/javascript">
jQuery(function($){
// Do stuff here.
});
</script>
EOT;
}, PHP_INT_MAX );
If you want to get fancy and filter where you want to load the file or not, best to use get_current_screen.
function myproject_admin_enqueue() {
$screen = get_current_screen();
// load on the NEW and EDIT screens of all post types
if ( 'post' === $screen->base ) {
wp_enqueue_script('my_custom_script', plugin_dir_url( __FILE__ ) . 'all-admin.js');
}
// load on the NEW and EDIT screens of one post type
if ( 'post' === $screen->base && 'myposttype' === $screen->post_type ) {
wp_enqueue_script('my_custom_script', plugin_dir_url( __FILE__ ) . 'mypostype-admin.js');
}
// load only when adding a NEW post, not when editing an existing one.
if ( 'post' === $screen->base && 'add' === $screen->action ) {
wp_enqueue_script('my_custom_script', plugin_dir_url( __FILE__ ) . 'new-admin.js');
}
}
add_action('admin_enqueue_scripts', 'myproject_admin_enqueue');
Directly adding wp_enqueue_script to your code doesn't include the script in new versions of Wordpress (5.0 above).
The better way is to register the script with wp_register_script first to create a handle and then enqueue that handle.
function custom_script_in_admin($hook) {
if ('edit.php' !== $hook) {
return;
}
wp_register_script( 'custom_handle_name',plugin_dir_url( __FILE__ ) . '/script.js', '',true );
wp_enqueue_script('custom_handle_name');
}
add_action('admin_enqueue_scripts', 'custom_script_in_admin');
Somehow the accepted answer didn't work for me. Here is another solution I didn't found in the answers and this is what did it for me, WP 5.x, adding some css and js for my backend...
function suedsicht_theme_add_editor_assets() {
wp_enqueue_style( 'custom-gutenberg-stylesheet', get_template_directory_uri() . '/css/custom-editor-style.css', array(), wp_get_theme()->get( 'Version' ), 'all' );
wp_enqueue_script('suedsicht-admin-js', get_template_directory_uri() . '/js/admin.js');
}
add_action( 'enqueue_block_editor_assets', 'suedsicht_theme_add_editor_assets' );
By using the admin enqueue script hook you can easily add the script file for the admin panel.
function custom_admin_js() {
wp_enqueue_script( 'custom_wp_admin_js', get_template_directory_uri() . '/new-assets/js/admin_section.js', false, '1.0.0' );
wp_enqueue_script( 'custom_wp_admin_js' );
}
add_action('admin_enqueue_scripts', 'custom_admin_js');

Categories