-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Date block: Allow connecting to Block Bindings #70585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Size Change: +308 B (+0.02%) Total Size: 1.89 MB
ℹ️ View Unchanged
|
Flaky tests detected in 8f77685. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/16351551233
|
75013ae
to
81964e1
Compare
const { __unstableMarkNextChangeAsNotPersistent } = | ||
useDispatch( blockEditorStore ); | ||
|
||
// We need to set the date to a default value upon first loading | ||
// to discern the block from its legacy version (which would default | ||
// to the containing post's publish date). | ||
useEffect( () => { | ||
if ( date === undefined ) { | ||
__unstableMarkNextChangeAsNotPersistent(); | ||
setAttributes( { date: new Date() } ); | ||
} | ||
}, [ date ] ); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is largely inspired by #43112.
@@ -623,7 +623,7 @@ Display the publish date for an entry such as a post or page. ([Source](https:// | |||
- **Name:** core/post-date | |||
- **Category:** theme | |||
- **Supports:** color (background, gradients, link, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~ | |||
- **Attributes:** displayType, format, isLink, textAlign | |||
- **Attributes:** datetime, format, isLink, textAlign |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using datetime
(rather than just date
) as the block can still be bound to the post's publish date, which is really a timestamp that includes the time (and can be set from the block toolbar's "pencil" icon via a DateTimePicker).
07f1d7d
to
fa2edfb
Compare
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 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. |
if ( get_the_modified_date( 'Ymdhi', $post_id ) > get_the_date( 'Ymdhi', $post_id ) ) { | ||
return esc_attr( get_the_modified_date( 'c', $post_id ) ); | ||
} else { | ||
return ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will an empty string cause some confusion to the user?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly. But I needed to keep this for backwards-compatibility with the block's previous behavior for the "Modified Date" variation.
I don't love it 100%, but there didn't seem to be a compelling argument against it, so I kept it this way 🤷♂️
@@ -7,6 +7,9 @@ | |||
"description": "Display the publish date for an entry such as a post or page.", | |||
"textdomain": "default", | |||
"attributes": { | |||
"datetime": { | |||
"type": "string" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add role:content
for a future reference to a binding?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that sounds like a good idea 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just left a couple of comments. But the PR is good to go. The backport still needs some work though.
Yeah, my thinking was that information like a post's publish date and last modified date should be presented as part of a dedicated source. Eventually, that source could also expose information such as a post's title, author, etc. It's definitely distinct from post meta, which is typically used defined meta information. Post Data seemed like a fitting name for what we're exposing here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've looked this over and don't see any issues. However, I'm not well versed in bindings.
Co-authored-by: Mukesh Panchal <[email protected]>
685800d
to
bf2ecd5
Compare
label: 'Post Date', | ||
value: entityDataValues?.date, | ||
type: 'string', | ||
}, | ||
modified: { | ||
label: 'Post Modified Date', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both labels should be translatable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oversight on my part! I'll address in a follow-up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent work refactoring the Date block in a way that allows to support custom dates, while offerring variations for the publish and modified dates directly wired to post data through Block Bindings. This is a great example of how flexible blocks could become when using proper APIs. What's the plan regarding the Post Data source and exposing other available fields like status, slug, author, featured media, etc? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noting here to call it out: we’re returning data that has been passed through esc_attr()
, and this is extremely ambiguous because there’s no exit from this function directly to the browser.
I think we saw that there’s no current way to indicate where this data goes, but it would be good to ponder all of these and think of a way we could work in data-escaping and security into the design if we can.
This probably cannot happen from these functions either, simply because these functions do not exist in the right place in the pipeline to know what escaping needs there are.
Luckily esc_attr()
and esc_html()
happen to be the same function today in WordPress, but this doesn’t prevent the potential for data corruption via double-escaping.
|
||
if ( 'modified' === $source_args['key'] ) { | ||
// Only return the modified date if it is later than the publishing date. | ||
if ( get_the_modified_date( 'Ymdhi', $post_id ) > get_the_date( 'Ymdhi', $post_id ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the U
option seems like it would reliably compare without us needing to ensure that we get all the right date field formats in the string. It should return the seconds since Unix Epoch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. This is pre-existing logic that I carried over, but I like yours much better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can start exposing those! I can file a PR to add a few more fields. |
I may need it too for Featured Image :-) |
Make the Date block accept a manually set date, i.e. independent of the current post's publish or last modified date. Retain the latter two options by introducing a new Block Bindings source called `core/post-data` that exposes those two dates. Update existing block variations of the Date block to continue to allow easy insertion of the "Post Date" and "Last Modified Date" variations of the block. Include code for back-compat in the block's PHP, and a block deprecation to update existing Date blocks to use the new Block Bindings-based approach. --------- Co-authored-by: Mukesh Panchal <[email protected]>
What?
Make the Date block accept a manually set date, i.e. independent of the current post's publish or last modified date. Retain the latter two options by introducing a new Block Bindings source called
core/post-data
that exposes those two dates.Update existing block variations of the Date block to continue to allow easy insertion of the "Post Date" and "Last Modified Date" variations of the block.
Include code for back-compat in the block's PHP, and a block deprecation to update existing Date blocks to use the new Block Bindings-based approach.
Why?
Various reasons: The block already supports the publish date of the post, and the "last modified" date. It's a natural extension to connect it to other data sources. One real-world example that inspired this PR was e.g. a director's website with a
film
CPT that had the movie's release as one meta field.How?
In order to connect the block to Block Bindings, we need an explicit date attribute for Block Bindings to connect to.
Problem(s) to solve
Prior to this PR, the block used the
__experimentalPublishDateTimePicker
to set the post (publish) date and time, as that date picker also allows setting the time. For back-compat, it might be easiest to continue storing date and time in all cases; for that, we should probably rename the newly introduced attribute todatetime
.Testing Instructions
Start by testing backwards compatibility:
On the
trunk
branch, create a new post, and insert the "Date" block, and "Modified Date" blocks.Check the code editor; the markup should look like this:
Go back to the visual editor. Set the post's publish date to an earlier date (e.g. yesterday).
Publish the post and view it on the frontend. It should look something like this:
Now switch to this PR's branch, rebuild Gutenberg, and reload the page on the frontend. Verify that the blocks still look the same as before.
Go back to the editor and reload it. Make a small change (e.g. add a new paragraph with a few characters), and switch to the Code Editor. Verify that the blocks have been updated by a block migration. They are now using Block Bindings:
Go back to the Visual Editor. Observe that the first block is now called "Post Date". Save the post again. Once again, view it on the frontend, and verify that it still looks the same as before.
Go back to the editor once more. Insert a "Date" block. In the block's toolbar, use the pencil icon to set an arbitrary date. Save the block, view the post on the frontend, and verify that all three blocks render as expected.
Finally, open a template in the Site Editor that contains a query loop with Post Date blocks. Verify that the block instances work fine there as well.
Screenshots or screencast
Before
Date (i.e. post publish date) and Modified Date blocks:
After
Post Date (i.e. post publish date), Modified Date, and "generic" Date block (that can be used to format a manually entered date):
Note that the Post Date block changes upon publish -- this is because the post wasn't previously published, so clicking "Publish" sets the post publish date, and the block reflects it.