date: drop a trailing backslash instead of formatting it as "undefined" - #81528
date: drop a trailing backslash instead of formatting it as "undefined"#81528Kgupta62 wants to merge 1 commit into
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @Kgupta62. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
| // Add next character, then move on. A backslash that ends the | ||
| // format has nothing to escape, so it is dropped, as in PHP. | ||
| i++; | ||
| newFormat.push( '[' + dateFormat[ i ] + ']' ); | ||
| if ( i < dateFormat.length ) { | ||
| newFormat.push( '[' + dateFormat[ i ] + ']' ); | ||
| } |
There was a problem hiding this comment.
Could you share the motivation? This has behaved this way since long, with no linked issue and no sign of anyone hitting it, the trigger is a format string someone would have to mistype by hand.
I'd gently push back on changing long-standing behaviour that isn't causing a reported problem. Each one still costs review time and carries regression risk, without a case on the other side of the ledger.
Same applies to a few of your other open PRs, the effort is appreciated, I'd just love to see it pointed at reported issues.
There was a problem hiding this comment.
Thanks @im3dabasia — the pushback is fair, and I agree with the principle. Here the trigger is not only a hand-mistyped constant, so let me lay it out.
The Date / Post Date block ships a free-text Custom format field — <TextControl label="Custom format"> in packages/block-editor/src/components/date-format-picker/index.js — and it calls onChange on every keystroke straight into the block's format attribute. The editor preview renders that string with dateI18n( format || siteFormat, … ) (packages/block-library/src/post-date/edit.js:103), while the front end renders the same string through PHP wp_date().
Two consequences:
- Anyone escaping a literal — typing
\a\tfor "at", say — has\as the last character for one keystroke, and in that moment the editor preview printsundefinedwhere PHP prints nothing. - A format saved with a trailing backslash renders
2019-06-18undefinedin the editor and2019-06-18on the front end.
That is an editor/front-end mismatch on a field users type into, which is the case I would want on the other side of the ledger.
The patch only touches the branch where the backslash has nothing left to escape — the escape behaviour itself is unchanged, it just stops emitting [undefined] into the moment format and matches PHP date().
On the broader point: taken on board. I will point the rest at reported issues rather than open more of these, and I am happy to close this one if you still think the trigger is too narrow to be worth the review time.
What?
format()no longer emits the literal stringundefinedwhen the format string ends with a backslash.Why?
The escape branch consumes the next character with no bounds check:
For a trailing backslash there is no next character, so
dateFormat[ i ]isundefined, string concatenation stringifies it, and moment renders it as a literal:date( 'Y\\', … )→"2019undefined"(expected"2019")date( 'Y-m-d\\', … )→"2019-06-18undefined"(expected"2019-06-18")The JSDoc points at PHP's
date()as the reference, and PHP emits nothing for a dangling trailing backslash. A user who mistypes a date format in Settings → General, or a plugin that builds a format by concatenation, gets the word "undefined" printed in every date on the site.How?
Only push the escaped character when there is one. Two unit tests cover a trailing backslash on its own and after a full date format; both fail on trunk with the output above.
Out of scope: a format string consisting of only a backslash. With this change it behaves exactly like an empty format string, which moment renders as an ISO date. That is the pre-existing behaviour of an empty format and is left alone here.
Testing Instructions
By hand:
Y-m-d\(with the trailing backslash).2026-08-12undefined; after it,2026-08-12.Testing Instructions for Keyboard
n/a — no interaction changes.
Use of AI Tools
AI tooling (Claude Code) was used to help find this defect and draft the fix and tests. I confirmed the wrong output on trunk myself, verified the tests fail before the change and pass after, and take responsibility for the code in this PR.