WordPress development tutorials

Chances are if you’ve read our series on adding plugin settings to WooCommerce, you’re using an existing WooCommerce settings page or new settings tab to add any required configuration options for your plugin.

If you have a more complex plugin who’s data will be accessed very often (such as Memberships or Subscriptions), you may even be adding a new submenu with a custom settings or usage page for your plugin.

However, we’ve run into any interesting bug lately that affects how you’ll enqueue any custom scripts or styles on extension settings screens, as screen ID checks don’t always return the expected IDs when working with submenu pages.

You’ll need to be aware of this bug when you use any page under the “WooCommerce” menu for plugin options and check the screen ID for this at any point in order to make your plugin non-English-friendly.

Background: Checking for Settings Pages

Let’s assume you’ve added your own settings tab to WooCommerce for a plugin’s configuration options. This is a great option for plugins whose settings don’t fit nicely under an existing tab, as this will let you create your own sections as needed.

Often, you may have settings that depend on one another, and conditionally hiding or showing these settings can assist users when setting up your plugin, ensuring they only see settings they need. Here’s an example of our SKU Generator plugin conditionally showing a setting when it’s relevant: (Click to view)

WooCommerce settings: conditional display

You’ll need to load some javascript to conditionally display these settings, but you don’t want to load it on every single admin page, just where you need it. Typically, you’d do that by checking the screen ID, and maybe even the current tab or section:

function load_scripts() {

    if ( 'woocommerce_page_wc-settings' === get_current_screen()->id ) {
        wp_enqueue_script( 'plugin_admin_scripts', $this->plugin_path . 'assets/js/admin-scripts.js' );
    }
}

This way, your script is only loaded where needed.

Note the pattern this follows for the screen ID: every single page under the “WooCommerce” menu, be it a settings tab or a custom settings page you’ve added with add_submenu_page(), will be prefixed with woocommerce_page_{screen} as its base / ID.

However, WordPress allows this prefix to change, which can cause issues if your plugin is used on a non-English site.

The Problem: Screen Information is Translatable

Let’s take a look at what the settings page typically looks like. If you log the get_current_screen() object, you’ll see that we have the expected data for our settings page:

WP_Screen Object
(
    [action] => 
    [base] => woocommerce_page_wc-settings
    [id] => woocommerce_page_wc-settings
    [in_admin:protected] => site
    [is_network] => 
)

Makes sense, right? When WooCommerce adds its menu page, it’s added with the slug woocommerce, so anything under that menu is prefixed with woocommerce_page_.

Now let’s take a look this screen object if the menu title, “WooCommerce”, is translated (this is using Korean):

WP_Screen Object
(
    [action] => 
    [base] => %ec%9a%b0%ec%bb%a4%eb%a8%b8%ec%8a%a4_page_wc-settings
    [columns:WP_Screen:private] => 0
    [id] => %ec%9a%b0%ec%bb%a4%eb%a8%b8%ec%8a%a4_page_wc-settings
    [in_admin:protected] => site
    [is_network] => 
)

Ruh roh. Now our scripts will never be loaded, which is bad news for us. The screen ID changes with the translation, so the get_current_screen() checks will fail with a translated menu title.

So why is this the case? Why does the screen ID / base change?

Take a look at the way WordPress sets the menu slug: it uses the sanitized menu title instead of the slug itself. When a menu is added, the title is what is shown to users, and thus should be translatable. However, this is then used as the page slug for plugins, meaning that if the menu title is translated, the screen base and ID will use the translated version.

You can follow the progress on this bug in Trac ticket 18857, or checkout Trac ticket 21454 for a more understandable read through of the issue.

Fixing Screen ID checks

Once this is patched, the screen ID for pages under a particular menu won’t change. However, for now, you should be aware of the fact that screen IDs could be transmutable.

So what can you do for your plugins in the meantime? If you need to check the screen ID directly for any page under the WooCommerce menu, you’ll need to do the same thing WordPress does: sanitize the menu title, which will be the translated version of “WooCommerce”:

$screen_id = sanitize_title( __( 'WooCommerce', 'woocommerce' ) ) . '_page_{screen}';

This will ensure your screen checks are valid in any language. If you have a class of helper or compatibility methods in your plugin, it’s best to add a function to get the screen ID so that when this is fixed in WP core, you can update one place with a WordPress version check.

/**
 * Helper to get the screen ID in case "WooCommerce" is translated.
 *
 * See: https://core.trac.wordpress.org/ticket/21454 for details
 * TODO: Can be updated with a version check when https://core.trac.wordpress.org/ticket/18857 is fixed
 */
function sv_get_wc_settings_screen_id() {

    $prefix = sanitize_title( __( 'WooCommerce', 'woocommerce' ) );
    return $prefix . '_page_wc-settings';
}

On a related note, if you add your own screen ID to the woocommerce_screen_ids filter to load WC scripts and styles, be sure to sanitize the title of your settings page here as well so the get_current_screen() checks in WooCommerce can recognize it.

This doesn’t just apply to WooCommerce; it applies to any settings screen that’s added under a specific menu. If you have your own menu or add screens to a different menu, be sure to check if the menu title is translatable, and update your screen ID checks as required.

Published by Nik McLaughlin

You can find Nik around the WP space, on LinkedIn, or on his personal blog.

2 Comments

  1. […] an interesting bug for all WordPress developers: did you know that screen IDs are translatable? If you check a screen ID for your settings pages (such as enqueuing scripts or styles), be sure […]

  2. Thank you for sharing this post

Hmm, looks like this article is quite old! Its content may be outdated, so comments are now closed.