Opened 5 weeks ago
Last modified 5 weeks ago
#65783 assigned defect (bug)
Change method of pulling "On this day" posts
| Reported by: | annezazu | Owned by: | alshakero |
|---|---|---|---|
| Priority: | normal | Milestone: | 7.2 |
| Component: | General | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: | ui |
Description
While helping with a site, I noticed that the "On this day" widget missed posts from today compared to the "Years ago today" plugin. For example, the "On this day" widget completely missed posts from the year 2002 that was shown in the "years ago today" plugin provided option. This is due to the "On this day" widget capping the number of posts shown to 10 to avoid both interface overwhelm and performance issues. This makes it seem that even if you have 20 posts published that day, it'll always act as if only "10" were posted.
Obviously, what a plugin can do is not always what's good for all of Core. In thinking about how to both think about the big publisher with hundreds of posts potentially in a day and a small blogger, I wanted to discuss changing the cap of 10 to a cap of 3-5 per year. This would take up bigger screen real estate but would be a more comprehensive option that I think users will appreciate. Let's discuss.
I don't think this is a blocker for 7.1 as is but adding it to the 7.1 milestone.
Attachments (1)
Change History (9)
This ticket was mentioned in PR #12804 on WordPress/wordpress-develop by @alshakero.
5 weeks ago
#2
- Keywords has-patch has-unit-tests added
## What?
Adds a Show more link to the On This Day dashboard widget when more than ten matching posts exist.
## Why?
The widget previously limited its query to ten posts, which could make it appear that no additional posts existed.
## How?
- Render the total matching-post count while keeping the initial list capped at ten posts.
- Fetch and append the remaining grouped posts through a nonce-protected dashboard Ajax action.
- Use the
button-linkstyle for the expand control and announce loaded post counts to assistive technology. - Add PHP, Ajax, and QUnit coverage.
## Screenshots
| Before | After |
|---|---|
|
|
## Testing Instructions
./vendor/bin/phpcs -n --report=summary,source src/wp-admin/admin-ajax.php src/wp-admin/includes/ajax-actions.php src/wp-admin/includes/dashboard-on-this-day.php tests/phpunit/includes/testcase-ajax.php tests/phpunit/tests/admin/wpDashboardOnThisDay.php tests/phpunit/tests/ajax/wpAjaxDashboardOnThisDay.phpnpx grunt jshint:core --file=src/js/_enqueues/wp/dashboard.jsnpx grunt jshint:tests --file=tests/qunit/wp-admin/js/dashboard.jsnpm run test:php -- --filter Tests_Admin_wpDashboardOnThisDay tests/phpunit/tests/admin/wpDashboardOnThisDay.phpnpm run test:php -- --group ajax --filter Tests_Ajax_wpAjaxDashboardOnThisDay tests/phpunit/tests/ajax/wpAjaxDashboardOnThisDay.php
This ticket was mentioned in PR #12806 on WordPress/wordpress-develop by @iamchitti.
5 weeks ago
#3
## What?
Changes the "On This Day" dashboard widget from a cap of ten posts overall to five posts per year, and makes the summary line report the true number of matching posts.
## Ticket
Trac ticket: https://core.trac.wordpress.org/ticket/65783
## Why?
Older years disappear entirely. Because orderby => date is global rather than per year, one prolific year exhausts the ten-post budget before an older year is reached. The limit isn't ten posts per day — it's ten posts on that calendar date across the site's whole history:
| Posts on that date per year | Oldest year that can appear |
|---|---|
| 1 | 10 years back |
| 2 | 5 years back |
| 3 | 3 years back |
A blog that posts twice on August 1st each year can't see past 2020. The report on the ticket is about a 2002 post vanishing for exactly this reason.
The count was wrong. $post_count was count( $posts ) on an already-capped array, so a day with 15 matching posts rendered "10 posts have been published on August 1st".
## How?
One query reads ID and post_date for every matching post, which is what makes the per-year totals accurate. Grouping and capping happen in PHP, then only the posts that will be displayed are loaded in full via _prime_post_caches().
Results are cached in the post-queries group keyed on wp_cache_get_last_changed( 'posts' ), since the widget queries twice per dashboard load.
Years with more than five matches get a "N more posts" link to that day's archive, so nothing becomes unreachable. That link is suppressed on February 28th in a non-leap year, because the existing leap-day merge means the group spans two
calendar days and no single archive covers both.
Deliberately avoided: one query per year. WP_Date_Query renders a year constraint as YEAR( post_date ) = 2019, which can't use type_status_date, so each per-year query degrades to a full filter over every published post. That
shape measured 48.1 ms against 3.19 ms for the single scan. There's a test asserting the scan contains no YEAR( to stop it creeping back in.
## Notable changes
wp_dashboard_on_this_day_get_posts()returns per-year data keyed by year rather than a flatWP_Post[].wp_dashboard_on_this_day_query_argskeeps its name and now carriespost_type,post_statusandposts_per_year.
## Performance
10k posts spanning 28 years, cold cache, ten runs:
| Sparse day (21 matches) | Dense day (421 matches) | |
|---|---|---|
| trunk | 1.41 ms | 0.76 ms |
| this PR | 3.03 ms | 3.19 ms |
trunk is fast because LIMIT 10 lets it stop after ten index entries — it's quick precisely because it isn't looking. Reporting an accurate total means scanning, since MONTH()/DAYOFMONTH() can't use type_status_date. The cost is ~1.6–2.4 ms on a dashboard load, and the result is cached for the widget's second query in the same request.
## Screenshots
| Before | After |
|---|---|
| | |
## Testing Instructions
- Publish 12 posts dated today's month/day in 2024, 2 in 2011, and 1 in 2002 or use this https://codeshare.io/5o1E1o in testing on wordpress-dev site.
- Load the dashboard.
- Before: one
2024group of ten entries, no 2011 or 2002, header reads "10 posts have been published". - After:
2024shows five entries plus a "7 more posts" link,2011shows both,2002shows one, header reads "15 posts have been published". - Click "7 more posts" — it should land on that day's archive.
npm run test:php -- --filter Tests_Admin_wpDashboardOnThisDay
### Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Implementation, unit tests, and inline documentation; benchmarking the query shapes against a 10k-post fixture; drafting PR description.
@peterwilsoncc commented on PR #12804:
5 weeks ago
#5
@alshakero I've taken the liberty of merging in trunk to resolve the conflicts following https://github.com/WordPress/wordpress-develop/commit/d1c6be6bdae3fb1ef62321df1a8f36060ab26069:
- src/wp-admin/includes/dashboard-on-this-day.php
- tests/phpunit/tests/admin/wpDashboardOnThisDay.php
Are you able to double check that I haven't missed anything?
I'm now moving on to testing and review.
@alshakero commented on PR #12804:
5 weeks ago
#6
@peterwilsoncc I pushed pagination support, but I'm conflicted about my approach to the CSS. I reused CSS from WP_List_Table. On one hand, the CSS is there and it's a shame to duplicate it, on the other hand, it ties two unrelated things together. WDYT? This doesn't use any JS or AJAX, it's quite clean otherwise.
@peterwilsoncc commented on PR #12804:
5 weeks ago
#7
@alshakero As I was typing out the above, a ticket was opened to punt the widget to WordPress 7.2 (See Core-65801), so there's no rush on anything I've mentioned.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)


Confirmed on trunk. I set up a test site with 12 posts on this day in 2024, 2 in 2011, and 1 in 2002, then loaded the dashboard:
Two things going on there. The obvious one is that 2011 and 2002 just aren't present — no heading, nothing to suggest there's anything older to see. That's the 2002 case from the report.
The one I didn't expect is the summary line. It says "10 posts have been published on August 1st" when there are actually 15.
$post_countiscount( $posts )on a result set that's already been capped, so the cap ends up being stated to the user as a fact. Even if we decided to keep truncating, that number shouldn't be wrong.It also kicks in earlier than I think the "big publisher" framing implies. The limit isn't ten posts per day, it's ten posts on that calendar date across our whole history, and since
orderby => dateis global rather than per year, a single busy year eats the whole budget before an older one gets a look in (source:trunk/src/wp-admin/includes/dashboard-on-this-day.php#L177):So a blog that posts twice on August 1st every year can't see past 2020. That's a pretty ordinary site.
On the trade-off: a per-year cap does eat more vertical space, and it only really works if the total gets reported honestly so the widget stops underselling itself. There's also a caveat in how we fetch the posts that I didn't see coming - the obvious approach of one query per year turns out to be a lot slower than what trunk does today, so the query shape matters at least as much as the number we pick. I'll add some stats in the PR I'm working on.