On sites with many pages, opening one to edit means going to Pages, searching and clicking. This snippet adds a Pages dropdown to the WordPress admin bar with an edit link for each page, on the front end and in wp-admin, so any page is two clicks away.
The snippet
<?php
/**
* Add a "Pages" dropdown to the WordPress admin bar with an edit link for each page.
* Shown only to users who can edit pages.
*/
// ===== Config =====
function dpc_admin_bar_pages_limit(): int {
return 100; // How many pages to list.
}
// ===== End of config =====
add_action( 'admin_bar_menu', 'dpc_admin_bar_pages', 999 );
function dpc_admin_bar_pages( WP_Admin_Bar $wp_admin_bar ): void {
if ( ! current_user_can( 'edit_pages' ) ) {
return;
}
$wp_admin_bar->add_node(
array(
'id' => 'dpc-pages',
'title' => esc_html__( 'Pages', 'dpc' ),
'href' => admin_url( 'edit.php?post_type=page' ),
)
);
$pages = get_posts(
array(
'post_type' => 'page',
'post_status' => array( 'publish', 'future', 'draft', 'pending', 'private' ),
'posts_per_page' => dpc_admin_bar_pages_limit(),
'orderby' => array(
'menu_order' => 'ASC',
'title' => 'ASC',
),
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
)
);
foreach ( $pages as $page ) {
if ( ! current_user_can( 'edit_post', $page->ID ) ) {
continue;
}
$title = wp_strip_all_tags( get_the_title( $page ) );
if ( '' === $title ) {
$title = __( '(no title)', 'dpc' );
}
if ( 'publish' !== $page->post_status && 'private' !== $page->post_status ) {
$title .= ' (' . get_post_status_object( $page->post_status )->label . ')';
}
$wp_admin_bar->add_node(
array(
'id' => 'dpc-page-' . $page->ID,
'parent' => 'dpc-pages',
'title' => esc_html( $title ),
'href' => get_edit_post_link( $page->ID, 'raw' ),
)
);
}
}
Add it with Scripts Organizer
In Scripts Organizer go to Code Blocks → Add New and give the block a name. Set Trigger location to Everywhere, tick PHP under Script location, paste the code into the PHP editor, edit the config and publish. Leave Action/Hook empty. The admin bar shows on the front end too, so Admin only is not enough.
The same code also works unchanged in a small plugin or an mu-plugin.
How it works
admin_bar_menupasses theWP_Admin_Barobject;add_node()adds the Pages item, linked to the Pages list, and one child item per page. Priority 999 puts it after the core items.- The menu only appears for users with the
edit_pagescapability (editors and administrators by default), and each page is checked withcurrent_user_can( 'edit_post', $id ). - Drafts, pending, scheduled and private pages are listed too, with their status after the title, sorted by page order and then title.
get_edit_post_link()builds the edit URL, so it still works when WordPress lives in a subdirectory.- The admin bar prints node titles as HTML. The snippet strips tags and escapes the title, so a page title can’t inject markup into every admin screen.
The older version had no capability check, so every logged-in user who sees the admin bar, subscribers included, got a list of all pages with edit links. It also printed titles unescaped, linked the parent item to Oxygen templates and loaded every page on every request.
Customise it
- More or fewer pages: change the number in
dpc_admin_bar_pages_limit(). - Another post type: change
'page'inget_posts()and thepost_typein the parent link, and use a capability that fits, such asedit_posts. - Only on the front end: add
if ( is_admin() ) { return; }at the top of the function. - For a single extra link instead of a list, see Add a Custom Link to the WordPress Admin Bar.
Gotchas
- With hundreds of pages a dropdown gets too long to use. Keep the limit low and use the Pages search for the rest.
- Child pages are listed flat, not indented under their parent.
In the Scripts Organizer library Import it with one click from Scripts Organizer.