Make WordPress Core

Opened 6 months ago

Closed 2 months ago

Last modified 7 weeks ago

#64952 closed defect (bug) (fixed)

Dashboard Quick Draft allows creating an empty draft without title or content

Reported by: sumitsingh Owned by: afercia
Priority: normal Milestone: 7.1
Component: Administration Version: 5.4
Severity: normal Keywords: has-screenshots has-patch
Cc: Focuses: accessibility, javascript, administration, coding-standards

Description

In the WordPress Dashboard, the Quick Draft widget highlights the title field, but it is still possible to create a draft post without entering a title or any content.

Steps to reproduce:

Go to Dashboard → Quick Draft
Leave both Title and Content empty
Click Save Draft

Current result:
A draft post is created even though no title or content was entered.

Expected result:
WordPress should prevent creating an empty draft or require at least a title before saving from Quick Draft.

Why this matters:
This can create accidental empty draft posts and is confusing from a UX perspective.

Attachments (8)

Dashboard ‹ wordpress-1293544-6294750.cloudwaysapps.com — WordPress.mp4 (549.8 KB ) - added by sumitsingh 6 months ago.
Here are quick recording about empty generating post.
Quick Draft Alert Box for mobile version - 64952.png (63.1 KB ) - added by torontodigits 5 months ago.
Quick Draft Alert Box for mobile version
64952.png (105.7 KB ) - added by afercia 3 months ago.
quick draft admin notices.png (190.0 KB ) - added by afercia 3 months ago.
quick draft 2.7 and 3.0.png (264.3 KB ) - added by afercia 3 months ago.
The quick draft widget in WordPress 2.7, WordPress 3.0 and the spinner when publishing.
Quickk draft for mobile version.png (15.6 KB ) - added by sanayasir 3 months ago.
64952 title 0.png (147.5 KB ) - added by afercia 7 weeks ago.
64952 content 0.png (205.8 KB ) - added by afercia 7 weeks ago.

Download all attachments as: .zip

Change History (43)

@sumitsingh
6 months ago

Here are quick recording about empty generating post.

#1 @gautammkgarg
6 months ago

I am facing same issue

PHP: 8.5
WordPress: 7.0-RC1

#2 @huzaifaalmesbah
6 months ago

Reproduction Report

Environment

  • WordPress: 7.0-RC1-62111-src
  • PHP: 8.3.30
  • Server: nginx/1.29.6
  • Database: mysqli (Server: 8.4.8 / Client: mysqlnd 8.3.30)
  • Browser: Chrome 146.0.0.0
  • OS: macOS
  • Theme: Twenty Thirteen 4.5
  • MU Plugins: None activated
  • Plugins:
  • Query Monitor 3.20.4
  • Test Reports 1.2.1

Steps taken

  1. Go to Dashboard → Quick Draft
  2. Leave both Title and Content fields empty
  3. Click on Save Draft
  4. 🐞 Bug occurs

Expected behavior

  • WordPress should prevent saving a draft when both title and content are empty, or
  • Require at least a title or content before allowing the draft to be created

This ticket was mentioned in PR #11380 on WordPress/wordpress-develop by @opurockey.


6 months ago
#3

  • Keywords has-patch added

Ticket: https://core.trac.wordpress.org/ticket/64952

## Summary

This PR fixes an issue in the WordPress dashboard Quick Draft widget where a draft could be submitted even when both the title and content fields were empty.

The update introduces validation to prevent submission unless at least one of these fields contains input, improving data integrity and user experience.

## Problem

Currently, the Quick Draft form allows users to submit completely empty drafts. This results in unnecessary blank draft entries being created in the database, which can clutter the posts list and create confusion.

Similar inconsistencies with Quick Draft behavior have been observed historically, where drafts may be created without meaningful content due to missing validation.

## Solution

  • Added validation to the Quick Draft submission flow.
  • Prevents form submission when both title and content are empty.
  • Ensures at least one field is filled before allowing draft creation.

Changes

  • Introduced conditional checks before submitting the Quick Draft form.
  • Updated relevant JavaScript/PHP logic to block empty submissions.

## Testing Steps

  • Go to WordPress Dashboard → Quick Draft widget.
  • Leave both Title and Content empty.
  • Attempt to submit.
  • Confirm that submission is blocked.
  • Add either a title or content and submit again.
  • Confirm that the draft is successfully created.

#4 @opurockey
6 months ago

@sumitsingh From Posts-> Add post, We can't save post if both title and content fields are empty. We can follow the same approach here. I have raised a PR that will prevent submission from quick draft if both fields are empty.

@opurockey commented on PR #11380:


6 months ago
#5

@westonruter , Thanks for the suggestions. I’ve addressed the requested improvements and updated the PR accordingly. Please take another look when you have a moment.

@westonruter commented on PR #11380:


6 months ago
#6

@OpuRockey An idea came to mind to leverage setCustomValidity so that an error message can be displayed in addition to focusing on the field. I added this in 899ed5b:

https://github.com/user-attachments/assets/306fc4c5-9ef6-4b11-a5dc-bb35d8ffe9cc

This provides the same result as you had, but with added accessibility and improved user experience.

@westonruter commented on PR #11380:


6 months ago
#7

  • Updated relevant JavaScript/PHP logic to block empty submissions.

It doesn't seem any PHP logic was added to block empty submissions?

#8 @SergeyBiryukov
6 months ago

  • Milestone Awaiting Review7.1

#9 @torontodigits
5 months ago

  • Keywords needs-dev-note added

@westonruter we've tested alert box in mobile & it looks a bit large as it has same font size that is for desktop & in our opnion font size should be less as compared to desktop by following UX rules.

What's your take on mobile version of alert box font size?

@torontodigits
5 months ago

Quick Draft Alert Box for mobile version

#10 @audrasjb
4 months ago

Removing trunk version as this is not going to be shipped with WP 7.0 but in the next releases.

@audrasjb commented on PR #11380:


3 months ago
#11

This looks good to me. In my testing it works fine on either Chrome or Firefox 👍

#12 @audrasjb
3 months ago

  • Keywords needs-dev-note removed

This looks good to me. I only proposed a minor text change.

Also removing needs-dev-note as I don't think this change will need a devnote on Make/Core.

@audrasjb commented on PR #11380:


3 months ago
#13

There is an E2E issue: "Allows draft to be created without Title or Content"
But it should check whether title OR content is provided, not both.

Probably needs an E2E test modification.

This ticket was mentioned in PR #12086 on WordPress/wordpress-develop by @audrasjb.


3 months ago
#14

  • Keywords has-unit-tests added

https://core.trac.wordpress.org/ticket/64952

This copies changes from #11380 and add E2E tests changes.

This ticket was mentioned in Slack in #accessibility by audrasjb. View the logs.


3 months ago

@audrasjb commented on PR #11380:


3 months ago
#16

I started a new PR to work on the failing E2E test: #12086

@audrasjb commented on PR #12086:


3 months ago
#17

Looks like the E2E tests are fixed now. I think the implementation is ready for review.
I'm closing the other PR in favor of this one.

Note for the future committer: don't forget to add the props from the first PR: opurockey, westonruter

@audrasjb commented on PR #11380:


3 months ago
#18

Closing in favor of #12086.

@audrasjb commented on PR #12086:


3 months ago
#19

Right @joedolson 👍 New test added for post with Title but without Content.

@audrasjb commented on PR #12086:


3 months ago
#20

Thanks for the feedback!

#21 @afercia
3 months ago

  • Version 7.05.4

Seems to me this is a regression that comes from this commit https://github.com/WordPress/wordpress-develop/commit/616e4ffb4e for WordPress 5.4.

Related ticket and changeset:

Quick draft dashboard widget creates classic block instead of paragraph block
https://core.trac.wordpress.org/ticket/48120
https://core.trac.wordpress.org/changeset/47191

I clearly remember the Quick Draft form on the Dashboard page didn't allow creating draft with no title or content. That changed in WP 5.4 by introducing some code that wraps the post content within some Gutenberg paragraph block markup <!-- wp:paragraph -->...

The consequence is that when the AJAX action that creates the post fires, the post content is never empty because it contains the paragraph block markup.

That seems not ideal fo me for a couple reasons:

  • Obviously, an empty post should not be created. So the wrapping within the paragraph block should happen after some check for empty post content.
  • It doesn't take into account the scenario where Classic Editor may be activated, and always insert the paragraph block markup in a classic post.

Basically, when there is some post content, what gets saved into the post is as follows:

<!-- wp:paragraph -->Content from the Quick Draft textarea<!-- /wp:paragraph -->

And when the Content textarea is left empty, what gets saved into the post is as follows:

<!-- wp:paragraph /-->

To test:
revert the change from https://github.com/WordPress/wordpress-develop/commit/616e4ffb4e

Overall, I don't think the proper fix for this issue is on the JS side as proposed in the linked PRs. Instead, it should be on the PHP side right before the code added in https://github.com/WordPress/wordpress-develop/commit/616e4ffb4e

Also, ideally, wrapping within the paragraph block markup should be prevented when Classic Editor is activated.

This ticket was mentioned in PR #12194 on WordPress/wordpress-develop by @afercia.


3 months ago
#22

Trac ticket: https://core.trac.wordpress.org/ticket/64952

## Use of AI Tools

Example disclosure:

AI assistance: Yes
Tool(s): GitHub Copilot
Model(s): Claude HAIKU 4.5
Used for: Initial research of the change that introduced the regrsssion.

#23 @afercia
3 months ago

In https://github.com/WordPress/wordpress-develop/pull/12194 I'm proposing a PHP-based approach which adds some more logic to the post-quickdraft-save action.

It also uses wp_dashboard_quick_press() to return an admin notice at the top of the Quick Draft widget when both title and content are empty. See attached screenshot.

To test:

  • Leave both title and content empty, observe the draft is not created and an admin notice appears.
  • Use a screen reader and observe that when the admin notice appears, its text is automatically announced.
  • Enter only the title and submit. Observe the draft is created. Edit the post and switch the block editor to 'Code editor' mode to confirm the post content is empty (no paragraph block markup).
  • Enter only the content and submit. Observe the draft is created. Edit the post and switch the block editor to 'Code editor' mode to confirm the post content does contain the content you entered wrapped within a paragraph block markup.
  • Install and activate the Classic editor plugin.
  • Enter title, content and submit. Observe the draft is created. Edit the post and switch TinyMCE to code mode. Observe the post content contains only the content you entered, no paragraph block markup.

For now, the PR does not contain tests. It would be nice to add / adjust the E2E tests from the other PR: https://github.com/WordPress/wordpress-develop/pull/12086/changes

Last edited 3 months ago by afercia (previous) (diff)

@afercia
3 months ago

#24 @afercia
3 months ago

  • Keywords has-unit-tests removed

I updated https://github.com/WordPress/wordpress-develop/pull/12194 to:

  • Fix and add E2E tests.
  • Make the admin notice have an ARIA role alert so that it's automatically announced by screen readers.

A review would be welcome, when you have a chance. Cc @SergeyBiryukov @desrosj @isabel_brison

#25 @afercia
3 months ago

  • Owner set to afercia
  • Status newassigned

#26 @aion11
3 months ago

On the open question about validation scope, the PHP-based approach discussed in comments #23-25 makes sense as the authoritative validation layer.

One UX consideration is how the error message is presented. While the current admin notice with role="alert" should be announced correctly to screen reader users, Dashboard notices can be easy to miss for sighted users because they are often visually separated from the Quick Draft widget itself.

Would it be worth considering displaying the validation message closer to the relevant field or Save Draft button? Keeping the feedback adjacent to the action that triggered it may make the error easier to notice and understand without requiring users to scan the page for a notice.

This wouldn't affect the validation implementation itself, but may improve the overall user experience depending on how the error output is ultimately rendered.

#27 @afercia
3 months ago

@aion11 Good point. On the other hand, after submitting, focus is moved to the title field so that placing the notice close to the submit button wouldn't be ideal.

Generally, for better accessibility, focus should me moved to the notice itself. However, I would suggest to consider further improvements for the notices in the context of #50486. After all, this ticket is about preventing from creating drafts with no title and content. https://github.com/WordPress/wordpress-develop/pull/12194 already contains some additional improvements and it would be best to not broaden the scope too much.

It is also worth noting that there is already a notice that appears at the top of the Quick Draft. To test:

  • From your browser inspector, remove the hidden nonce field. In the DOM, it is placed a little before the Save Draft button and it's something like: <input type="hidden" id="_wpnonce" name="_wpnonce" value=" ...
  • Enter some content and click Save Draft.
  • Observe a notice appears at the top with text: 'Unable to submit this form, please refresh and try again.'

In the latest commits on https://github.com/WordPress/wordpress-develop/pull/12194

  • I added a success notice when the submission is successful. Previously, no accessible feedback was provided for a success.
  • I cleaned up the JS. It was still referencing a 'reset' button and a 'spinner' that don't exist any longer since ages.
  • Minor cleanup for the CSS,

The new attached screenshot illustrates the 3 notices.

#28 @afercia
3 months ago

For some software archeology:

After the 'Crazyhorse' redesign in WordPress 2.7, in the Quick Draft there were a 'Reset' and 'Publish' buttons. Later, the Publish button was conditionalluy showing 'Submit for review' depending on user roles. See https://core.trac.wordpress.org/ticket/8108

When publishing, there was a spinner image. Af first, it was a 'waiting.gid' image, with no spinner CSS class. There was also a sort of success 'notice' at the top.

See attached screenshot.

The real 'spinner' was introduced in 3.5 (it replaced the 'waiting' gif). See https://core.trac.wordpress.org/changeset/22019/

The #publishing-action section, the Reset / Publish buttons and the spinner were removed 13 years ago in https://core.trac.wordpress.org/changeset/26144/ for the 3.8 redesign see https://core.trac.wordpress.org/ticket/25824

If you want to see these old UIs, you can play with the WordPress playground, targeting these versions:
https://playground.wordpress.net/?php=5.2&wp=2.7&url=wp-admin
https://playground.wordpress.net/?php=5.2&wp=3.7&url=wp-admin
https://playground.wordpress.net/?php=5.2&wp=3.8&url=wp-admin

Lastly, the whole Quick Draft widget is hidden when no JS since https://core.trac.wordpress.org/ticket/26376 so any 'no-js' functionality is pointless here.

@afercia
3 months ago

The quick draft widget in WordPress 2.7, WordPress 3.0 and the spinner when publishing.

This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.


3 months ago

@afercia commented on PR #12194:


2 months ago
#30

Addressed CR feedback. Should be good to go now.

#31 @afercia
2 months ago

  • Resolutionfixed
  • Status assignedclosed

In 62670:

Administration: Prevent the Dashboard Quick Draft widget from creating a draft with empty title and empty content.

Fixes a regression from WordPress 5.4 by making sure the Paragraph block markup is only added when there is some actual content. Otherwise, WordPress will consider the post content 'not empty' and would allow creating a draft with no actual content and no title.

  • Also makes sure the Paragraph block markup is only added when the block editor is actually in use.
  • Adds failure and success admin notices.
  • Adds a role="alert" attribute to the admin notices so that they are automatically announced by screen readers.
  • Adds a $notice_type parameter to wp_dashboard_quick_press().
  • Cleans up the related JS from dead code that doesn't do anything.
  • Prevents from highlighting the most recent draft when no new draft has been actually created.
  • Cleans up the related CSS.
  • Adds E2E tests.

Props sumitsingh, huzaifaalmesbah, opurockey, westonruter, SergeyBiryukov, torontodigits, audrasjb, aion11, sanayasir, joedolson, afercia.
Fixes #64952.

#32 @tyxla
8 weeks ago

Because we use ! empty() for checking the emptiness of title and content, and ! empty( '0' ) is true, we can't create a quick draft with title "0". While rare, it looks like an edge case that might need to be fixed.

#33 @afercia
7 weeks ago

Interesting point @tyxla. I'm not sure I understand what the use case would be, as it's very unlikely users would ever want to create a post with '0' as title (or content).

That said, I believe this is consistent with how the post editor itself works:

  • Try to publish a post with title '0' and nothing else: observe it is not possible.
  • Try to publish a post with excerpt '0' and nothing else: observe it is not possible.
  • Try to publish a post with a paragraph with content '0': it is possible, but only because of the paragraph markup.
  • Repeat after switching the editor to 'Code editor': publishng is not possible,

See screenshots.

Last edited 7 weeks ago by afercia (previous) (diff)

@afercia
7 weeks ago

#34 @tyxla
7 weeks ago

I hear you, but I still think it's a weird edge case to have. And people can have all kinds of purposes in mind, so ideally, they could name posts as they want.

I do see this is a broader edge case than just in the dashboard widget, so maybe it's something to double-check more holistically. Haven't checked the pre-existing code that handles post creation, but I'm assuming it's doing the same ! empty() checks, and that is likely wrong because of such edge cases.

#35 @afercia
7 weeks ago

Yeah, maybe worth a separate ticket for a broader investigation. Just a note that also the new widget in the Gutenberg dashboard experiment should be double checked. It already has an inconsistent behavior that has been reported elsewhere.

Note: See TracTickets for help on using tickets.