Make WordPress Core

Opened 3 years ago

Last modified 5 months ago

#26571 reviewing enhancement

Increase flexibility of "At a Glance" Dashboard Widget to match "Right Now" Widget

Reported by: mrwweb Owned by: chriscct7
Milestone: Future Release Priority: normal
Severity: normal Version: 3.8
Component: Administration Keywords: has-patch needs-testing needs-refresh
Focuses: docs Cc:


Following the changes in #26495, the "At a Glance" Dashboard widget is now much less flexible for extending.

Primarily, the issue is the new dashboard_glance_items filter which is significantly less flexible than the previous collection of actions.

Two main issues:

  1. The filter forces all items to be in a single list along with the core "glance items."
  2. The filter does not add any classes to added list items, making them impossible to style.

This last issue is particularly bad, since a class is required to change the icon associated with a list item in the "At a Glance" list.

Here's a use case for why a more flexible filter or an action following the list but before Version and Privacy info is important from my plugin Post Status Menu Items:


Note the separate list and list-item icons. To get that at the present time, I had to hack out of the existing list with an empty list item in the first list and a new empty list with one empty item at the end:

<li class="comment-count"><a href="edit-comments.php">28 Comments</a></li>

<h4>Post Statuses</h4>
<ul class="ps-post-statuses">
<li class="publish-status-post-count">...
...<a href="http://localhost/wp3.6/wp-admin/edit.php?post_status=trash">1 Trash</a></li>

At a bare minimum, the filter should allow for classes, and the ability to create multiple lists would be even better.

There is a rightnow_end action, but it comes after the version and privacy information which feels like a "footer" to me.

The easiest solution for allowing separate lists and wouldn't require reverting #26495 would be to simply add an action following the closing tag of the At a Glance list. Then the dashboard_glance_items could just be extended a bit to add unique classes for styling.

Attachments (4)

dashboard.diff (486 bytes) - added by nerrad 3 years ago.
tweak dashboard_glance_items filter
dashboard.2.diff (475 bytes) - added by nerrad 3 years ago.
tweak dashboard_glance_items filter
26571.diff (549 bytes) - added by swissspidy 10 months ago.
26571.2.diff (652 bytes) - added by swissspidy 9 months ago.

Download all attachments as: .zip

Change History (26)

#1 @toscho
3 years ago

  • Cc info@… added

#2 @theMikeD
3 years ago

  • Cc theMikeD added

#3 follow-up: @Latz
3 years ago

Today I was confronted with this problem, too. Though I haven't any really good solution I managed to at least avoid the empty list items by using the filter as an action (this is a hack after all):

add_filter('dashboard_glance_items', 'addElements');

function addElements() {
    echo '<li class="mytest"><a href="#">Users</a></li>';

No clean code at all but it does the job.

#4 in reply to: ↑ 3 ; follow-up: @toscho
3 years ago

Replying to Latz:

function addElements() {

You should at least return the original array. Your current hack makes things worse by removing all previously registered items. :)

#5 in reply to: ↑ 4 ; follow-up: @Latz
3 years ago

Replying to toscho:
Of course you're right, Toscho's always right :-). Just for the record:

add_filter('dashboard_glance_items', 'addElements');

function addElements($elements) {
    echo '<li class="mytest">' . '<a href="#"> Users</a>' . '</li>';
    return $elements;

This way?

#6 in reply to: ↑ 5 @mrwweb
3 years ago

Replying to Latz:

Replying to toscho:
Of course you're right, Toscho's always right :-). Just for the record:

This isn't really the place to discuss hacks. (But while we're at it, here's what I'm doing. Empty list elements before and after but still technically using the filter.)

Getting this back on track... What do we need to remedy this situation so that we have roughly the same amount of flexibility as previously?

I'd propose:

  1. A dashboard_glance_items_after action that runs immediately after the </ul> of the glance items list.
  2. A modified dashboard_glance_items filter that can handle classes. I assume that would be by passing an array. Either array( '{class}' => '{list item html}' OR array( 'class' => '{class}', 'li' => '{list item html}'.

So questions:

  1. Any objections to change 1 above? (name, placement, use case)
  2. Does anyone have examples of a similar filter somewhere else in core to model this after? There was talk in #26495 of passing the core list items to the filter as well which would need to be considered.
  3. How much do we need to consider backwards compatibility for 3.8? Seeing that #26495 ignored it for ALL PREVIOUS VERSIONS, I'm tempted to say "not much" but a second opinion would be good.

I've never submitted a patch before but I'll step up on this one if people can help me think through the best route for the filter.

#7 @Latz
3 years ago

1) The action is a good idea to be able to do arbitrary stuff.

2) I like the array( 'class' => '{class}', 'li' => '{list item html} ) pattern better because using the class as the key name like in the first pattern you've proposed is not very intuitive in my mind.
Secondly I would not use the key name "li" since it assumes that the markup uses a list. This may change in the future. I would suggest "item" or "content":array( 'item' => '{item html}, 'class' => '{class}' )

Your questions:
1) No objections.
2) Looked through the filters and couldn't find anything similar.
3) Same opinion. Additionally all usages of the current filter forces merely hacks like the examples above.

#8 @viktor-photo
3 years ago

Please advise, what do you think about this "temporary" solution:

add_action( 'dashboard_glance_items', 'cor_right_now_content_table_end' );
function cor_right_now_content_table_end() {
    $args = array(
        'public' => true,
        '_builtin' => false
    $output = 'object';
    $operator = 'and';
    $post_types = get_post_types( $args, $output, $operator );
    foreach ( $post_types as $post_type ) {
        $num_posts = wp_count_posts( $post_type->name );
        $num = number_format_i18n( $num_posts->publish );
        $text = _n( $post_type->labels->singular_name, $post_type->labels->name, intval( $num_posts->publish ) );
        if ( current_user_can( 'edit_posts' ) ) {
            $output = '<a href="edit.php?post_type=' . $post_type->name . '">' . $num . '&nbsp;' . $text . '</a>';
        echo '<li class="post-count ' . $post_type->name . '-count">' . $output . '</li>';
    $taxonomies = get_taxonomies( $args, $output, $operator );
    foreach ( $taxonomies as $taxonomy ) {
        $num_terms = wp_count_terms( $taxonomy->name );
        $num = number_format_i18n( $num_terms );
        $text = _n( $taxonomy->labels->singular_name, $taxonomy->labels->name, intval( $num_terms ) );
        if ( current_user_can( 'manage_categories' ) ) {
            $output = '<a href="edit-tags.php?taxonomy=' . $taxonomy->name . '">' . $num . '&nbsp;' . $text . '</a>';
        echo '<li class="taxonomy-count ' . $taxonomy->name . '-count">' . $output . '</li>';
// Add Some CSS to "At a Glance" Widget
function custom_colors() {
    echo '<style type="text/css">
        .slides-count a:before {content:"\f233"!important}
        .gallery-count a:before {content:"\f163"!important}
add_action('admin_head', 'custom_colors');

3 years ago

tweak dashboard_glance_items filter

#9 @nerrad
3 years ago

  • Cc drenobi@… added
  • Keywords has-patch added

I second adding an action right after the filter so users can add stuff in there to separate up content.

However, the existing filter just needs a slight tweak to allow the ability to add classes. See my patch as added (dashboard.diff)

3 years ago

tweak dashboard_glance_items filter

#10 @nerrad
3 years ago

woops ignore dashboard.diff - has extra unneeded li items.

#11 @Latz
20 months ago

Related: #27414

10 months ago

#12 @swissspidy
10 months ago

  • Milestone changed from Awaiting Review to Future Release

26571.diff is an updated patch using esc_attr() to properly escape the class.

I feel like that's the minimum we should do here.

#13 @swissspidy
10 months ago

  • Milestone changed from Future Release to 4.5
  • Type changed from defect (bug) to enhancement

#14 @swissspidy
10 months ago

  • Keywords needs-patch added; has-patch removed

Needs a new patch. I like the solution proposed in 6 (using an array with different keys and adding an action) better. I'll try to work on it when I find time.

9 months ago

#15 @swissspidy
9 months ago

  • Keywords has-patch needs-testing added; needs-patch removed

This ticket was mentioned in Slack in #core by chriscct7. View the logs.

9 months ago

This ticket was mentioned in Slack in #core by chriscct7. View the logs.

8 months ago

#18 @chriscct7
8 months ago

  • Owner set to chriscct7
  • Status changed from new to reviewing

This ticket was mentioned in Slack in #core by jorbin. View the logs.

8 months ago

#20 @jorbin
8 months ago

  • Milestone changed from 4.5 to Future Release

#21 @ocean90
5 months ago

  • Focuses docs added
  • Keywords needs-refresh added

26571.2.diff looks good so far. I think we should document the change in the filter docs though.

#22 @zodiac1978
5 months ago

Sorry, but I don't know why we need the class here.

With a new list item I can use a custom class within a link/span/etc. via CSS code like this to change the (dash)icon:

#dashboard_right_now .custom-class:before { dashicon css code }

We can't just use classes like dashicons dashicons-info here, because the admin css is providing a dashicon for every span and link too and the dashicons class at the li-item would change the font-family for the list-item content to the dashicon font.

But I thought it wa sthe intention to change the icon and it would be great time saver if we could use the dashicon classes here, but this isn't possible, because of the before mentioned reasons.

So I don't think the patch is helping us here, as we can use the same with code like that:

function add_to_glance( Array $items ) {

    $items[] = '<a class="custom-class" href="http://google.de">Google</a>';
    return $items;

add_filter( 'dashboard_glance_items', 'add_to_glance' );
#dashboard_right_now .custom-class:before {
	color: orange;
	content: "\f348";

Unfortunately we need a CSS block or file to do that, because we can't use :before in style attribute.

Note: See TracTickets for help on using tickets.