10

I have noticed that some plugins such as Contact-form-7, Nextgen-gallery, possibly others, have an interesting anti-feature of not registering their shortcodes when is_admin() is true.

The problematic thing is, if you want to generate some dynamic content (which may have shortcode) from ajax, and use the "correct" wp way of doing it, admin-ajax.php, it is impossible to not have WP_ADMIN be true. See the first lines of admin-ajax.php:

define( 'DOING_AJAX', true );
if ( ! defined( 'WP_ADMIN' ) ) {
    define( 'WP_ADMIN', true );
}

Now, it seems there are PHP extensions that will let you un-set a defined constant (hacky), or there may be a way to mess with the undocumented WP_Screen system and $GLOBALS['current_screen'] to make is_admin() function return false?? The most usable workaround seems to be posting to the page or the site root.

Is it common for plugins to register their shortcodes when is_admin() is false? If so, I couldn't find any documentation or reason for it other than that it may be a premature optimization.

2 Answers 2

6

I have observed the same issue with contact-form-7 a while back.

But note that registering shortcodes based on is_admin is doing_it_wrong (see gmazzap`s answer)

There are the two reasons that seem legitimate at first sight (and why they are wrong):

  1. (Unlikely) The plugin author tried to optimize the script to only register shortcodes when they are needed. In this case the author did not consider that the shortcode might be used in Ajax requests.

    Wrong because: This optimization does not provide any performance gain. It simply adds a value to the global "registered shortcodes" array.

  2. (This is the more likely one) The plugin author did intentionally disable the support for the shortcode in Ajax requests. With Contact-Form-7 this possibly is the case because forms can be set to "Submit via Ajax". However, this feature requires the form to load additional javascript files which are not loaded when the shortcode is parsed via Ajax and javascript is added via enqueue_scripts().

    The author decided to disable the Ajax support to prevent bug reports like "Don't use this: Form is displayed but clicking the Submit button does not work. Complete waste of time!"

    So the user will either see a guaranteed-working form or no form at all.

    Wrong because: Checking for is_admin is bad practice here. The conditon should check if the constant DOING_AJAX is defined and true.

Though most plugins do not use this kind of condition, the few that have that restriction possibly have it because of problems in the past.

When a shortcode is simply doing some output on the page there is no reason to add any admin-condition. However, when the shortcode does also enqueue js or css files then it makes sense to limit the usage to non-admin/non-ajax requests.

3
  • 2
    Not registering shortcode has close to zero impact in performance. Registering just adds a variable to an array. What is possibly slow is to perform the shortcode, not to register it. So if it's a performace optimizazion, it's a failing one. If the plugin author want to disable shortcode for ajax, checking for is_admin is doing_it_wrong there're far better ways in WP to check for ajax requests. Finally, if plugin enqueues js/css, if it does it well (using 'wp_enqueue_scripts' action) it will not affect admin pages because that hook is not fired in admin pages.
    – gmazzap
    Commented May 25, 2015 at 18:30
  • @gmazzap Thanks for the feedback, I totally agree! I've updated my answer and added your input to make it more clear that the condition is a bad practice.
    – Philipp
    Commented May 26, 2015 at 9:54
  • I don't think #2 is likely, as enqueue_scripts shouldn't affect the_content calls and admin-ajax calls.
    – NoBugs
    Commented May 30, 2015 at 18:11
3
+50

Actually, there is no reason to do not register shortcodes on admin.

If plugins author want to disable plugin form Ajax they should do

if (defined('DOING_AJAX') && DOING_AJAX)

instead of checking for is admin.

Note that in future, is possible that Shortcake will be embedded in core because it is a "Feature Plugin".

If it will happen, shortcode not defined in admin wont work with it. This gives you another confirm that there's no reason to do not register shortcodes on admin: even core developers are working on things that require shortcodes available on admin.

That said, you have to possibilities:

  1. contact plugins author and see if they can fix that behavior
  2. try to find a solution by yourself

Regarding #2, actually exists libraries that can force is_admin to be true. By they are hackish, and I would never use those in production.

An example is Patchwork.

Using it you can override any PHP custom function.

In a MU plugin you can do (completely UNTESTED):

add_action('muplugins_loaded', function() {
  if ( defined('DOING_AJAX') && DOING_AJAX ) {
     require 'path/to/Patchwork.php';
     Patchwork\replace("is_admin", function() {
        return FALSE;
     });
  }
});

This will make is_admin() return false on ajax requests.

However, as said, this is pretty hackish, and will affect other plugins (and core) behaviour with unpredictable effects.

Another thing you can do is to register the plugin shortcode handler on admin requests.

E.g. if plugin code is:

if (! is_admin()) {
  add_shortcode( 'shortcode' , 'plugin_shortcode_handler' );
}

then you can write another plugin that does:

if (is_admin()) {
  add_shortcode( 'shortcode' , 'plugin_shortcode_handler' );
}

This way the shortcode will be added in both cases.

This may or may not work alone depending on other plugin code, but there is no a general answer to this.

3
  • You can also add_shortcode('shortcode', array('their-class', 'their-function') ) or similar.
    – NoBugs
    Commented May 30, 2015 at 18:14
  • @nobugs of course :)
    – gmazzap
    Commented May 31, 2015 at 12:36
  • Or a better "workaround", just post to root of the site or to the page, which ironically is what NextGen does.
    – NoBugs
    Commented Jun 4, 2015 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.