Search by

automattic / jetpack-admin-ui

kraftjehervedereksmartautomattic

Generic Jetpack wp-admin UI elements

Package info

github.com/Automattic/jetpack-admin-ui

Type:jetpack-library

pkg:composer/automattic/jetpack-admin-ui

Statistics

Installs: 3 910 697

Dependents: 14

Suggesters: 0

Stars: 4


README

Generic Jetpack wp-admin UI elements

How to use

Menu Registration

Use the Admin_Menu class to add your plugin under the Jetpack top level menu in WP-Admin.

This package will make sure to register the top level menu, if not registered yet, and will add the new menu(s) item(s) under it.

Use the add_menu to register your menu, no need to do it inside the admin_menu hook. You can do it in your plugin initialization.

The parameters this method gets are the same parameters add_submenu_page gets, except that you don't need to inform parent menu.

Example:

use Automattic\Jetpack\Admin_UI\Admin_Menu;

$page_suffix = Admin_Menu::add_menu(
	__( 'My Awesome plugin', 'my-awesome-plugin' ),
	__( 'My Awesome plugin', 'my-awesome-plugin' ),
	'manage_options',
	'my-awesome-plugin',
	'__my_plugin_page_callback'
);
add_action( 'load-' . $page_suffix, 'my_plugin_do_stuff_on_page_load' );

Menu visibility

An item can declare what gates it, so that turning its feature off removes it from the sidebar. Pass the declaration as the seventh argument:

Admin_Menu::add_menu(
	'Jetpack Search',
	'Search',
	'manage_options',
	'jetpack-search',
	array( $this, 'render' ),
	null,
	array(
		'product' => 'search',
		'key'     => 'jetpack-search',
	)
);
Key Meaning
product A My Jetpack product slug — the products with cards on the My Jetpack page. Preferred, and covers most items.
module A Jetpack module name. Only for items with no product behind them.
key The name a host uses for this item in the filter below. Declare one on every item. Falls back to the menu slug when absent.

Prefer product. A product is not the same thing as a plugin. It may be gated by a Jetpack module, by a standalone plugin, or by either:

Gated by Example products
A Jetpack module Stats, Forms, Newsletter, AI
A standalone plugin Boost, Akismet, CRM
Either — the standalone plugin when it's installed, the module otherwise Social, Search, VideoPress, Backup, Protect
The Jetpack plugin alone, because the product has no module of its own Scan

The product's is_activated() already knows which of those applies, so a registration site names the product and never has to work out which kind it is. It asks only whether the site has switched the product on, never whether it has a plan: a lapsed plan keeps the item, so the route back to upgrading survives, and resolving a gate never makes a request to WordPress.com.

Reach for module only when a sidebar item has no product class at all. SEO is the example: it's gated by the seo-tools module and has no My Jetpack card, so there's no product to name. An item that declares neither is always shown.

A name this site has no module for cannot be answered, so it keeps the item rather than removing it — a typo in a gate is inert. Off the Jetpack plugin that covers any module a standalone plugin has not declared through jetpack_get_available_standalone_modules, so declare one there before expecting a module gate to do anything.

A module gate reads Modules::is_active(), which always answers true on WordPress.com Simple, so gates there never remove anything. Hosts on Simple shape the sidebar through the filter below.

Always declare a key, as a fixed string rather than a reference to the page's slug constant, so renaming a page never renames what hosts have written into their filters.

Everything fails open. An item that declares no gate, a gate naming a product that isn't registered, and a site where My Jetpack didn't initialize all leave the item in place, so declaring a gate can only ever remove an item deliberately.

Declaring a gate is a commitment that the page renders something sensible when the gate is unsatisfied, because a host can force it visible anyway — see below.

Host control

jetpack_admin_menu_visibility filters a map of item key to state. Absent keys stay default.

State Meaning
default Show the item if its gate is satisfied. What every item does unless a host says otherwise.
visible Show the item whatever its gate says.
hidden Keep the item out whatever its gate says.

Every state governs the sidebar entry only. An item that is hidden, or whose gate is unsatisfied, still registers its page, so admin.php?page=… keeps working for My Jetpack's Manage buttons, bookmarks, and support links.

add_filter(
	'jetpack_admin_menu_visibility',
	function ( $items ) {
		// Keep an entry point for a product this platform sells but the site hasn't activated.
		$items['jetpack-search'] = Admin_Menu::VISIBILITY_VISIBLE;
		// Drop a product this platform doesn't offer.
		$items['jetpack-videopress'] = Admin_Menu::VISIBILITY_HIDDEN;

		return $items;
	}
);

The whole map is passed at once so two mu-plugins setting different keys merge rather than clobber each other. visible cannot expose a page to someone who lacks the capability for it — add_submenu_page() refuses those regardless.

Only items registered through Admin_Menu::add_menu() are in the map. Anything added with a bare add_submenu_page() is out of this filter's reach.

Security

Need to report a security vulnerability? Go to https://automattic.com/security/ or directly to our security bug bounty site https://hackerone.com/automattic.

License

admin-ui is licensed under GNU General Public License v2 (or later)