Skip to content

WP Admin

An administration theme laid out like the WordPress admin (7.1, "Modern" colour scheme), for sites whose editors know WordPress. It is a Claro sub-theme. The left menu is core Navigation, restyled; nothing replaces it.

The project has three parts:

  • wp_admin, the theme: the dark left menu, list tables, notices, the edit screen's "Publish" box.
  • wp_admin_bar, a module in modules/: the black admin bar across the top of every page. Outside the admin theme it takes the place of Navigation's sidebar, as WordPress shows only the admin bar on the front end. It is a module because a theme's code runs only on pages it draws.
  • wp_dashicons, a module in modules/: Dashicons, the WordPress admin icons, as a dashicons icon pack for the core Icon API. Any template can print one with {{ icon('dashicons', 'admin-post') }}, and modules built on the Icon API, such as UI Icons, list them.

The theme requires both modules, and the admin bar requires Dashicons.

Requirements

  • Drupal 11.4 or later
  • Navigation (core)

Install

composer require drupal/wp_admin
drush pm:install wp_dashicons wp_admin_bar
drush theme:install wp_admin
drush config:set system.theme admin wp_admin

What it changes

WordPress Drupal Where
Admin menu: 160px, dark, current section blue with its submenu open, other sections fly out on hover, collapses to 36px Navigation sidebar css/navigation.css, js/navigation.js
Admin menu icons Navigation's sections, Shortcuts, Help and Announcements drawn with the Dashicon of the nearest WordPress screen; others keep Navigation's icon wp_admin_preprocess_navigation_menu()
Admin bar: site name, "+ New", "Howdy, name" Every page, for users with "Access navigation bar" modules/wp_admin_bar
Admin bar on the front end: no menu, "Edit Page" Pages outside the admin theme; on an entity's page, "Edit" with the entity's other tasks under it modules/wp_admin_bar
"Pages" + "Add Page" heading Page title with local actions beside it templates/layout/page.html.twig, css/page.css
nav-tab row; "All | Published | Drafts" Primary tabs; secondary tabs css/page.css
List table, row actions under the title Tables; operations dropbuttons in a table cell become inline links shown on row hover. In the content, media, people, comment, block and file lists they move under the title css/tables.css, css/row-actions.css, RowActionsHooks
Login screen: 320px white box on grey, "Lost your password?" and "← Go to Site" under it Login, password reset and registration pages, drawn in this theme while it is the admin theme LoginThemeNegotiator, templates/layout/page--wp-login.html.twig, css/login.css
/wp-login.php, /wp-admin Redirected to their Drupal pages WordPressRedirectController
Notices Status messages css/messages.css
Classic edit screen: "Publish" box at the top of a 280px sidebar Node form; actions moved into the sidebar templates/form/node-edit-form.html.twig, css/postbox.css
Settings screens: label left, field right Forms built on ConfigFormBase wp_admin_form_alter(), css/forms.css
Postboxes, dashboard widgets Details elements, dashboard module blocks css/postbox.css
WPBakery's backend editor: rows of element boxes, with edit, clone and delete on each Paragraphs widgets, as described under Page building css/paragraphs.css, js/paragraphs.js, templates/paragraphs/paragraph--preview.html.twig
WPBakery's "Add Element" panel The Paragraphs Editor Enhancements dialog css/paragraphs-dialog.css

js/navigation.js finds the current section by the longest menu link path the page's path sits under, so /admin/structure/types/manage/article/fields is under Structure. Pages with no menu link of their own fall back to their list: /node/* to Content, /media/* to Media, and so on. That section's flyout is copied open under it while the menu is expanded. When the menu is taller than the window it scrolls with the page, as WordPress's does.

The list changes are made to the views' configuration when the theme is installed: each view's operations field goes into its title column, which Views' table style supports itself. Views that arrive later with a module get the same, and uninstalling the theme puts the operations back in their own column. Nothing is changed during a configuration import.

Page building

Paragraphs widgets are drawn as WPBakery Page Builder's backend editor:

  • The field is a panel under a blue bar holding its name and its actions: edit all, collapse all, drag & drop.
  • Each item is a box with a grey bar: drag handle, icon and name, then edit, duplicate and remove as icons. Items inside an open item are white boxes whose icons show on hover.
  • A closed item shows the items it holds as boxes, laid out in its columns, so a row reads as its elements; any other closed item shows a line of its text. The boxes are drawn from the paragraph itself, so they show unsaved changes.
  • An open item with columns lays out the items it holds in those columns too, and again as soon as another layout is picked. An item opened in place among them takes the whole width. "Add in between" is left out between columns; the "+" under the items still adds.
  • Clicking a box opens that item, however deep, with the items above it, in one step; the items beside them stay closed. Paragraphs alone opens one level per click.
  • An item opened on its own, by its box or its edit button, or newly added, that holds no other items opens as WPBakery's "Edit element" dialog: over the page, at full width however deep it sits, with "Done" to close it. Items holding others open in place, as they are the layout, and so does every item opened by "Edit all".
  • Closing a dialog opened from a box puts the page back as it was: the item whose box was clicked closes again, with the items the click opened inside it.
  • A wide field in an open item, such as an editor's toolbar, no longer widens the items above it past the page; the toolbar groups what does not fit.
  • Adding is a dashed "+" box under the items, and a round "+" on the line between two items.
  • The radio buttons of a column field are drawn as row layouts.

To get all of it:

  1. Install Paragraphs Editor Enhancements, which brings Paragraphs Features. Its "Add" dialog is drawn as WPBakery's "Add Element" panel: categories as tabs, a search box, a grid of icons. Give each paragraph type an icon and a category.
  2. In each Paragraphs widget's settings: "Closed mode" Preview, "Add mode" Modal form, and Paragraphs Features' "Add in between" and "Delete confirmation".
  3. Give each paragraph type a preview display with no fields. The closed boxes are drawn from the paragraph, not from that display, so it only saves the work of building it.
  4. If a paragraph type holds a number of columns, name its field under Appearance → WP Admin → Paragraphs, "Columns field". Its value is a number, or an option labelled with a ratio such as "Main and aside (2:1)". Show the field with the "Check boxes/radio buttons" widget to get the layout picker.

Paragraphs Features switches itself on only under themes named claro or gin. wp_admin_bar switches it on under any Claro sub-theme, this one included. Opening an item from its box, and marking the items opened as dialogs, is done by wp_admin_bar too, in ParagraphsOpenHooks, as it changes the form.

Gin Toolbar adds Gin's AJAX throbber, dialog and Media Library styles under every theme; they use Gin's colours and layout, which this theme does not set, so the full-screen throbber shows as an empty white circle and the Media Library as a transparent dialog with its grid in one row. The theme removes them with libraries-override, so Claro's apply.

Gin Layout Builder draws the Media Library and media edit forms with its own templates under any theme but Gin, and loads their CSS only in Layout Builder. wp_admin_theme_suggestions_alter() drops its template suggestions, so Claro's templates apply.

WordPress addresses

/wp-login.php goes to the login form, or by its action to the logout confirmation, password reset or registration page; a redirect_to on this site becomes the login form's destination. /wp-admin goes to the dashboard, and the familiar screens to their Drupal pages: edit.php to Content (?post_type=page filters by the content type of that name), post-new.php to Add content, users.php to People, plugins.php to Extend, themes.php to Appearance, options-general.php to Basic site settings, and so on. Visitors who are not logged in go to the login form first.

Apache sends these paths to Drupal through core's .htaccess. nginx usually hands any .php path to PHP and answers "File not found", so /wp-login.php and /wp-admin/*.php need these lines in the server block:

location = /wp-login.php {
  rewrite ^ /index.php last;
}
location ^~ /wp-admin/ {
  rewrite ^ /index.php last;
}

Front-end themes

The admin bar is fixed to the top of the window and the page is pushed down by its height, 32px, or 46px below 783px wide. A theme with a fixed or sticky header can keep it below the bar with top: var(--wp-admin-bar-height, 0). The bar also sets data-offset-top, so --drupal-displace-offset-top counts it.

Limits

  • Admin pages are laid out for 1024px and up. Below that the admin bar's menu button opens Navigation's own drawer, recoloured, in place of the left menu.
  • gin_toolbar points Navigation's top bar template at Gin's under every theme. wp_admin_theme_registry_alter() points it back.

Dashicons

modules/wp_dashicons/icons is svg-min/ from WordPress/dashicons 0.9.0 (GPL-2.0-or-later), the last release before the project stopped taking new icons. WordPress still ships the same icons as its dashicons font for the admin menu and admin bar.

Maintainers

  • Tyler Brown Cifu Shuster - tbcs

This project has been sponsored by: