Problem/Motivation

The current {node}.created and {node}.changed columns are often insufficient to meet the needs of publishing workflows. Take the following use case...

An author creates a new article on May 1. This article is edited several times, eventually being published on May 9. Any chronological article listing should now list the article's date as May 9. On May 15, a small typo is discovered. The article is then edited to fix the typo and saved, but chronological article listings should still list the article's date as May 9, since that is when it was originally published.

Currently there is no straightforward way of accomplishing this. Listing articles by creation date doesn't account for articles which are held in draft form for a time while being readied for publication. Listing articles by their modification date fails to account for articles which need minor corrections after they have been published.

Proposed resolution

Add a "published" timestamp column to the {node} table. When a node is saved, if {node}.status=1 and no publication date has been set, then set {node}.published={node}.changed. However, if {node}.published is not empty, then maintain the existing value.

Remaining tasks

  1. Implement the proposed resolution
  2. Write tests for new behaviors
  3. Write upgrade path tests
  4. Implement Views and Token integration to expose the published date
  5. Update the default node list and front page view to sort on the published date
  6. Update the submission information displayed on nodes to use the published date
  7. Review patch and commit!

Tasks for follow-up issues:

  • Extend this behavior to other entities?

User interface changes

Replace the current "Authored on" field, under the "Authoring information" tab on node edit forms, with a new "First published on" field. When the node edit form is loaded, if {node}.published > 0 than the existing value is displayed, otherwise the field is blank. If this field is empty when the node is published, a published date will be generated automatically on submission. If the user manually enters a value in the "First published on" field then it will be used in place of the default value for {node}.published, overwriting any existing value.

The default front page node listing—and its equivalent Views display—will sort on the new published date, instead of nodes' created date. Likewise, the submission information displayed on nodes will use the published date.

Screenshot_1_28_13_10_03_PM.png

API changes

Minor changes to implement {node}.published, but nothing that should impact other modules, unless they want to use the new timestamp for something.

CommentFileSizeAuthor
#169 published-timestamp-1838918-163-again.patch41.56 KBjonathanshaw
#168 published-timestamp-1838918-163.patch41.56 KBjonathanshaw
#163 published-timestamp-1838918-163.patch41.56 KBjstoller
#163 interdiff.txt802 bytesjstoller
#161 published-timestamp-1838918-161.patch41.41 KBjstoller
#161 interdiff.txt4.48 KBjstoller
#159 published-timestamp-1838918-159.patch37.77 KBjstoller
#159 interdiff.txt921 bytesjstoller
#155 published-timestamp-1838918-155.patch36.81 KBjstoller
#155 interdiff.txt848 bytesjstoller
#153 published-timestamp-1838918-153.patch36.81 KBjstoller
#153 interdiff.txt8.11 KBjstoller
#149 published-timestamp-1838918-149.patch32.71 KBjthorson
#142 Screenshot_2_5_13_9_10_PM.png62.06 KBjstoller
#142 published-timestamp-1838918-142.patch35.26 KBjstoller
#142 interdiff.txt6.92 KBjstoller
#138 published-timestamp-1838918-138.patch35.22 KBjstoller
#138 interdiff.txt1.71 KBjstoller
#134 published-timestamp-1838918-134.patch34.58 KBjstoller
#132 published-timestamp-1838918-132.patch34.33 KBjstoller
#129 published-timestamp-1838918-129.patch33.84 KBjstoller
#113 Screenshot_1_28_13_10_03_PM.png61.88 KBjstoller
#110 published-timestamp-1838918-110.patch33.83 KBjstoller
#110 interdiff.txt4.36 KBjstoller
#106 published-timestamp-1838918-106.patch29.21 KBjstoller
#106 interdiff.txt10.54 KBjstoller
#97 Change published date.jpg33.16 KByoroy
#98 Change published date.jpg45.27 KByoroy
#92 published-timestamp-1838918-92.patch24.29 KBjstoller
#92 interdiff.txt1.63 KBjstoller
#86 published-timestamp-1838918-86.patch24.33 KBjstoller
#86 interdiff.txt707 bytesjstoller
#80 publishing-options-unchecked.png12.22 KBjstoller
#80 publishing-options-checked.png19.45 KBjstoller
#80 publshing-options-ex-checked.png20.24 KBjstoller
#80 published-options-override.png36.56 KBjstoller
#80 publishing-options-no-js.png27.65 KBjstoller
#80 published-timestamp-1838918-80.patch24.33 KBjstoller
#80 interdiff.txt2.29 KBjstoller
#71 published-timestamp-1838918-71.patch23.24 KBjstoller
#71 publishing-options.png29.29 KBjstoller
#69 published-on-field.png45.68 KBjstoller
#60 published-timestamp-1838918-60.patch23.23 KBjstoller
#60 interdiff.txt2.36 KBjstoller
#57 published-timestamp-1838918-57.patch23.25 KBjstoller
#55 published-timestamp-1838918-55.patch23.24 KBjstoller
#55 interdiff.txt1.41 KBjstoller
#52 published-timestamp-1838918-52.patch22.9 KBjstoller
#52 interdiff.txt2.28 KBjstoller
#49 published-timestamp-1838918-49.patch22.3 KBjstoller
#49 interdiff.txt1018 bytesjstoller
#43 published-timestamp-1838918-43.patch23.36 KBjstoller
#40 published-timestamp-1838918-40.patch23.34 KBjstoller
#40 interdiff.txt7.99 KBjstoller
#35 published-timestamp-1838918-35.patch23.27 KBjstoller
#35 interdiff.txt7.7 KBjstoller
#34 1838918-34.patch16.35 KBdamiankloip
#34 interdiff.txt1.55 KBdamiankloip
#32 published-timestamp-1838918-32.patch16.16 KBjstoller
#32 interdiff.txt3.34 KBjstoller
#29 published-timestamp-1838918-29.patch14.62 KBjstoller
#29 interdiff.txt385 bytesjstoller
#27 published-timestamp-1838918-27.patch14.58 KBjstoller
#22 published-timestamp-1838918-22.patch14.2 KBjstoller
#15 1838918.upgrade-test.do-not-test.patch1.9 KBBTMash
#15 1838918.patch13.69 KBBTMash
#14 published-timestamp-1838918-14.patch12.23 KBjstoller
#14 interdiff.txt589 bytesjstoller
#11 published-timestamp-1838918-11.patch12.25 KBjstoller
#3 published-timestamp-1838918-3.patch6.23 KBjstoller
#1 published-timestamp-1838918-1.patch5.07 KBjstoller
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jstoller’s picture

Status: Active » Needs review
FileSize
5.07 KB

While, I'm not entirely sure I know what I'm doing, but this seems to work.

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-1.patch, failed testing.

jstoller’s picture

Assigned: Unassigned » jstoller
Status: Needs work » Needs review
FileSize
6.23 KB

I added an update hook.

jstoller’s picture

Title: Add {node}.published timestamp » Add 'published' timestamp to nodes
Issue tags: +Usability, +Needs tests, +DrupalWTF, +workflow, +API addition, +Needs backport to D7

Wow! That actually worked! :-)

Renaming and adding tags, in hopes of getting some eyes on this.

Tony-Mac’s picture

How can I help?

jstoller’s picture

@Antek, can you review the patch, verify it works and see if I missed anything? And if you know how to write tests, feel free to do so.

RdeBoer’s picture

Typo in one of the comments: // Set the pulished timestamp to...

Given its scope, patch looks fine to me.

Question is whether the node table is the right spot for the published flag (status) and the publication date or whether it should be the node_revision table. Or whether this should be generalised further to cover any entity...

BTMash’s picture

I think its a good idea though we have to also consider if there are any ripple effects through the rest of the system (does it show up in views, etc). I don't think this is the kind of change that can get a backport to D7. With that said, we do need tests (both regular to test that the published timestamp works and upgrade path to make sure the timestamps are accurate).

The node save test will need to be updated for the published date. We also need views tests.

For upgrade path tests, the simplest thing to do would be look at the basic upgrade path tests (look at something like http://api.drupal.org/api/drupal/core!modules!system!lib!Drupal!system!T... (look at the source near the bottom of the page) and you'll have something like that and you would be changing up the confirmation tests after the upgrade.

BTMash’s picture

I can help out with the upgrade path tests and will try to get them sometime today (not changing the assigned since you have it but just an FYI).

jstoller’s picture

@RdeBoer, I think this will be most useful as a node-level property. To me the big question is always "when was ANY version of this content first published?" I certainly would not oppose adding a 'published' column to the {node_revision} table, in addition to the {node} table, but the latter is far more important. In fact, if you want to talk revisions, then I'd start with #1838884: Add 'created' and 'changed' columns to node_revision table. That issue is in need of a patch, if you're interested.

As for generalizing this to all entities, I'm 100% for it. I just thought it best to start with nodes, get that committed, then expand on this if there's time. I can certainly see a use for published dates with comments, and maybe even users and taxonomy terms, but node content is where it's most needed, by far.

@BTMash, you rock! Feel free to take an issue from me anytime. ;-)

I don't think the current patch will interfere with Views as is, but it certainly should be added to Views as a field/filter/sort criteria. I'm assuming that can be worked in after feature freeze though?

Help with the tests is absolutely appreciated. The testing infrastructure is a bit beyond me right now. In truth, this whole thing is a bit beyond me, but I poked and prodded until it worked.

One note on the upgrade procedure. Right now I'm setting 'published'='changed' for any node with 'status'=1. This seems like a sane default to me, but I'm happy to entertain other thoughts on this.

jstoller’s picture

I fixed the typo from #7, removed an extra line-break I found, added some checks to testTimestamps() in NodeSaveTest.php, fixed a conflict with a recent core commit and re-rolled against head.

@BTMash, are you still working on the upgrade path tests? And can you take a look at the node save tests I added to see if they look right?

Anyone see any other problems?

jstoller’s picture

Issue summary: View changes

Clarified proposed resolution

jstoller’s picture

Issue summary: View changes

Updated issue summary.

BTMash’s picture

Sorry I couldn't get to it earlier. The plan is to tackle this sometime over the weekend (both the review and attaching an upgrade test).

Lars Toomre’s picture

+++ b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.phpundefined
@@ -72,7 +72,7 @@ function testImport() {
   /**
-   * Verifies accuracy of the "created" and "changed" timestamp functionality.
+   * Verifies accuracy of the "created", "changed" and "published" timestamp functionality.

This needs to be a one line summary less than 81 characters. Perhaps re-word with a second paragraph of what fields/properties are checked?

jstoller’s picture

Shortened comment from #13 and re-rolled.

BTMash’s picture

I'm attaching a version of the patch that is just with the upgrade test and one that is combined with the current patch. The upgrade test is fairly rudimentary but we have a base to start from. Test seems to pass so far. But needs further review.

Status: Needs review » Needs work
Issue tags: -Usability, -Needs tests, -DrupalWTF, -workflow, -API addition, -Needs backport to D7

The last submitted patch, 1838918.patch, failed testing.

BTMash’s picture

Status: Needs work » Needs review
Issue tags: +Usability, +Needs tests, +DrupalWTF, +workflow, +API addition, +Needs backport to D7
BTMash’s picture

I'm a bit confused by how my patch failed if its the same but with an additional test. Retesting.

BTMash’s picture

#15: 1838918.patch queued for re-testing.

BTMash’s picture

There we go - now passes and actually 'needs review' :P

moshe weitzman’s picture

Do we need to declare the new property in the typedData system? Are other date fields handled with typed data?

jstoller’s picture

I noticed a minor typo in a comment (fixed in attached patch). Otherwise the new update path test looks good to me.

@moshe, I'm unfamiliar with the typedData system, but as far as I can tell, this new "published" timestamp is handled identically to the existing "created" and "changed" timestamps.

jstoller’s picture

Issue summary: View changes

Updated issue summary.

jstoller’s picture

Issue tags: -Needs tests

Updated issue summary to reflect current status and removing "Needs tests" tag.

jstoller’s picture

@BTMash: So, if you reviewed my part of the patch and I reviewed your part of the patch, then does that count for RTBC? :-)

marcingy’s picture

Status: Needs review » Needs work

The update part of patch seems flawed to me. Using the changed date seems incorrect as nodes could have been published and then updated multiple times after that initial save, I think there needs to be consideration as to whether or not a node type has revisions, in which case the date of the first revision at status 1 should be used as the published date.

Also node_update_8014 should run as a batch.

jstoller’s picture

I'm again reaching the edge of my coding capabilities. Anyone want to take a stab at improving the update as suggested in #25?

@marcingy, can you point me toward an example of an update like this being run as a batch? Perhaps if I saw how it was done elsewhere I could fumble my way through implementing it here.

jstoller’s picture

Status: Needs work » Needs review
FileSize
14.58 KB

I changed the update function, so it sets {node}.published to the timestamp of the first revision with status=1 for each node, if such a revision exists. If you know of a more performant way of doing this, let me know.

I also altered the upgrade path test to check for this behavior. I have no idea what's in the database that's being tested, so I can't say how appropriate this test is, but it should pass. Again, if anyone has a better way of testing this, let me know. Or post a new patch. :-)

joris_lucius’s picture

@jstoller: I am just starting with the D8 testing and this the first patch I ever tested.
I applied it to my local git install and have some results, could you check them out and leave your comment?

  • When editing an unpublished with an published timestamp:
  • Leaving it empty does not use form submission as the description suggests but uses the old value
  • entering 29-12-28 11:33:38 +0100 returns 2029-12-28 11:33:38 +0100

The last issue might not be right for this patch because you use the code below and not actually check it yourself.

   // Validate the "published on" field.
   $pub_date = new DrupalDateTime($node->pub_date);
    if ($pub_date->hasErrors()) {
    form_set_error('pub_date', t('You have to specify a valid publication date.'));
    }

If you need help with coding I am happy to help, I have experience in D5/6/7 but have not worked on 8 yet.

jstoller’s picture

@joris_lucius, thanks for testing! This is the first core patch I've written myself, so yay for firsts. :-)

Good catch! I see the issue, but I don't think it should work exactly the way you suggest. I've fixed node_submit(), so now if the "Published on" field is empty and the "Published" checkbox is unchecked, Drupal will reset {node}.published to 0. The field will then stay blank until the next time the node is published, or until a new date is entered manually. I hope this behavior makes sense to everyone.

As for your last comment, I'm not sure what to say. I'm validating the "Published on" field identically to how the current "Authored on" field is validated, so if there's a problem with it than I expect it belongs in a different issue. I'm just following existing practices.

If you have time to test the new patch, I'd love to get this RTBC before the new year. :-)

marcingy’s picture

Status: Needs review » Needs work

The upgrade path still needs some love and I forgot about this issue :( Have a look at taxonomy_update_7005 for an example of a batch update.

Also why do this

+    if (!empty($node->published)) {
+      $node->pub_date = format_date($node->published, 'custom', 'Y-m-d H:i:s O');
+    }

Instead why not format date at render time as internally we are likely only interested in the unix timestamp.

The use of node publish and pub_date in the FAPI code seems strange and if you just went done the root of formating publish it would seem cleaner to me, also maybe consider allowing the format to be over riden via $conf.

Can this

if (!empty($node->pub_date)) {
+    $node_published = new DrupalDateTime($node->pub_date);
+    $node->published = $node_published->getTimestamp();
+  }

Be simplified to

if (!empty($node->pub_date)) {
$node->published = new DrupalDateTime($node->pub_date)->getTimestamp();
}

Also there is the queston of views support. This adds a new 'field' but no where in core is it actually exposed.

jstoller’s picture

@marcingy:
I'll take a look at the batch example and see if I can reverse engineer it.

As for your code questions, in both cases I'm using the exact same code that is used for the created date field. You'll see this if you look just above my code, in both places.

From NodeFormController.php:

    else {
      $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
      // Remove the log message from the original node entity.
      $node->log = NULL;
    }
    if (!empty($node->published)) {
      $node->pub_date = format_date($node->published, 'custom', 'Y-m-d H:i:s O');
    }

And from node.module:

  if (!empty($node->date)) {
    $node_created = new DrupalDateTime($node->date);
    $node->created = $node_created->getTimestamp();
  }
  else {
    $node->created = REQUEST_TIME;
  }

  if (!empty($node->pub_date)) {
    $node_published = new DrupalDateTime($node->pub_date);
    $node->published = $node_published->getTimestamp();
  }
  elseif (!empty($node->status)) {
    $node->published = REQUEST_TIME;
  }
  else {
    $node->published = 0;
  }

I thought it best to leave it this way, for consistency. I figured it would all be refactored later in the development cycle, if necessary.

As for allowing the format to be overridden via $conf, I have no idea what that entails. Is the "Authored on" field handled this way? If so, can you show me where and I'll try to duplicate it? If not, then can we save this for a followup issue, since there's no reason why both fields shouldn't be handled in the same way.

Likewise, I was going to save Views support for a followup issue, once the field itself made it in. Do you think that's a problem? If so, then would you care to help with the code? :-)

jstoller’s picture

@marcingy: Here's an new patch with the update running as a batch. Is this what you had in mind? Any thoughts on an appropriate number nodes to update in each batch? Right now its set at 1000.

jstoller’s picture

Status: Needs work » Needs review

Setting to needs review.

damiankloip’s picture

Issue tags: +VDC
FileSize
1.55 KB
16.35 KB

Sorry to just jump in here, hope that's ok. Now Views is in core, this should probably include the integration for that too, as it should be relatively trivial. I also just removed a couple of whitespace characters from the last patch.

jstoller’s picture

@damiankloip, you beat me to it! :-) I was just working out the Views integration this morning, but didn't get round to posting it until now. I appreciate the help though!

I went through and looked for everywhere the created and changed fields are used, and then I copied that same treatment for our new published field. Assuming I didn't screw it up, this should have full Views integration and Token support. I also rolled in your whitespace corrections. The interdiff is against my patch in #32.

Please, please, please review. And feel free to jump in again if you see anything wrong with this patch.

damiankloip’s picture

err, yeah, I would have rolled in my changes for the actual integration too ;) See the interdiff in #34. So my feedback on that is basically contained in what I have done, that you didn't roll into your patch :)

jstoller’s picture

@damiankloip, unless I'm missing something, it's in there.

diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc
index a67b870..41d2db7 100644
--- a/core/modules/node/node.views.inc
+++ b/core/modules/node/node.views.inc
@@ -117,6 +117,22 @@ function node_views_data() {
     ),
   );
 
+  // published field
+  $data['node']['published'] = array(
+    'title' => t('Published date'), // The item it appears as on the UI,
+    'help' => t('The date the content was first published.'), // The help that appears on the UI,
+    'field' => array(
+      'id' => 'date',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'id' => 'date'
+    ),
+    'filter' => array(
+      'id' => 'date',
+    ),
+  );
+
   // Content type
   $data['node']['type'] = array(
     'title' => t('Type'), // The item it appears as on the UI,

Is this wrong?

damiankloip’s picture

It's in there, but clearly my patch wasn't used. You have just done it yourself I guess?! Things like the inline comments? Which we don't do anymore. Generally it's a good idea to just use the most recent patch, rather than talk about changing an older one to have changes from a newer one :)

dawehner’s picture

This is really good so far but i really wonder why this is tagged as needs backport. Isn't that a new feature?

+++ b/core/modules/node/lib/Drupal/node/NodeFormController.phpundefined
@@ -44,6 +44,9 @@ protected function prepareEntity(EntityInterface $node) {
+      $node->pub_date = format_date($node->published, 'custom', 'Y-m-d H:i:s O');

In general i'm wondering whether we should really shorten here and not use something like $node->published_date

+++ b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.phpundefined
@@ -102,29 +106,75 @@ function testTimestamps() {
+      'status' => 0,
...
+    $node->status = 1;
...
+    $node->status = 0;
...
+    $node->status = 1;

What about using the node status constants.

+++ b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.phpundefined
@@ -102,29 +106,75 @@ function testTimestamps() {
+    $node = $this->drupalGetNodeByTitle($edit['title']);
...
+    $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
...
+    $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
...
+    $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
...
+    $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);

Why not just get the node from the entity_create and not load it all the time. This could then be a lot easier.

+++ b/core/modules/node/node.moduleundefined
@@ -992,6 +992,17 @@ function node_submit(Node $node) {
+  elseif (!empty($node->status)) {
+    $node->published = REQUEST_TIME;
+  }
+  else {
+    $node->published = 0;
+  }

Don't we have the same logic in the storage controller already?

+++ b/core/modules/node/node.views.incundefined
@@ -117,6 +117,22 @@ function node_views_data() {
+  // published field
+  $data['node']['published'] = array(
+    'title' => t('Published date'), // The item it appears as on the UI,
+    'help' => t('The date the content was first published.'), // The help that appears on the UI,

As damian wrote, there is no need for this silly comments anymore and we remove it in other patches, but yeah you couldn't have known that.

+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/NodePublishUpgradePathTest.phpundefined
@@ -0,0 +1,51 @@
+class NodePublishUpgradePathTest extends UpgradePathTestBase {

Oh great, an upgrade path test!

+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/NodePublishUpgradePathTest.phpundefined
@@ -0,0 +1,51 @@
+   * Tests a successful point release update.

Better describe what is going on here, it's updating the nodePublished column.

+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/NodePublishUpgradePathTest.phpundefined
@@ -0,0 +1,51 @@
+      $timestamp = db_query('SELECT timestamp FROM {node_revision} WHERE nid=:nid AND status=1 GROUP BY nid', array(':nid' => $node->nid))->fetchField();

You probably should also use spaces between nid=:nid etc.

jstoller’s picture

@damiankloip, sorry, didn't mean to break with protocol. I already had my patch ready to go when I saw yours, so it seemed easier to just pull in the missing bits. I didn't realize the in-line comments were being phased out, so I left them in for consistency with the other date fields. I've removed them now.

@dawehner, this patch should contain all your requested changes, with the exception of removing the drupalGetNodeByTitle() functions in the NodeSaveTest. If I'm not mistaken, getting $node from entity_create(), or save(), would give us the node object we are writing to the database. This is certainly more performant, but in order for this to be a true test I think we need to first save the node and then read it back out again, using complete save and load operations.

dawehner’s picture

This is certainly more performant, but in order for this to be a true test I think we need to first save the node and then read it back out again, using complete save and load operations.

Is there anything else in core which does something similar? If you really need the loading why not simply use $node = node_load($node->nid);

In general I think you should wait until #1833334: EntityNG: integrate a dynamic property data table handling is in, because from my perspective a generic entity storage is way more important
than this issue (sorry) and so we shouldn't work towards breaking that patch.

jstoller’s picture

@dawehner, I just extended the existing tests in NodeSaveTest.php. If you look at the current file, you'll see this same method used throughout. I assume drupalGetNodeByTitle() is used instead of node_load() because we know the title of the node we just created, but not the nid. To be fair, I don't have a terribly deep understanding of the API, so I can't tell you what the best way to accomplish this is. It just seems to me that if we're really going to test what happens when we save a node, then we need to do it such that all the hooks which fire when a node is saved and read back out are give a chance to do so.

I took a quick look at #1833334: EntityNG: integrate a dynamic property data table handling and it doesn't seem to touch any of the same files we're touching in this patch. Can you explain what in this patch would break that one? Is it a piece we could cut out and save for a follow-up issue? There are other follow-up issues I'd like to address once this is in, so I don't want to hold this patch up too long.

jstoller’s picture

Issue summary: View changes

Update remaining tasks

jstoller’s picture

One of the files we edit has moved, so I re-rolled against head.

Any more comments on this?

dawehner’s picture

This was the totally wrong issue: #1498674: Refactor node properties to multilingual is the one I was talking about.
As that issue hasn't been updated that recently you should probably not wait on that one, but that is just a guess.

jstoller’s picture

So... Does anyone have any remaining comments on this issue, or can someone mark it RTBC? Development time for followup issues is quickly evaporating and I'd like to get this in sooner than later.

jstoller’s picture

damiankloip’s picture

Status: Needs review » Needs work

It's generally looking pretty good, a couple of things:

+++ b/core/modules/history/lib/Drupal/history/Plugin/views/field/HistoryUserTimestamp.phpundefined
@@ -37,6 +37,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
+      $this->additional_fields['published'] = array('table' => 'node', 'field' => 'published');

This has crept in, I don't think we need this on this handler? I know it completes the set but it's not being used.

+++ b/core/modules/node/node.views.incundefined
@@ -382,6 +398,60 @@ function node_views_data() {
+  $data['node']['published_fulldate'] = array(
...
+  $data['node']['published_year_month'] = array(
...
+  $data['node']['published_year'] = array(
...
+  $data['node']['published_month'] = array(
...
+  $data['node']['published_day'] = array(

Not too sure what all these are doing in here? The Date handler for the published field data will handle outputting in whichever format you need. Plus, none of these plugins, such as 'node_published_fulldate' even exist, So this would be throwing some errors :)

damiankloip’s picture

Sorry, arguments not filters :) Just the first comment, not the second! Sorry!

jstoller’s picture

Status: Needs work » Needs review
FileSize
1018 bytes
22.3 KB

@damiankloip, I removed the change to HistoryUserTimestamp.php and ignored your second comment, as requested. :-)

jstoller’s picture

Green light! Can I get an RTBC? :-)

marcingy’s picture

Status: Needs review » Needs work

So after looking at the upgrade path there is an issue. The process is based off using a timestamp off of the node revision table. This works prefectly if revisions per node are enabled otherwise you end up with a case as follows.

I create a node that is status one. 2 weeks later I change some text the timestamp gets updated. The first published date will now be incorrect. I am not sure what the solution to this but as it stands the approach being used could lead to massive problems. Maybe we need to follow these rules

* If we have revisions use the first status 1 entry
* If we have no revisions use the created date, while this also may be wrong it means that the it adheres to the current rules where created is given precedence over changed.

Also I would like to weigh in that this can't really be back ported to drupal 7 in my opinion as it has significant implications in terms of upgrades for existing sites and the same solution can be achieved by adding a field in d7 and populating that in a programatic way so while a core solution might be nice it this is really a feature request.

jstoller’s picture

Status: Needs work » Needs review
FileSize
2.28 KB
22.9 KB

This should do it.

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-52.patch, failed testing.

damiankloip’s picture

I will let you guys fight out the upgrade path tests. when those are sorted, the rest is rtbc for me.

jstoller’s picture

Status: Needs work » Needs review
FileSize
1.41 KB
23.24 KB

This should fix the upgrade path test to match the changes in #52.

@marcingy, does this address your concerns?

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-55.patch, failed testing.

jstoller’s picture

Status: Needs work » Needs review
FileSize
23.25 KB

Oops. Small typo.

jstoller’s picture

What do you say marcingy? Can we commit this sucker?

tstoeckler’s picture

+++ b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php
@@ -102,29 +106,75 @@ function testTimestamps() {
+    $node = $this->drupalGetNodeByTitle($edit['title']);
...
+    $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
...
+    $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
...
+    $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
...
+    $node = $this->drupalGetNodeByTitle($edit['title'], TRUE);

This should be $node = node_load($node->id()).

+++ b/core/modules/node/node.install
@@ -707,6 +713,97 @@ function node_update_8013() {
+      ->condition('r.status', 1,'=')

1. There should be a space after the last comma.
2. I might be mistaken, but I think '=' is the default condition operator and, hence, can be omitted.

Both of these things are very minor, and this could definitely go in, without that, but I have one more substantial question:
I am far from being a DB expert so this might actually have a valid answer, but is there a reason that moving all nodes into the temporary table can be done in a single pass, but then moving that back into node requires a batch?

jstoller’s picture

@tstoeckler:
The drupalGetNodeByTitle() function is already used throughout NodeSaveTest.php. For consistency, if nothing else, I would like to keep using it here, since I'm mostly just modifying the existing tests. I'm also not completely convinced you're suggestion will do exactly what the test is supposed to be doing here. Can we save refactoring this test for a separate issue?

The attached patch removes the extraneous '=' and a couple unnecessary commas.

As for your DB question, I copied this approach from another module and am also not a DB expert, but I can take a guess. Filling the temporary table is done with one big database call. But when you move the data into the node table, you're executing at least two db calls per node, in addition to the call to grab your data, plus some per-node php calculations. I can see how this might overwhelm a system with many thousands of nodes, causing the update function to time out. Batching the processing of individual nodes should help guard against that.

marcingy’s picture

Another thing has crossed my mind after looking at the actually form changes in a browser which seems to create a bit of wtf from a user point of view. We have 2 field exposed
* Created
* First published

The 2 can be set independently and you can infact set a nodes creation date to be after the publish date which seems strange. Now maybe this is part of a follow but the UI we end up with is less than ideal. Maybe this patch should be split into 2 part one
* Add the new field and make sure that it gets populated when the node is first published but with no exposure on the node form
* Step 2 amend the UI to expose the field and likely hide the creation date of the node as that is now in effect behaving in a similar way as being changed.

As I say it might be possible to commit this patch as is and do the created/published changes in a follow up so not blocking as such just throwing the idea out there as I am sure this patch will get some more reviews once it hits the rtbc queue.

Otherwise I think the patch looking pretty good, and I agree it would be nice to get someone with some database chops to look at the update function detail.

jstoller’s picture

@marcingy, I would argue that the publish and created dates serve two very different purposes, so we need to allow them each to be modified independently from one another. The ability to change a publication date is important to this feature, so I wouldn't want to remove it. The dates have different meanings and are used by different parts of the system in different ways. In fact, I have a D6 website right now where I set my publication date before my created date on some nodes. There are perfectly reasonable use cases for doing this, so I wouldn't try to stop it from happening. It is up to the developer/site builder for a given site to restrict when and how these fields can be manipulated.

If you're OK with the rest of the patch, then can you mark it RTBC? I'd still like to squeeze in some followup issues if we can, before time runs out.

marcingy’s picture

Status: Needs review » Reviewed & tested by the community

I will mark rtbc but I have real concerns about the ux of what is being committed, I am sure though who ever commits this will weigh in if they have issues with UX.

I do see what you are saying re UX and I am not saying publication date can't be before created date, what I am saying is that it makes no real sense to expose both in the UI as it opens up users to ask questions, and remember not all sites are configured by true site builders or developers so there needs to be a sane and usable default.

jstoller’s picture

Status: Reviewed & tested by the community » Needs review

Well, from my perspective, if we were to only allow editing of one of these dates on the node form, I would show the published date over the created date. However, before a change like that could be made,the published date would need to be integrated deeper into Core. Namely, the article listings which now use the created date would need to be altered to use the published date. This should happen anyway, IMHO, but that's for a followup issue.

As for the current UI, I'm not too worried about it. The two date fields are on different tabs and it seems clear they are altering to different things.

marcingy’s picture

Yup I am in agreement with the end state of just published, and hiding the created date, so I think we are seeing exactly the same end state :) Did you cross post or did you mean to set it back to needs review?

jstoller’s picture

Status: Needs review » Reviewed & tested by the community

Didn't mean to change the status.

tstoeckler’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: -Needs backport to D7 +Needs usability review

Agree with the RTBC code-wise. Thanks for your explanations @jstoller, they make tons of sense :-)

Reading the last comment, I think this could use a lookover by Bojhan, yoroy or someone else from the usability team, to make sure we're not introducing a regression on one of *the* most visited forms on most Drupal sites. Hence, moving to "needs review" and tagging accordingly.

Also, to accelerate the usability review process, it would be awesome if someone could attach before/after screenshots of everything that this patch changes in the UI.

Again, if we get the green light from the UX team, this can go straight to RTBC.

(Also removing the backport to D7 tag, I highly doubt we will want to do that.)

Edit: Remove completely weird English. Sorry, not a native speaker.

jstoller’s picture

I'll try to add a screenshot later tonight.

As for the D7 backport, I disagree, but we can get into that after this is committed. :-)

jstoller’s picture

FileSize
45.68 KB

Here's a screenshot of the new "Published on" field. The field is essentially the same as the existing "Authored on" field, but in a different tab.
published-on-field.png

John Pitcairn’s picture

Should that say "First published on"?

jstoller’s picture

@John Pitcairn: Yes. Yes it should. :-)

publishing-options.png

John Pitcairn’s picture

Knowing some users, I think there might be some confusion about whether this is a scheduled publishing field, ie if they uncheck the "published" checkbox and enter a future date/time into the field, they'll think it will be automatically published at that date/time. But that's something the usability review can consider, and I'm unlikely to let my users anywhere near this option anyway ;-)

jstoller’s picture

@tstoeckler: I don't think this is in any way a UX regression. As a UX designer myself, here are my 2-cents:

  1. The functionality of a published field is itself a big UX win.
  2. The ability to manually override the published field, through the UI, is an important part of this feature.
  3. In the context of the node edit form, as it currently stands, the published field has been placed in the appropriate location and is about as intuitive as can be expected.
  4. There seems to be agreement that any significant UX problems stemming from this feature are actually with the "Authored on" field and not with the "First published on" field. I think this can and should be dealt with in a follow up issue, rather than here.
  5. Given that the whole node creation form is being rethought, whatever we do here is likely to be changed anyway. The sooner we get this feature committed, the sooner others can integrate it into their plans.

@John Pitcairn: You raise an interesting point and I suppose I could see that happening. If we think it's a real concern, we could add some more help text, but I'm afraid that's already a bit long. We could also change the label to something like "Was first published on," to make it clear this is something that happened in the past.

That being said, these are just simple string changes. Again, given a more extensive overhaul of this form is already underway, I think we need to get the feature in quickly, so we can play with improving the UX in the context of those other issues.

jstoller’s picture

scronide’s picture

For what it's worth, I agree with #72. If I encountered this in the wild I would wonder if it supported auto-publishing on future dates, so I suspect end-users might easily assume it.

I foresee a bigger problem in the long-run if workflow statuses are abstracted out. If a node can be "In review", "Rejected", etc. then editable date fields for each becomes unwieldy. Even now, the argument for a published timestamp could be applied to the "Promoted to front page" and "Sticky at top of lists" states much the same.

yoroy’s picture

Status: Needs review » Needs work

I think having this feature is a good idea. The latest UI is not yet convincing though:

- The UI elements are in the right place. But boy do they fill up the room.
- Is the 80% use case that you want to use this? Or should this be something that's available when needed but not so prominently there all the time?
- The amount of description text is a clear indication that a single text field does not suffice for helping people express a full data and time. One would expect a date picker here.
- The wording of the label reads as if this is required info, almost as a direct order. What I miss is a clue for why I might want this: "Change original publication date" or "Set first published date" or something.

Overall I think this introduces too much UI too prominently. "Nice to have", maybe "should have" but the current UI presents this in a "Must have" fashion.

What about showing the actual "first published on: date, time" info, with the date and time as a link that trigger the text field or date picker? Similar to the machine name pattern: http://drupal.org/node/1227546

jstoller’s picture

Status: Needs work » Needs review

@scronide: I reject that tracking when something was first promoted, or set to sticky, is in any way equivalent to tracking when it was published. And as someone who has long worked on workflow issues, I see no general use case for tracking the first time something was submitted for review, or rejected. In most workflow scenarios the node creation date, or the individual revision timestamp, is all you need. However, for reasons previously stated, sorting nodes by their creation date in public lists is a broken system. There is something special about the first time content is made public and in most cases sorting on that is far more appropriate than the other available options.

@yoroy: I agree 100% that this is not an ideal UX for this feature. That said, the current implementation is identical to the "Authored on" field, so there is precedence for this approach. I absolutely agree that this field should be a date/time picker, but to the best of my knowledge that isn't supported in core yet. Once #501428: Date and time field type in core is committed, we can easily convert this from a textfield to a datetime field, which should help a lot, but I don't think we should hold up this issue for that one.

I like the idea of hiding the date and providing a link to edit it, like machine names. That said, there is a lot of plumbing in place to make that machine name trick happen. I'm not sure we can get away with doing all that for one field on the form. If we do, then it should probably be abstracted into something more generally usable. It also should probably be done in a follow up issue. In any case, we would still need this to work when javascript is disabled, in which case we'd be left with what we have now.

Most importantly, this issue doesn't exist in a vacuum. Issues like #1510532: [META] Implement the new create content page design and its offshoots will be impacted by this new form element. I would like to get this feature in soon, so the new field can be addressed within the context of these larger UX discussions. Trying to perfect the field within the current form, knowing the form is going to change, seems counterproductive. Lets get the feature in there, so developers have something to work with.

yoroy’s picture

Status: Needs review » Needs work

My review was very much with the new content creation form in mind :) I agree date picker is beyond current scope here.

I don't understand your reasoning around abstracting around machine name pattern. It's already a pattern, what further abstraction is needed here?

Does the field show a value when editing an existing content item? It's the emptyness of the field that makes this look, not necessarily required, but leaving it blank suggests you are forgetting or ignoring something. It leaves on open loop in the user experience, which doesn't build trust.

So, current UI is not acceptable in my opinion. A usability review was requested, I gave one. It's not encouraging to then get 'lets make that a follow up issue' as the response. I'm fine with getting the feature in first but then it may be better to remove the UI all together and design a better one in a followup.

John Pitcairn’s picture

Personally I'd expect the "first published on" field to be non-editable for most users anyway (a permission perhaps?), and for it to display "never published" if the node has never been published.

jstoller’s picture

@yoroy: I promise I'm not trying to give UX short shrift. I'm just doing the best I can to improve it with a fast approaching deadline.

As I said, this field works identically to the "Authored on" field, so if you're editing an existing node that has been published at some time (or had its published date set manually), then the form field will not be empty, but rather filled with the existing published date. When the form is submitted, if there is a date in the form field it'll be maintained. If the field is blank on submission and the node is being published, then the submission time will be saved as the published date for that node.

"machine_name" is a specific field type defined in the form API. Using that type governs how the field is themed and loads a bunch of javascript which handles its behavior, but that behavior is specific to machine name fields. So while the ideal behavior for the published date may be similar, it is not similar enough to use the same code and I can't imagine that anyone will want to create a published_date field type in the form API. That is why I say we would need a more generally applicable solution.

In that vein, I've done some more experimenting with the form API's existing functionality and created a workaround which I hope you will all find more appealing. When creating a node, if "Published" is unchecked, the published date options are hidden:
publishing-options-unchecked.png

When "Published" is checked, a second checkbox appears giving users the opportunity to override the published date:
publishing-options-checked.png

If you are editing an existing node that already has a published date, then that date will be listed in the field description:
publshing-options-ex-checked.png

If you check the override checkbox, then the form field appears, allowing you to enter your own date, or edit the existing one:
published-options-override.png

Finally, in the event Javascript is disabled, the "First published on" field will display, but the override checkbox will be hidden, so as not to confuse users. This is similar to what happens with the machine name field when there is no javascript.
publishing-options-no-js.png

Once #501428: Date and time field type in core is committed, we can change this text field to a proper datetime field and clean up its descriptive text, which will further improve the UI. Also, assuming the "Authored on" field is retained, this same treatment should be applied to it as well.

@John Pitcairn: The same could be said for a number of fields on the node edit form. Whether it's the authoring information, URL path settings, comment settings, menu settings, or the ability to create a new revision, I generally hide it all from my end users. Of all of these, the publish date is probably the one I'd be most inclined to allow them to edit directly. So unless we're ready to add permissions for all of these node options, I'm not comfortable singling out the publication date.

John Pitcairn’s picture

Yup, happy with the solution proposed in #80.

xmacinfo’s picture

The UX in #80 is impressive! Let’s get this in.

xmacinfo’s picture

Issue summary: View changes

Updated issue summary.

John Pitcairn’s picture

Don't let this delay approval: a question I know one of my clients will ask: if the first-published date is overridden in a later revision, is that a property of the node or of the node revision? In other words can we still recover the "real" first-published date?

jstoller’s picture

Right now the published date is a node property.

swentel’s picture

+++ b/core/modules/node/lib/Drupal/node/NodeFormController.phpundefined
@@ -258,6 +261,40 @@ public function form(array $form, array &$form_state, EntityInterface $node) {
+        'style' => array('display:none;'),

Why would we do inline styling here, that's not really nice if people want to override, this should go away completely. - edit - or use the 'element-invisible' class.

Note that #1751606: Move published status checkbox next to "Save" will probably go in this week which removes the 'published' checkbox completely - although that probably won't interfere *that* much I guess.

jstoller’s picture

@swentel: The 'element-invisible' class won't work, but I changed it to use the 'element-hidden' class.

Just so everyone understands what's going on here, the override checkbox is wrapped in a container with the 'element-hidden' class. This class sets display:none, so in the absence of Javascript, this form element will be completely hidden. Then I use the form API's #state attribute to trigger (via Javascript) the override checkbox to display when the publish checkbox is checked. It's a silly little trick, but it works.

Once #1751606: Move published status checkbox next to "Save" is committed, we'll need to adjust this slightly. In that case we'll want the override checkbox to always be visible when Javascript is supported, so we'll need to trigger off something that's always true. But let's cross that bridge when we get to it.

swentel’s picture

Oh, right fine enough as well, I knew it was something with 'element' :)

jstoller’s picture

@yoroy: I think it's your call now. Can we RTBC this?

dawehner’s picture

+++ b/core/modules/node/node.views.incundefined
@@ -383,6 +399,60 @@ function node_views_data() {
+      'id' => 'node_published_fulldate',
...
+      'id' => 'node_published_year_month',
...
+      'id' => 'node_published_year',
...
+      'id' => 'node_published_month',
...
+      'id' => 'node_published_day',
...
+      'id' => 'node_published_week',

Instead of using plugin IDs which does not exists yet, you should probably use the ones coming from #1893906: Move views argument date handlers from node module

jstoller’s picture

@dawehner: I'm no views expert, but won't that break this patch? It's a trivial change to make, but shouldn't I wait until that patch is committed before I go changing this one? There's no guarantee what order they'll be committed in, after all. If I'm wrong and it's safe/recommended to alter this patch now, then let me know and I'll make the change.

dawehner’s picture

It seem so to, as the other patch is already RTBC, that it will committed before.

Not sure whether I described that correctly, but the code from above simply does not work at all ;)

jstoller’s picture

This has the Views fixes requested in #89.

dawehner’s picture

This fixes looks good!

jstoller’s picture

@yoroy: Are you OK with the interface changes shown in #80? If so, then I think we're good.

marcingy’s picture

No issues from me about rtbc'ing this now it has usability review assuming yoroy is happy that is!

jstoller’s picture

yoroy’s picture

FileSize
33.16 KB

I still find it unsettling that when checking the 'Published' checkbox this additional options shows up. You check the box to mark the content as published. Not to change the first publication date. I understand that that's when the option becomes available, but just checking the 'Published' checkbox does not mean there's an intent to change the 'first published' date.

Also, I worry about a mental clashing of concepts with scheduler-style modules, especially when this 'first publised' option gets shown when the node hasn't been saved yet. Can we offer this option only after the content has been published?

**Edit: updated wireframe in next comment**

yoroy’s picture

FileSize
45.27 KB

Forgot last step in wireframe.

John Pitcairn’s picture

Not showing the published date until after the publish event has actually occurred seems like a win. But any kind of editable date field here definitely implies a scheduler. What about either:

A - not allowing a first-published date to be set which is in the future, or
B - just display the original first-published date, and leave making it editable to contrib?

jstoller’s picture

If you need to input custom publication dates, then there is a very good chance you'll want to input the date prior to actual publication. At least that's what I found when I implemented this feature in the past using field hacks. So hiding the field until after a node is published doesn't make sense to me.

When doing this in the past I've reset the publication date to the current date on publication, if it was set to a future date. We could do that here, but I didn't want to remove flexibility unless it was strongly desired. Are we sure that users will never have valid reasons for setting future publication dates? If so, then I could add something to the validation function that takes the minimum of the publication date field and the current time.

I would really rather not have to pull the UI component of this patch. I think it's going to be very important moving forward. If we look at #1892744: Use pulished date, instead of created date, for default node listings as the end goal, I think we're going to want to allow editing of the publication date for the same reasons we now let users edit the creation date. So I'd like to find a palatable UI now if we can.

Remember, we've had an editable date field on the node edit form forever. Has there been any problem with users thinking that's a scheduler, or thinking that field is required? Maybe there has, but before I posted #1892762: Alter or remove "Authored on" field on the node edit form I didn't see anyone calling for it to be hidden or removed. I realize that there are some differences between this field and that one, but we're also taking more precautions.

Finally, don't forget about #1751606: Move published status checkbox next to "Save". All indications are that it will be going into D8 soon and once that patch lands the publish checkbox goes away, so UIs like that in #98 will not be possible.

Are there any string changes we can make that might mitigate the scheduler issue?

yoroy’s picture

Yes, we've had an editable date field on the node form forever. It's also been quite well hidden all the time.

- I still think this should be a link, not a checkbox. Ideally, a checkbox is used for a on/off type setting. A link would be less UI chrome and better convey the nature of the interaction: you click the link because you want to customize this, so the resulting extra UI elements are less of a surprise.
- How do you think this feature should look when #1751606: Move published status checkbox next to "Save" is in? Since this is indeed the state we're working towards I'm still very uncomfortable with adding this "temporary" UI.

Current proposals put thing very prominently in sight around the arguably most important functionality of a CMS: getting stuff published to the internets. Right now, it clutters that part of the UI too much. We have to be very picky here.

jstoller’s picture

When #1751606: Move published status checkbox next to "Save" gets in I would leave this field exactly where it is now, hidden under the publishing options pane. I might even drop it to the bottom of that pane. I would absolutely not move it under the new drop button. And once the publish checkbox goes away, this pane will be decidedly less important. That leaves the published date field nearly as we'll hidden as the created date field. More so, given these extra protections we're trying to put in place.

jstoller’s picture

Well, #1751606: Move published status checkbox next to "Save" has now been committed. It looks like it not only disposed of the publish checkbox, but it also changed "Publishing options" to "Promotion options," so this field no longer really fits there. With this in mind, I'm now recommending that we move the published field directly under the "Authored on" field, within "Authoring information." I think this new context will largely remove the UX problems we've been struggling with.

jwilson3’s picture

So, assuming #103, could the "Authored on" field (created date field) simply be replaced by "Published on" (published date field) and let contrib modules deal with exposing the created date? Having two editable date fields creates a UX quagmire for the most common publishing use case (which only display one date on the front end) and will be the source of lots of confusion.... "Wait, which field should I edit to change the display date on the front end?"

jstoller’s picture

That would be fine by me! In #1892762: Alter or remove "Authored on" field on the node edit form I suggested removing the created date field, but that's contingent on #1892744: Use pulished date, instead of created date, for default node listings also getting in. We could try to do it all in this issue, but I thought it would be easier to break it up into separate chunks.

jstoller’s picture

This patch now replaces the old "Authored on" field with our new "First published on" field, keeping it hidden under "Authoring information." It also changes the default front page node listing and the default front page View to sort on the publication date. Likewise, it changes the node submission information to display the publication date.

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-106.patch, failed testing.

xmacinfo’s picture

“Authored on” and “First published on” does not mean anything and are confusing.

Do you mean the “created” date? Or the new “published” date?

Please remove any confusion and use simple and understandable lingo. Also think of translation issues when something is not clear, translation will add another degree of uncertainty.

We should stick to Created [date], Modified [date] and Published [date].

jstoller’s picture

@xmacinfo: These are UI changes, so I referenced the labels of the form elements in the UI. I'm sorry if that caused confusion. For the record, the created date is still there and works as expected. I just removed the form field which allowed for its customization on the node edit form. In its place I've added a field which allows users to customize the published date.

jstoller’s picture

Status: Needs work » Needs review
FileSize
4.36 KB
33.83 KB

I knew that was too easy. Hopefully this will fix the test errors.

Status: Needs review » Needs work
Issue tags: -Needs usability review, -Usability, -DrupalWTF, -workflow, -API addition, -VDC

The last submitted patch, published-timestamp-1838918-110.patch, failed testing.

jstoller’s picture

Status: Needs work » Needs review
Issue tags: +Needs usability review, +Usability, +DrupalWTF, +workflow, +API addition, +VDC
jstoller’s picture

Here's a screenshot of the new field in it's new home. The form looks the same as it did pre-patch, except for the label text. I think by removing the second date field and placing the this one in the context of "Authoring information," instead of "Publishing options," we remove most opportunities for confusion.

Screenshot_1_28_13_10_03_PM.png

xmacinfo’s picture

I still don't understand that “First published on” label. Is this the creation date, or the new publication date?

When creating a node, it may not be published at the same time of its creation.

Last saved means last modification, so modification date. That one is fine.

So is First published on the new publication date? If so, why do we let the end user changed it's value? Because changing the value would not make it First published on.

If First published on is the creation date, well, change the label back to Creation.

Please remove any confusion and use simple and understandable language. Also think of translation issues when something is not clear, translation will add another degree of uncertainty.

xmacinfo’s picture

Status: Needs review » Needs work

As per my previous comment.

jstoller’s picture

Status: Needs work » Needs review

I'm afraid I still don't understand your confusion. The "First published on" field means exactly what it says it means. Barring any user interference, this date is set automatically the first time a node is published and maintains that same value for the life of the node, no matter how many times it is subsequently published or unpublished. It is quite literally the date the node was first published. That said, there are many use cases where one might want to manually change this date, so we allow it to be altered through the UI, just as we now allow users to change the created date.

For the record, this field never said "Creation date." It always read "Authored on," which is incredibly vague. With this patch we are keeping the created and modified dates fixed, as a historical record, which IMHO is how they should be. Then we're providing a more mailable published date to use for sorting in lists. So, if I'm posting an article that was published in 1982, I can note that in the publication date and it'll be listed accordingly. Or if I want to reset the published date when I make some edits, I can do that too.

So, if not "First published on" then how would you recommend we label this field? What would better imply that this is the date of the node's initial publication?

jstoller’s picture

Issue summary: View changes

Link to follow up issues and latest screenshots.

John Pitcairn’s picture

The problem is that "publish" has years of accumulated meaning in Drupal. I'm not sure there is a useful synonym however...

jstoller’s picture

I think the real problem is that, prior to this patch, "published" was sometimes used to mean "created," even though they are two totally separate things. With this patch, published means published. Drupal veterans will figure it out (and rejoice at the new functionality) and Drupal newcomers will just get it. I think we would be doing ourselves a disservice if we tried to find a synonym. We're calling it what it is and that's a good thing.

xmacinfo’s picture

Status: Needs review » Needs work

Authoring something = creating something, hence Authoring on == Created on. This is specially true in the content creation industry, where the author creates content.

Changing “authoring on” to “published on” is bending their definitions of in the English language.

The problem is within Drupal since its beginning, where content publication was done at the same time as it creation. One flag is missing 'publication date', so users often changed the 'creation date' manually through the UI. We need a 'publication date' in the database.

On a content management system, or publication-centric system used in newspaper, for example, creating content did not mean publishing the content. An article might be written one day and published the day later.

So until the database as one more row in the node table (we currently have created and changed date), we should be warry about using any published on date.

Let's add a new “published” date row in the node table.

But for now, the label should either be:

- Created on
- Authored on

webchick’s picture

....?

That's what this patch does...?

jstoller’s picture

Status: Needs work » Needs review

@xmacinfo: You seem to be terribly confused. If you look at the patch, or read the issue summary above, you'll see that this patch does add a "published" column to the {node} table, in addition to the existing "created" and "changed" columns. Then, on the UI side, it removes users' ability to edit a node's created date, replacing that with a field for editing the node's published date. Furthermore, it updates the default node listings in Drupal so they will sort on this new published date, and it changes the submission information displayed on nodes to use the published date, instead of the created date. As I said, published really does mean published here.

@yoroy, et all: Now that I've moved the field to a new location, are you OK with leaving it exposed? I think I can safely say that this does nothing to diminish the UX from its current state.

xmacinfo’s picture

@webchick: This patch merges the creation date with the published flag and add a new published date in the database.

+++ b/core/modules/node/node.install
@@ -114,6 +120,7 @@ function node_schema() {
       'node_changed'        => array('changed'),
       'node_created'        => array('created'),
+      'node_published'      => array('published'),
       'node_frontpage'      => array('promote', 'status', 'sticky', 'created'),

This is a huge UX improvement!

But I fail to see which field is displayed here under the First published on field (created or published).

The proper label discussion is very minor compared to the large usability and richness of that this patch brings to Drupal.

xmacinfo’s picture

Issue summary: View changes

Updated issue summary.

jstoller’s picture

Issue summary: View changes

Updated issue summary.

jstoller’s picture

I've updated the issue summery, now that #1892762: Alter or remove "Authored on" field on the node edit form and #1892744: Use pulished date, instead of created date, for default node listings have been rolled into this issue. I also included the screenshot from #113.

@xmacinfo, I'm not sure how much clearer I can be. The "First published on" field manages the published date. That's why it uses the word "published" in the label. It is exactly what it says it is.

marcingy’s picture

Now that created is gone it remove the UI elements that I saw could cause confusion (note am I not a ux person in anyway shape or form). It would be a shame if this patch missed the code freeze because of bike sheding.

jstoller’s picture

jstoller’s picture

What else do we need to do to get this patch committed? We're already into February and I'd rather not push it to the last minute. Can we mark it RTBC?

jwilson3’s picture

I really hate stirring the dust on this, but I'm trying to think of publishing workflow and I'm also now coming up short... please hear me out (and shoot me down if necessary ;) These observations could be moved to a follow up ticket, because I dont want this to block having this initial improvements getting in in the first place.

So, if not "First published on" then how would you recommend we label this field? What would better imply that this is the date of the node's initial publication?

I find the "First published on" label confusing for two reasons:

1) "First published on" when starting from a new content, and the field is empty, insinuates (incorrectly?) that if you populate the field with a date in the future upon first save of the node, it is scheduled to be published on a date in the future. Does this patch actually do this? If not, we might consider providing an additional sentence in the description text, when the item is new and the field has no value, that "Note: specifying a date in the future will not schedule this for publishing". This will leave room for a contrib module (or a follow-up core issue) to provide this extra workflow logic and change this description text text to say that specifying a date in the future will schedule the node for publishing.

UPDATE: I just thought about this again, and its less about the label, as the field in general.

2) "First published on" loses meaning with reality as soon as you change the default auto-populated value in a subsequent edit after having published the node for the first time. I understand the reasoning behind why the word "First" was added above, but I think that this is a red herring that makes things more complicated to understand and will generate more questions. To me, this is a simple problem with a simple answer: the fact that we are exposing this field as editable means there can only be one value, and by default, it is not updated in subsequent unpublish --> publish operations.

One possible solution to this would be to provide an additional sentence in the description text, when the item is not new and is unpublished but already has a published date, stating that the field is not automatically updated when clicking the save/publish button, and that it is exposed as editable for just this reason. This would leave room for a contrib module to eg, remove this extra text, make the field "click to edit" or hide it altogether, and provide the additional workflow logic someone may want to have automatically updated publish dates on subsequent content workflow edits.

Since these are just observations, I don't want to block progress, I'm not going to change this back to needs work unless someone else agrees with the sentiments here ;)

A final suggestion, in an effort to keep the field description text shorter, we could wrap the example date in an abbr (or some other more semantic field) and put the text "The date format is YYYY-DD-MM and -0800 is the time zone offset from UTC" as the *title* attribute, that appears when you hover the example date.

jstoller’s picture

I am all for editing that description text. However, I do no think it makes sense to do so at this point. All of the existing text is necessary to turn a text field into a date field and if you add more text then it makes the description way too long and unreadable. I would also oppose hiding important instructions in a title attribute. That just isn't a reliable way of communicating the instructions. As soon as a proper datetime field is supported in the form API we can convert this field to use it. Hopefully we can then dump most of the description text here. Then we can easily add in more text about the behavior of this field, but we should save that for a follow up issue.

IMHO, the field label is not a red herring, nor does it make things more complicated to understand. The intention of this field is to represent the first time content was published. We'll let you manually edit that timestamp, but it still represents the first time content was published (accurate or not). Just as now we let you manually edit the authored on date, but it still represents the date content was (supposedly) first created.

If anyone can suggest some simple edits to the description text that will further clarify things, without turning it into a novel, then I'd gladly update the patch. However, I would really rather not see this important patch die due to bike shedding about a few words in the field description.

jstoller’s picture

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-129.patch, failed testing.

jstoller’s picture

Hmm. I'm not entirely sure what's happening with that Forum block test. If anyone has any thoughts on how to fix this, I'd be happy for the help.

jstoller’s picture

Status: Needs work » Needs review
FileSize
34.33 KB

Well, here goes nothing.

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-132.patch, failed testing.

jstoller’s picture

Status: Needs work » Needs review
FileSize
34.58 KB

I think this is going to fix the test, but we should update Forum module to use the published date in a follow-up issue.

jstoller’s picture

Back to a green light! Now, can I get an RTBC? :-)

jwilson3’s picture

+++ b/core/modules/node/lib/Drupal/node/NodeFormController.phpundefined
@@ -41,7 +41,7 @@ protected function prepareEntity(EntityInterface $node) {
-      $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
+      $node->published_date = format_date($node->published, 'custom', 'Y-m-d H:i:s O');

+++ b/core/modules/node/node.moduleundefined
@@ -1012,6 +1012,14 @@ function node_submit(Node $node) {
+  if (!empty($node->published_date)) {
+    $node_published = new DrupalDateTime($node->published_date);
+    $node->published = $node_published->getTimestamp();
+  }
+  else {
+    $node->published = 0;
+  }

Why do we need to save the published timestamp in a formatted date that is apparently only used on the edit form? Could the translation from timestamp format into the form field format be done without the need for an additional public member on the $node object? What does having this duplicate information buy us?

jstoller’s picture

Re #136:
The short answer is, this is how the current creation date field is handled and I'm just duplicating that method. Does it hurt anything? Do we need to change it now, or can we save it for later refactoring?

jstoller’s picture

I don't claim to be an expert, but looking over the code again I think the use of $node->published_date makes sense as is. I would advocate for leaving it.

That said, I did notice some holdover code from the old created date field, so I've made some small adjustments.

scronide’s picture

For what it's worth, my personal opposition to this is because the majority of the workflow systems I build are entirely private, where private-to-public content publishing concepts simply don't apply. This proposal would background metadata that applies to most content and replace it with a permanent UI element that will be irrelevant, and forever blank, for many non-default content types. I'd rather this wasn't railroaded through on a whim.

It is incorrect to simply reuse the "Leave blank to use the time of form submission" text from the "Authored on" description. This happens to relate directly to the first functional problem with the patch that I can see: when I select "Save as unpublished" for a new node, the "First published on" date comes back filled with "1969-12-31 16:00:00 -0800". I haven't looked into it in depth, but I figure this is because the published_date is always being passed through format_date() in prepareEntity().

jwilson3’s picture

Status: Needs review » Needs work

so, NW, based on the issue brought up in #139, which seems sound, no?

jstoller’s picture

@scronide: I assure you this is not being railroaded through on a whim. I personally have thought about this issue for years and have been working on it here for nearly three months now. It is a real issue which needs to be addressed. In my opinion, even internal systems which don't publish content for the general public can still benefit from the concept of "published" content. It's just being published for an internal audience. And this in no way diminishes any existing metadata. In fact, I think it elevates the importance of the created date, since now it is more likely to actually reflect the date content was created. Plus, it is a lot easier to hide this feature from end users, if you don't want it, then it is to implement if you do.

As for the functional problem you came across, it may take a few days but I'll investigate that as soon as I'm able. If anyone has any thoughts, feel free to throw them my way.

jstoller’s picture

Status: Needs work » Needs review
FileSize
6.92 KB
35.26 KB
62.06 KB

OK. This patch includes the following changes:

  1. The bug noted in #139 has been fixed.
  2. {node}.published now equals NULL, instead of 0, if there is no published date.
  3. I no longer set $node->published_date in NodeFormController::prepareEntity (see #136).
  4. I reimplemented the changes from #92, which were somehow lost along the way.
  5. I made a minor change to the form field description text, noting "Leave blank to use the time of form submission when published."
  6. When viewing an unpublished node, the submission information will list the node's creation date if no published date has been set.

Here's an updated screenshot, just for fun:
Screenshot_2_5_13_9_10_PM.png

Status: Needs review » Needs work
Issue tags: -Needs usability review, -Usability, -DrupalWTF, -workflow, -API addition, -VDC

The last submitted patch, published-timestamp-1838918-142.patch, failed testing.

jstoller’s picture

Status: Needs work » Needs review
Issue tags: +Needs usability review, +Usability, +DrupalWTF, +workflow, +API addition, +VDC
jstoller’s picture

We're back to green! :-)
Any other concerns?

jwilson3’s picture

Status: Needs review » Needs work
+++ b/core/modules/node/node.installundefined
@@ -707,6 +713,97 @@ function node_update_8013() {
+      // See if the node has multiple revisions. If it does, use the revision
+      // timestamp. If not then use the node created date.
+      $revisions = db_query('SELECT COUNT(*) FROM {node_revision} WHERE nid = :nid', array(':nid' => $nid))->fetchField();
+      $published = ($revisions > 1) ? $record->timestamp : $record->created;

Can you clarify why you'd pick the revision's timestamp date as the published date when first processing and adding this new field to the database, but when a new revision gets created through Drupal's UI, you specifically do not update the published date.

Also, we've already got the node's first published revision timestamp stored in the temporary table. First, if there was only one revision, and the node's created date was not changed by hand, then the revision->timestamp and node->created should be the same value no? Could that logic be used instead of an extra query to get the number of revisions? Secondly, if there's more than one revision, and the first published revision's timestamp doesn't match that of the original $node->created date, then how can you be sure that you're picking the right date to put in the new published field? Does Drupal display the revision's timestamp (if it exists) in place of the created date on the front end for the $submitted data? From the non-developer site content administrator's perspective, this will have the effect that the custom created date that may have been specified on the node at some point is inadvertently changed/updated to some other seemingly random value.

jstoller’s picture

Status: Needs work » Needs review

As has been discussed earlier, this field is supposed to represent the first time content was published on the site. Therefore, unless someone manually enters a published date through the UI, I don't create a published timestamp until the content is actually published. Once created, that timestamp is then maintained indefinitely, unless purposefully changed by the user.

The problem when updating from D7 is that we don't really know when a particular article was first published. We're forced to make an educated guess about the site's intent for each node. So here are the current assumptions:

  1. We should only create a published date for nodes that are currently published, or have a previous revision that we know was published.
  2. If a node has multiple revisions, then we assume the timestamp of the earliest revision with status=1 represents the first time the node was published.
  3. If a node only has one revision, then we assume it is not being revisioned.
  4. If a node is not being revisioned, the revision timestamp will reflect the node's changed date (not it's created date), but Drupal prioritizes the creation date for this purpose, so we use $node->created instead of the timestamp.

Accepting that this is an inherently imperfect process, I think this logic is generally sound. That said, here are some alternate methods we could consider:

A) Ignore the revision count and instead look to see if the node type was set to save new revisions by default.

B) Ignore the revision timestamp and use the created date on all nodes that we know have been published at some time.

C) Ignore nodes' publication status all together and just set published to created on all nodes.

Personally I think our current approach is the best option, but I could change it if there's consensus in another direction. Option 'A' could work, but it won't catch nodes that use revisioning intermittently. Option 'B' would be easier to implement and resulting lists may match D7 more closely, but it is technically less accurate. Option 'C' would be completely inaccurate, but I leave it here as a possibility.

jstoller’s picture

Bump.

jthorson’s picture

Needs reroll ... conflicts with f6b4d4a22.

Affected files:
core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php
core/modules/node/lib/Drupal/node/NodeFormController.php
core/modules/node/node.install
core/modules/node/node.module
core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php

The NodeFormController and node.module changes could use a second set of eyes ... I'm admittedly guessing, since I haven't looked at the new DateTime piece, and wasn't sure if the fixed formatting in the published portion was done for a reason or not.

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-149.patch, failed testing.

jstoller’s picture

@jthorson, can you post an interdiff, so I can see what you've changed?

jthorson’s picture

@jstoller Not sure how to do that, if the original patch doesn't apply. That said, the conflicts were largely minor ... with the biggest change being that the date property is now a DateTime object instead of a string. NodeFormController.php and node.module are the only files that weren't absolutely trivial.

Edit: Long story short ... I only spent about 5 minutes on it; no real lost effort if you simply applied the reroll yourself. Most of the fails would be due to tests keying on the parameter which was replaced with $node->published; though I wasn't sure if your patch intended to replace the original parameter, or add a new one.

jstoller’s picture

Status: Needs work » Needs review
FileSize
8.11 KB
36.81 KB

I caught a few errors in #149 and (hopefully) fixed the testbot issues. Fingers crossed.

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-153.patch, failed testing.

jstoller’s picture

Status: Needs work » Needs review
FileSize
848 bytes
36.81 KB

Oops. Missed a couple references in the update function.

Status: Needs review » Needs work
Issue tags: -Needs usability review, -Usability, -DrupalWTF, -workflow, -API addition, -VDC

The last submitted patch, published-timestamp-1838918-155.patch, failed testing.

jstoller’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work
Issue tags: +Needs usability review, +Usability, +DrupalWTF, +workflow, +API addition, +VDC

The last submitted patch, published-timestamp-1838918-155.patch, failed testing.

jstoller’s picture

Status: Needs work » Needs review
FileSize
921 bytes
37.77 KB

I'm just shooting in the dark here, but I think this might work.

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-159.patch, failed testing.

jstoller’s picture

Status: Needs work » Needs review
FileSize
4.48 KB
41.41 KB

If anyone who actually understands this translation stuff wants to take a crack at this, I'd be grateful for the help. In the mean time, here we go with another wild guess.

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-161.patch, failed testing.

jstoller’s picture

Status: Needs work » Needs review
FileSize
802 bytes
41.56 KB

Still trying...

Status: Needs review » Needs work

The last submitted patch, published-timestamp-1838918-163.patch, failed testing.

yoroy’s picture

Issue tags: -Needs usability review

un-tagging

yoroy’s picture

Issue summary: View changes

Updated issue summary.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jonathanshaw’s picture

Version: 8.1.x-dev » 8.2.x-dev
jonathanshaw’s picture

Uploading again for testbot, no change from #163

jonathanshaw’s picture

jonathanshaw’s picture

Status: Needs work » Needs review

Sorry, being stupid, forgot to set to needs review. This will certainly fail.

The last submitted patch, 168: published-timestamp-1838918-163.patch, failed testing.

jonathanshaw’s picture

Status: Needs review » Needs work

https://github.com/ueberbit/publication_date has a contrib solution to this that uses a translatable non-revisionable basefield to deliver the same result as this patch, but in a way that can be applied to any entity.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

richard_productowner’s picture

Hi, Has this issue died? Seems kinda odd to me not to have this in core given that it's a basic requirement for editorial sites which work on content and revise it in advance of publication. The Publication Date module hasn't moved out of Beta so this requirement still seems essential to me.

moshe weitzman’s picture

We have content moderation in Drupal core now so the problem space gets even more complex. Until its solved, I suggest creating a regular Publish Date field on your entities and manually setting a value, or add some code to programmatically set it. This would all be done by a Contrib module as well.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

maxilein’s picture

jstoller’s picture

Assigned: jstoller » Unassigned

I didn't realize this was still assigned to me! I think it's ridiculous this feature hasn't been implemented in core yet, but I don't have the bandwidth to fight for it now.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

taggartj’s picture

+ 1 for this as trying to do basic stuff like this kinda sucks.
$database->query("SELECT DISTINCT YEAR(published_at) from {node_field_data}"); .. :( is int field

So have to do ..
SELECT DISTINCT YEAR(FROM_UNIXTIME(published_at)) FROM node_field_data

AaronMcHale’s picture

@taggartj re #186, I get the impression you're doing that querying as part of a module, if so, and this is just a suggestion, but have you tried the Entity Query API, instead of directly querying the database? As that's a much more platform agnostic approach, since it abstracts away a lot of the raw database querying, and means you don't have to worry about the specific table structure that any given site might be using. Definitely the preferred option, especially if you're writing a module.


Anyway, this issue definitely needs an update, the last patch is quite out of date at this point.

The first thing I would think is, how does this impact the Workflow and Content Moderation modules? This seems like something those core modules would be very interested in: if I change the state from draft to published, the published date should update.

More generally, this might be a good candidate for providing a Interface and accompanying Trait in the Entity API, then applying that to the node entity type. That would be very relevant for going along with #2833378: Create an EntityCreatedInterface with accompanying trait to promote code reuse and standardization.

John Pitcairn’s picture

@AaronMcHale:

if I change the state from draft to published, the published date should update

But only the first time that state change occurs? If you unpublish then republish, should the published date change? That's probably business-logic specific. What should happen when content has been unpublished, gone through multiple revisions, and then finally been republished? How does that compare to content that stays published, has one or more drafts on top of that published revision, then an approved draft gets published?

To support an editorial revisioning/publishing workflow, maybe what we really need here is a first_published and last_published timestamp? The former might be a pure core responsibility, bur the latter a workflow/moderation module responsibility (including core workflow/moderation modules), but extendable by contrib workflow/moderation modules.

joachim’s picture

This should be rescoped to apply to any entity type that uses EditorialContentEntityBase.

jonathanshaw’s picture

#188:

To support an editorial revisioning/publishing workflow, maybe what we really need here is a first_published and last_published timestamp?

If the published_date field is revisionable, then that gives us sufficient storage for all possible use cases and we don't need the 2 fields. For example, normally the publication_date would simply be copied unchanged from the previous revision when creating a revision, and therefore be the original publication date; but if someone wanted to they could make custom logic to set it to null when the entity is unpublished and reset it when the entity is republished.

If publication_date was revisionable, we could have 2 methods:
- getPublicationDate() which gets the publication date from the current revision.
- getOriginalPublicationDate() which queries the entities revisions and gets the publication date of the revision with the earliest publication date

John Pitcairn’s picture

That sounds near-ideal, though what if the entity is revisionable but some client-imposed business logic requires revisions are not created yet they still want to publish/unpublish and track both dates? Don't laugh...

jonathanshaw’s picture

though what if the entity is revisionable but some client-imposed business logic requires revisions are not created yet they still want to publish/unpublish and track both dates?

We only need to consider the 80% use case. For everything else, there's custom fields.

AaronMcHale’s picture

Re @John Pitcairn in #188: Those are all good questions that should be considered. Unfortunately I don't have any answers to those right now. One possible option that comes to mind would be for Content Moderation, providing configuration that allows setting how/when this field should be updated, e.g. configuration could allow choosing on which transition(s) the published date should be updated and if it should only be updated if it was not previously set. I guess that option could even just be done by the Node module itself for each content type, because even if the site doesn't have Content Moderation installed, Node still provides a basic published and unpublish option.

Having said that, I think this issue should just focus on getting the Entity API side of things implemented, then have a follow-up for Node/Workflow/CM specific aspects and interactions.

Re @joachim in #189: Yeah good point, that would be an interesting update hook. It would have to find all of the Entity Types installed on a site and update them appropriately. This is definitely something then that we should look to have as a Trait and Interface, which is included by EditorialContentEntityBase. I wonder if it should be part of or separate from #2833378: Create an EntityCreatedInterface with accompanying trait to promote code reuse and standardization, my gut feeling is separate since that's doing something slightly different.

Re @jonathanshaw #190: That sounds like a sensible solution, if the Entity Type supports revisions, then make it a revisionable field.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

dubcanada’s picture

What do we need to do to move this forward, I agree it is absolutely ridiculousness that a content/authoring first experience does not have a concept of a "published on" date. Updated on is nowhere near accurate for the vast majority of publications. Most people have resorted to implement this themselves.

So let's figure out a game plan to move this forward and get even a basic version into core.