Problem/Motivation

See original product management review at https://www.drupal.org/node/2755073#comment-11343377 for origin.

While Content Moderation module exposes a UI for setting content to various moderation states, such as "Draft" or "Archived," there is no corresponding UI for a content moderator who needs to approve / reject content in these states to get a list of relevant content. The out-of-the-box admin/content view only allows selection of "Published/Unpublished," neither of which are moderation states themselves, and both of can be inclusive of many possible moderation states.

Only published/unpublished

Proposed resolution

Many possible solutions were discussed, including making adjustments to the admin/content view directly to add a drop-down for Moderation State (not possible because this would be exposing experimental modules' data on a production/stable page), adding a new tab under admin/content along the lines of Comments, Files, and Media (which doesn't really fit, since this view is showing Content/Nodes, not a new "type" of content).

In the end, the solution that has sign-off from the UX + product management team is to mirror the pattern that the Comments view uses; expose a sub-tab for content moderation that shows items in a non-published state, and provide a drop-down there to filter by one or more Moderation States.

So the admin/content view continues to list all content as it always has; just now has been split into two tabs:

 Overview and Moderated Content

The second tab only lists content in a non-"Published" workflow state, to mirror the Comments approval view that this pattern is based on:

Moderated content view

If the view is empty, it displays the following text:

No moderated content available. Only pending versions of content, such as drafts, are listed here.

Remaining tasks

User interface changes

The view at admin/content now has two sub-tabs: "Overview" (the original view) and "Moderated content" (the new view). The views are as pictured above.

API changes

None.

Data model changes

None.

Original report by webchick

See original product management review at https://www.drupal.org/node/2755073#comment-11343377 for origin.

One of the original must-haves identified in this initiative was the requirement of a View that allows content moderators to actually... moderate content. ;) Because without that, people within the content approval flow get hard-blocked and can't actually "do" anything, because there's no way (without engaging the services of a Views Master™) to get a list of content in a Draft state:

Only published/unpublished

The preview screenshot at https://www.drupal.org/files/issues/Screen%20Shot%202017-08-14%20at%2012... looks great; we just need to either apply that to the default Content view when Content Moderation (or Workflow or whatever makes sense) is enabled, or if that's too hard, add a "Moderate" or something sub-tab to that view that exposes the filter.

We can go over this on tomorrow's UX call if you'd like.

CommentFileSizeAuthor
#105 Screen Shot 2018-01-15 at 12.26.05 PM.png174.7 KBwebchick
#105 Screen Shot 2018-01-15 at 12.26.14 PM.png156.26 KBwebchick
#103 interdiff-103.txt1.39 KBamateescu
#103 2902187-103.patch37.26 KBamateescu
#96 interdiff-95.txt620 bytesamateescu
#96 2902187-95.patch37.23 KBamateescu
#94 Screenshot from 2018-01-13 08-53-03.png39.87 KBManuel Garcia
#93 2902187-93.patch37.27 KBtimmillwood
#91 interdiff-91.txt3.12 KBamateescu
#91 2902187-91-combined.patch91.56 KBamateescu
#91 2902187-91.patch38.24 KBamateescu
#87 admin-content-moderated.png120.8 KBwebchick
#86 admin-content-moderated-empty.png134.32 KBwebchick
#86 admin-content-moderated2.png175.61 KBwebchick
#86 admin-content2.png204.04 KBwebchick
#84 2902187-84-combined.patch72.72 KBamateescu
#84 2902187-84.patch38.22 KBamateescu
#82 interdiff.txt2.05 KBamateescu
#82 2902187-82-combined.patch106.13 KBamateescu
#82 2902187-82.patch71.56 KBamateescu
#79 moderated-blocks.png34.81 KBamateescu
#79 interdiff.txt35.2 KBamateescu
#79 2902187-79-combined.patch106.14 KBamateescu
#79 2902187-79.patch71.64 KBamateescu
#73 2902187-73.patch39.03 KBSam152
#73 2902187-73-combined.patch75.32 KBSam152
#70 admin-content-node-moderated.png129.35 KBwebchick
#70 admin-content.png186.6 KBwebchick
#66 interdiff.txt7.97 KBamateescu
#66 2902187-66-combined.patch86.69 KBamateescu
#66 2902187-66.patch38.94 KBamateescu
#63 interdiff.txt1.7 KBamateescu
#63 2902187-63-combined.patch80.03 KBamateescu
#63 2902187-63.patch32.27 KBamateescu
#59 interdiff.txt3.8 KBamateescu
#59 2902187-59-combined.patch80.02 KBamateescu
#59 2902187-59.patch32.26 KBamateescu
#50 Screenshot from 2017-08-16 14-07-50.png94.08 KBtimmillwood
#50 2902187-50-combined.patch79.24 KBtimmillwood
#50 2902187-50.patch31.99 KBtimmillwood
#50 interdiff-2902187-50.txt7.8 KBtimmillwood
#40 Screenshot from 2017-08-16 08-08-31.png85.13 KBtimmillwood
#39 2902187-39.patch63.88 KBtimmillwood
#39 interdiff-2902187-39.txt4.45 KBtimmillwood
#37 moderated-content-revisions.png28.55 KBamateescu
#37 interdiff-37.txt15.52 KBamateescu
#37 2902187-37.patch61.68 KBamateescu
#36 interdiff-36.txt422 bytesamateescu
#36 2902187-36.patch58.41 KBamateescu
#35 content-overview-with-moderated-content-tab.png51.21 KBamateescu
#35 moderated-content-fallback.png26.77 KBamateescu
#35 interdiff.txt7.26 KBamateescu
#35 2902187-35.patch58.83 KBamateescu
#31 Screenshot from 2017-08-15 21-07-25.png78.52 KBtimmillwood
#31 2902187-31.patch52.36 KBtimmillwood
#31 interdiff-2902187-31.txt6.34 KBtimmillwood
#24 2902187-24.patch53.85 KBtimmillwood
#24 interdiff-2902187-24.txt7.56 KBtimmillwood
#23 Screenshot from 2017-08-15 17-09-08.png80.66 KBtimmillwood
#23 2902187-23.patch51.02 KBtimmillwood
#18 Screen Shot 2017-08-15 at 8.21.30 AM.png45.59 KBwebchick
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

webchick created an issue. See original summary.

jibran’s picture

Issue tags: +VDC

How about adding a secondary tab to the content page just like comments page instead of a new primary tab? I believe we add a primary tab for media as well. We'll end up having too many primary tabs.

Bojhan’s picture

Title: Need to provide a way out-of-the-box for content moderators to moderate content » Provide a way for users to moderate content
Sam152’s picture

Title: Provide a way for users to moderate content » [PP-1] Provide a way for users to moderate content
Status: Active » Postponed
timmillwood’s picture

Status: Postponed » Needs work

I think postponing this is misleading, yes it depend on #2862041: Provide useful Views filters for Content Moderation State fields but needs a lot of work if we're going to get Content Moderation stable this week.

timmillwood’s picture

I've been looking at options here, and it doesn't seem we can alter the views.view.content view shipped with Node module, so we'd have to provide our own. Do we provide one for Node and Block? What about Media?

Do we provide one view at "/admin/content/moderated" and one view at "/admin/structure/block/block-content/moderated"? Would they be the same as the default views, just with the added "Moderation state" exposed filter?

plach’s picture

Any chance we can leverage optional fields/filters as we do with language in the content overview? The language column and filter are hidden until the Language module is enabled. I don't remember the technical details though, so I'm not sure it's feasible for CM.

jibran’s picture

I think we should create new view under admin/content/node something like admin/content/node/moderate and we can make it a secondry tab. That way we can add it to any list builder without cluttering the admin menu.

plach’s picture

Anyway, regardless of the route we choose, separate view or content or view, Angie mentioned content so we should stick to nodes, I'd say.

xjm’s picture

Title: [PP-1] Provide a way for users to moderate content » Provide a way for users to moderate content

The commit freeze for 8.4.0-beta1 is this morning, so there should not be any additional feature additions this week (or to 8.4.x at all).

Edit: I can see how it is important. But we should not operate under the assumption that we're going to rush and not sleep for 72h and land a new view for a user page, or delay the beta.

xjm’s picture

Version: 8.4.x-dev » 8.5.x-dev
Status: Needs work » Active

WRT the above about nodes, yes, I'd recommend restricting the scope to a node view to start as I think that's probably what users will expect as the 80% usecase. Other additional moderatable things could be feature additions in later releases, if desired.

This is really a minor-only change, which currently means 8.5.x, so setting accordingly. Also setting to active since there's no patch. Maybe we would backport it if it's the only thing at all blocking content moderation from being stable, if the product team thinks it can't be stable without this at all, but we would make that decision after commit. (However, if it's a must-have, getting it into 8.5.x at least is what we ant regardless.

timmillwood’s picture

Title: Provide a way for users to moderate content » [PP-1] Provide a way for users to moderate content

This is still technically postponed on #2862041: Provide useful Views filters for Content Moderation State fields but I don't want to put off people working on it, and we don't have a "Postponed (active)" or "Postponed (Needs work)" status.

It would be devastating to not see Content Moderation and Workflows stable in 8.4.0 because of this issue.

xjm’s picture

It would be devastating to not see Content Moderation and Workflows stable in 8.4.0 because of this issue.

@timmillwood, I'm concerned by this statement. The requirement for both modules is that they be beta, which they already are. There's no risk there. It would be cool for them to be stable, but since that's only something we started considering in the past week, why would it be devastating for them to not be?

But the initial feature deadline for 8.4.x is already two weeks ago and this issue did not even exist then. We used to burn people out around the beta by constantly delaying and delaying and adding all kinds of exceptions for issues that might never be done, and it was bad, and we don't do that anymore on purpose. Beta is supposed to be a hard deadline across the board to be fair to everyone.

However, it also should not matter I hope in terms of the feature itself. If the view needs to be added, then it will need to be committed to the minor development branch (currently 8.5.x) at some point.

TLDR, I think it's worth focusing on regardless, but the deadline has already passed for the beta so don't stay up nights or anything. My recommendation is to work on the feature and let committers sort it out after commit.

xjm’s picture

Also note that Workflows can be stable regardless as far as I understand since this view would be added to Content Moderation. So even if the product team thinks we can't mark Content Moderation stable without this, Workflows is not affected.

timmillwood’s picture

Assigned: Unassigned » timmillwood

I believe Workflows is waiting on #2899553: Architectural review of the Workflows module (documentation cleanups) and then yes, we can get #2897130: Mark workflows module as stable in to make Workflows stable.

We have been working for months under the impression we were working towards Content Moderation being stable in 8.4.x because it would've been experimental for 1 year. It seems like such a tough blow to not make it stable after such a focussed effort from many many people. This also allows us to move on to other aspects in the initiative such as Workspaces.

It sounds like #8 is a good approach, I am working on a patch for this now.

xjm’s picture

Thanks @timmillwood.

We have been working for months under the impression we were working towards Content Moderation being stable in 8.4.x because it would've been experimental for 1 year. It seems like such a tough blow to not make it stable after such a focussed effort from many many people. This also allows us to move on to other aspects in the initiative such as Workspaces.

Once it's done, it's done, regardless of which branch it's done in. It could still be marked stable in 8.5.x as of Friday. I am not sure how it could have the impression for months; you and I discussed it back around 8.3.0 and agreed that it needed to be beta by this release. I made this change to the roadmap at your request: #2755073-74: WI: Content Moderation module roadmap

Looking at Angie's screenshot, I'm wondering if this actually something where we should be changing the default core admin/content view itself (adding a filter) after Content Moderation is stable and as part of providing it in Standard. Perhaps overriding the route or such. "As an administrator, I expect to be able to list content in all moderation states as part of a single administration screen." Having a different tab I need to look at to see a subset of some nodes seems like bad UX, especially since it will be the same-but-different view it is at admin/content.

We can't change admin/content before Content Moderation is stable though. Adding a default view itself is trivial, but once we add it as part of a stable release, at least some sites are stuck with it because after installation, it's the site's config and not CM's. The site owner can choose to configure the view differently, so we cannot overwrite it or change it once installed. We could only change it for sites that install it later.

So, I'd encourage us to not rush this issue just because we want to meet a deadline (that has already passed), and compromise on the correct user experience.

webchick’s picture

This isn't a "feature"... this is a gaping hole in the basic functionality, it was identified back in June 2016, and it was supposed to block initial commit of the Workflow functionality in the first place. I agree 300% that I would not want it to block Workflow / Content Moderation from becoming stable in 8.4 over this. That team has kicked ass and taken names, and it would be a huge win both for them and the community to ship 8.4 with stable workflow feature usable in production. But you literally cannot use the new functionality as a content moderator without some sort of solution here, hence my insistence. (In this respect, it's more or less a "critical bug" with Content Moderation, and IMO should qualify for backport.)

I'm +1 for not rushing the solution, though (further brainstorming is encouraged, however! :)). Like I said, let's discuss it on UX call today and come up with a solution with UX/product management buy-in, and code it up.

webchick’s picture

My 2 cents:

Given we can't make adjustments to the admin/content view prior to the module becoming stable (makes sense), then probably the simplest thing that can possibly work is @jibran's suggestion of replicating a similar pattern we have for comments:

Separated into published vs. unpubllished

Maybe something like "All content" / "Content awaiting moderation." It's not quite the same as Comment's split, because the main "Content" view will show all content, including content awaiting moderation/unpublished vs. just published/unpublished, but that seems like the most straight-forward thing, which is validated by an existing core pattern. It's also a pattern we can re-use as other things become moderatable and need similar views exposed: taxonomy terms, blocks, etc.

And, if we find that secondary tabs are confusing and impossible to find (spoiler alert: they are :P), we can adjust this for both nodes and comments at the same time in a future release, since they're both using the same pattern.

xjm’s picture

Category: Task » Bug report

(In this respect, it's more or less a "critical bug" with Content Moderation, and IMO should qualify for backport.)

Well, even with bugs, if the change introduces disruption or breaks semver, we only add it in a minor release generally, even sometimes for criticals if we think it's actually disruptive: https://www.drupal.org/core/d8-allowed-changes#minor However, I can see how we should categorize this as a bug, so marking it as such.

xjm’s picture

This isn't a "feature"... this is a gaping hole in the basic functionality, it was identified back in June 2016, and it was supposed to block initial commit of the Workflow functionality in the first place.

I am super confused; this seems like a brand new issue? But it sounds like maybe we just had misunderstanding between the product review and the initiative on what the scope of #2862041: Provide useful Views filters for Content Moderation State fields was.

@webchick, do you think that moving from sub-tabs to a filter on the view itself would be a blocker for adding it to Standard?

xjm’s picture

Hmm actually, I just remembered again why I think the tab pattern does not work. admin/content already has the "Published" and "Unpublished" bulk operation selector. Putting "Draft" on a different page seems to me like it would be extremely confusing.

webchick’s picture

No, the specific implementation doesn't matter (I mean, it does from the standpoint that it must pass the UX gate so can't be nonsensical :)); only the outcome, which is that content moderators can actually view a list of content in draft (or whatever).

And yeah, the new sub-issue was a request from the team to keep the other issue solely focused on the site builder (Views) experience, not the content author experience. Both were identified as must-haves in the original product management review linked from the top of the issue summary.

timmillwood’s picture

Status: Active » Needs review
FileSize
51.02 KB
80.66 KB

Once it's done, it's done, regardless of which branch it's done in.

Yes, it'll be stable, but not stable in a stable release.

I am not sure how it could have the impression for months; you and I discussed it back around 8.3.0 and agreed that it needed to be beta by this release.

Since March there has been a number of discussion it was stated (or maybe just implied) about working toward getting them stable in 8.4.0. Not as a requirement, but as a goal.

the simplest thing that can possibly work is @jibran's suggestion of replicating a similar pattern we have for comments

Here's a patch which does that.

timmillwood’s picture

FileSize
7.56 KB
53.85 KB

This update removes the status column from the table, because that doesn't make sense. It also adds a "Moderation state" column and "workflow" columns, both of these are sortable, and the workflow name links to the workflow.

timmillwood’s picture

The patch in #23 and #24 adds a hard dependency on Views, so either we add that dependency to content_moderation.info.yml, or we create a fallback.

The last submitted patch, 23: 2902187-23.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 24: 2902187-24.patch, failed testing. View results

webchick’s picture

Awesome. The only minor thing I'd do is move Moderation State before Language like it is in the Content view.

Is the (#) part of the comment moderation view title easy? If not, no worries.

timmillwood’s picture

Assigned: timmillwood » Unassigned

Unassigning from me for now.

It looks as though the failing test is due to the views dependency.

webchick’s picture

Reviewed this patch in UX meeting:

  • +1 to re-using the existing sub-tab pattern from Comments
  • +1 to moving Moderation state before Language
  • Too bad about Moderation state vs. Published state, but doesn't seem to be a way around it until after the module is stable.
  • Can drop the Workflow column in the view; it makes the table wider than it needs to be, and users can always add this back in if they need it.
  • Bulk actions are missing from the moderation view; however, given that actions include "Publish/Unpublish" this would add confusion;
    also since you're supposed to actually review the item before publishing it, so... ;) This is OK.
  • Title of tab and view should be "Moderated content" (we try to avoid verbs here).
  • The # from the comments view doesn't make sense here, because it's not personalized per-editor; the view shows all content that is moderatable, not just those in non-published states.

In summary:

  1. (hard-blocker) Fix whatever the problem is preventing the sub-tab from appearing on the Content view.
  2. (hard-blocker) Either add the hard dependency to Views or add a manual controller type as a fallback. (The thinking on the call was just to add the hard dependency for now and look to remove it possibly in a later release, but this is something that needs buy-in from the Content Moderation maintainers.)
  3. Drop the workflow column from the view
  4. Move the moderation state drop-down filter before Language field.
  5. Change name of page title + sub-tab title to "Moderated content"

We do those things, this issue is resolved. Whew!

timmillwood’s picture

Status: Needs work » Needs review
FileSize
6.34 KB
52.36 KB
78.52 KB

This patch drops the workflow column, moves the moderation state select list, updates the sub tab title, and adds a views dependency.

#30.1 - Sub-tab not appearing on "content" view still to do.

Note: This patch is a combined patch with #2862041: Provide useful Views filters for Content Moderation State fields.

webchick’s picture

Just confirming that the screenshot in #31 reflects what we talked about on the UX call, so has buy-in from at least myself, @yoroy, @jojototh, @clara, and @ckrina. So once we resolve that pesky tab invisibility bug, +1 for RTBC.

plach’s picture

Minor: would it make sense to rename the main tab from Content to Overview (or whatever we use in these cases). Otherwise we have two stacked "Content" tabs, which is not great.

DuneBL’s picture

patch #31 failed at some point on last 8.5 build:

patching file core/modules/content_moderation/config/optional/views.view.moderated_content.yml
patching file core/modules/content_moderation/config/schema/content_moderation.schema.yml
patching file core/modules/content_moderation/content_moderation.info.yml
Hunk #1 FAILED at 7.
1 out of 1 hunk FAILED -- saving rejects to file core/modules/content_moderation/content_moderation.info.yml.rej
patching file core/modules/content_moderation/content_moderation.links.task.yml
patching file core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php
patching file core/modules/content_moderation/src/ViewsData.php
patching file core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_state_filter.yml
patching file core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_state_filter_entity_test.yml
patching file core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_state_filter_revision_table.yml
patching file core/modules/content_moderation/tests/modules/content_moderation_test_views/content_moderation_test_views.info.yml
Hunk #1 FAILED at 8.
1 out of 1 hunk FAILED -- saving rejects to file core/modules/content_moderation/tests/modules/content_moderation_test_views/content_moderation_test_views.info.yml.rej
patching file core/modules/content_moderation/tests/src/Kernel/ViewsModerationStateFilterTest.php
patching file core/modules/system/tests/modules/entity_test/src/Entity/EntityTestNoBundle.php
amateescu’s picture

2. (hard-blocker) Either add the hard dependency to Views or add a manual controller type as a fallback. (The thinking on the call was just to add the hard dependency for now and look to remove it possibly in a later release, but this is something that needs buy-in from the Content Moderation maintainers.)

I wasn't quick enough to reply on the UX call when you asked me but I'm not buying the hard dependency on VIews at all :) So here's a patch that adds a manual fallback controller, whose implementation is really simple: just use the node view builder (which is also used as the default content list fallback) and switch the 'Status' column to a 'Moderation state' one. Of course, we have to do a bit more than that, like loading the latest revisions of the nodes instead of the default ones, but it's still fairly simple and good enough for a fallback, IMO.

This fallback controller also has a nice side effect that it fixes hard-blocker 1, the problem that was preventing the sub-tab from appearing on the Content view.

Here's how it looks:

And the main content overview tab:

amateescu’s picture

And it seems that I forgot why I wrote the patch above.. so we can remove the dependency :/

amateescu’s picture

After writing the fallback controller I noticed that its output was different than the one from the view, because the view was showing the title of the default revision instead of the latest one.

So.. hey, I just need to add the 'Is Latest Revision' filter provided by Content Moderation, right? Nope! Turns out that the moderated_content view was not even using revisions at all :(

I rebuilt the view starting from scratch and, sadly enough, we're now dealing with a whole new set of problems:

  1. The content type filter/field is not available from the revision tables (no idea why!) so I had to create a relationship to the base tables in order to get it, and.. surprise: it's not showing anything for a node with a pending revision

  2. The moderation state field: my content (two articles and a page) was created before enabling the Content Moderation module, and, after enabling it, I only edited one of the articles and created a draft revision for it (Test article 1 - draft). This means that I have no ContentModerationState entry for the article that was not updated (Test article 2), so it doesn't have any state. #2867312: Create a batch process to ensure entities that exist for newly moderated entity types get a corresponding ContentModerationState entity, so that views works. is still open..

  3. The 'Operation links' handler also needs to use the relationship to the base tables, and, unlike the content type case above, it's completely broken and the view is blowing up because of some fatal error. The upside is that this one is most likely the easiest to fix :)

With a fair bit of sadness, here's our moderated node revisions view:

amateescu’s picture

I also stumbled upon the initial issue that was opened to tackle this problem #2780613: Ensure that content in moderation can be found in the admin UI easily

timmillwood’s picture

This patch fixes #37.1 and #37.3.

I changed the relationship in the view to join on entity ID rather than revision ID, and I added a "content revision" version of the operations field to EntityViewsData.

timmillwood’s picture

Here's a screenshot to prove it with a list of draft (default revision), published, and draft (pending revision) articles.

timmillwood’s picture

The fix for #37.2 might be #2852067: Add support for rendering computed fields to the "field" views field handler, then we won't need the ContentModerationState relationship.

timmillwood’s picture

#37.2 is a particularly tricky issue, and we have two options.

  1. Keep the functionality as it is now, moderated entities only show up if they are saved after moderation is enabled.
  2. Show all entities, even if they aren't moderated, the moderation column would be empty of have a value such as "Not moderated".

Content Moderation stores the moderation state in the ContentModerationState entity. These only get generated when an entity is saved after Content Moderation is installed and after moderation is enabled on the entity type. We compute an initial value of the moderation state based on the publishing status, this can be used with #2852067: Add support for rendering computed fields to the "field" views field handler to list the moderation state for an entity before moderation is enabled, but the filtering works by an SQL join to the ContentModerationState entity tables, so filtering to show entities with no moderation state will not display the ones created before moderation is enabled, because there the state is computed and can not be queried.

DuneBL’s picture

#39 failed to be applyed on 8.5

...
patching file core/modules/content_moderation/tests/modules/content_moderation_test_views/content_moderation_test_views.info.yml
Hunk #1 FAILED at 8.
...

this leads to an error when going to content page:

ymfony\Component\Routing\Exception\RouteNotFoundException: Route "content_moderation.admin_moderated_content" does not exist. in Drupal\Core\Routing\RouteProvider->getRouteByName() (line 190 of core/lib/Drupal/Core/Routing/RouteProvider.php). 
Drupal\Core\Menu\LocalTaskDefault->getRouteParameters(Object) (Line: 310)
Drupal\Core\Menu\LocalTaskManager->getTasksBuild('system.admin_content', Object) (Line: 358)
Drupal\Core\Menu\LocalTaskManager->getLocalTasks('system.admin_content', 0) (Line: 94)
Drupal\Core\Menu\Plugin\Block\LocalTasksBlock->build() (Line: 203)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func('Drupal\block\BlockViewBuilder::preRender', Array) (Line: 376)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 448)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 490)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 47)
__TwigTemplate_f8a17f041581af9829850fd45db45c2b69d8b3a60b80408d416da5d23dbccb61->doDisplay(Array, Array) (Line: 432)
Twig_Template->displayWithErrorHandling(Array, Array) (Line: 403)
Twig_Template->display(Array) (Line: 411)
Twig_Template->render(Array) (Line: 64)
twig_render_template('core/themes/seven/templates/page.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('page', Array) (Line: 435)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 490)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 90)
__TwigTemplate_be8c7bbb9c824f2826368d7c8da984c6279779db72a67fd8056a00bb23b816f2->doDisplay(Array, Array) (Line: 432)
Twig_Template->displayWithErrorHandling(Array, Array) (Line: 403)
Twig_Template->display(Array) (Line: 411)
Twig_Template->render(Array) (Line: 64)
twig_render_template('core/themes/classy/templates/layout/html.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('html', Array) (Line: 435)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 147)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 574)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 148)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) (Line: 108)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 50)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 656)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
DuneBL’s picture

But more important, as already stated in "https://www.drupal.org/node/2862041#comment-12223325" when I try to add the moderation state field in a view, I got the following error:
The handler for this item is broken or missing.

Step to reproduce: (drupal 8.5)
1-edit content view
2-add the "moderation state" field from the "content" category (same problem with the revision category)
3-the error is popping up

timmillwood’s picture

@DuneBL - the moderation state needs to be added with a relationship to ContentModerationState until #2852067: Add support for rendering computed fields to the "field" views field handler lands.

timmillwood’s picture

Re #43: I can't replicate the issue on 8.5.x

DuneBL’s picture

Many thanks for checking...
I could remove the #43 problem after a drush cr (the devel flush cache button was not enough ?!?)
=>Sorry for having loosing your time.... maybe we should run something to apply the updated config file (ex: routing)?

regarding #45, I have added a relationship to ContentModerationState, but the problem stay... Anyway, I will wait the landing!

plach’s picture

@timmillwood:

Here's a screenshot to prove it with a list of draft (default revision), published, and draft (pending revision) articles.

This explanation makes me think that maybe we need the status column after all, otherwise how would a user know whether a node is actually visibile on the site in some form or not?

amateescu’s picture

@DuneBL, re #44: we have a dedicated issue for that: #2859381: Broken/missing handler for Moderation state field

timmillwood’s picture

If I've rolled these patches correctly the combined one includes patches from #2862041: Provide useful Views filters for Content Moderation State fields and #2852067: Add support for rendering computed fields to the "field" views field handler, where as the standard patch is just the bits this issue is adding, and the interdiff is the changes from #39.

Here I have:

  • Removed the relationship between ContentModerationState.
  • Linked the entity title to the entity.
  • changed the path from "moderate" to "moderated".
  • Added a filter to not show entities with no moderation state.

Updated screenshot:

timmillwood’s picture

Note: This still doesn't "fix" #37.2, nodes created before moderation is enabled will not show in the "Moderated content" view. If we remove the filter to not show entities with no moderation state it will show nodes created before moderation was enabled, but it will also show nodes without moderation enabled where the moderation state will be empty.

We could throw a warning in a DSM to say "Content added before moderation was enabled are not listed", this was an idea that came up when talking to @jojototh and @dixon_.

timmillwood’s picture

Another option I've been looking into is using COALESCE() to compute the moderation state if it doesn't exist. See #2862041-86: Provide useful Views filters for Content Moderation State fields.

timmillwood’s picture

Title: [PP-1] Provide a way for users to moderate content » [PP-2] Provide a way for users to moderate content

Even after my comments in #51 and #52, I'd be extremely happy for #50 to be committed, I just want to make sure all options were looked into.

timmillwood’s picture

Status: Needs review » Needs work

Just had a call with @webchick, she seemed happy with the patch from #50 but two changed need to happen:

  • Update the view to not show content in the "Published" state.
  • Update the empty text to explain clearer why there is no moderated content.
webchick’s picture

Yep. This highly mitigates the confusing side of the current behaviour; then you're only seeing things with a publishing workflow other than "We're done, it's live" and that content totally makes sense to a) have in a separate view, and b) for that view to be empty until/unless there is something that is in a non-published workflow state.

This solution is not 100% perfect, because Tim brought up the fact that you can have multiple "final" published states (as well as "final" unpublished states), but for the 80%+ (97%?) case, this should work. Those with severe edge cases can always tweak the view as needed.

hass’s picture

I'm happy to see 8.4 may becomes the first useable D8 release if moderation is stable, but "Content added before moderation was enabled are not listed" sound not really funny... that is like data loss. Why not running a migration of current content so it get's listed? How should people find their content otherwise?

timmillwood’s picture

@hass - you'll find it exactly where it was before you enabled moderation.

jojototh’s picture

@hass - ALL content will still show up at Content > Overview; MODERATED content only will show up at Content > Moderated content. There will be 2 secondary tabs at the current Content page. See screenshots above.

amateescu’s picture

Status: Needs work » Needs review
FileSize
32.26 KB
80.02 KB
3.8 KB

Here's an updated patch that takes care of both points from #54/#55.

The combined patch includes the latest patches from #2852067-58: Add support for rendering computed fields to the "field" views field handler and #2862041-90: Provide useful Views filters for Content Moderation State fields.

The last submitted patch, 59: 2902187-59.patch, failed testing. View results

xjm’s picture

If we make this view a sub-tab under admin/content, only users with "administer content" permission will be able to see this view. Is that its intended purpose?

webchick’s picture

Status: Needs review » Needs work

@yoroy and I reviewed this patch, and otherwise looks/works great from our POV. The only minor thing that came up is maybe adjusting the empty text from:

"No moderated content available. Only pending versions of the content, such as drafts, are listed here."

to:

"No moderated content available. Only pending versions of content, such as drafts, are listed here."

(Could be done on commit; it's just removing the word "the".)

As far as @xjm's question, it looks like this view hinges off the "view all revisions" permission, which looks to be incorrect. With that, you can get into an information disclosure vulnerability, where you can see the title of a node (revision), but when clicking into it get a 403. It should probably hinge off "View any unpublished content" instead, like the other workflow functionality does. But otherwise, yes, only seeing that tab with the "access content overview page" permission does make sense from a product POV.

amateescu’s picture

Status: Needs work » Needs review
FileSize
32.27 KB
80.03 KB
1.7 KB

@webchick, that's great to hear :)

Updated the empty text and changed the view and fallback route to use the 'access content overview' permission, which is also the one that's used by the main 'Administer content' view.

timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

Looks like all boxes are ticked. So we should be good to move to RTBC, although it is still postponed on the other two issues.

Bojhan’s picture

Wow, this issue moved fast :) Looking great!

My only suggestion would be, we can go even shorter to something like "No moderated content (e.g. drafts) available". But we can do that post commit too!

amateescu’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
38.94 KB
86.69 KB
7.97 KB

Assuming that @xjm's comment from #2862041-91: Provide useful Views filters for Content Moderation State fields was meant for this issue:

We are also missing dedicated test coverage for the new view. There should be test coverage for all the twists and turns this issue has gone down in terms of what to display. This is not the kind of test coverage that should be scoped to followps.

Here's full test coverage for the new view :)

Also let's not mark this issue RTBC with a combined patch with others that haven't landed yet, and please provide the no-test patches so it's easier to read what's part of this issue. Thanks!

No-dependency patches have been posted here in #50, #59 and #63 (the ones without "-combined" in the file name).

timmillwood’s picture

Wim Leers’s picture

I skimmed the issue, and it's not clear to me what this issue is blocked on, what this is actually doing and why the default /admin/content view is insufficient.

An IS update would do wonders — and I'm quite certain it'll help this issue get committed faster too :)

webchick’s picture

Assigned: Unassigned » webchick

Ok, attempting to do that.

webchick’s picture

Issue summary: View changes
Issue tags: -Needs issue summary update
FileSize
186.6 KB
129.35 KB

Ok, issue summary now updated according to the template. I believe all of that is correct, but might not hurt for one of the WI people to double-check.

Also, in the process of writing that, I re-reviewed the patch again. I noticed the path chosen for this new view was admin/content/node/moderated which seemed a bit odd (should be just admin/content/moderated to preserve "hackable" URLs). I thought that was because that "node" part of the URL was a wildcard and for blocks would be "custom-block" or something, except in looking more into that I discovered that this is just a standard view with a hard-coded path, which means we have the same "no way to moderate content" problem for custom blocks, which also can have workflows applied to them. :(

So, I really, really hate to do this, but is it doable to fix that as well in this issue, or should we spin off a (not "must-have") follow-up for that? (rationale: not an 80% use case, and people can easily clone this view if they need it, if it exists. it's making it from scratch that's so difficult.)

Btw, I'm more than happy to commit this patch one once it's ready, but can't do so without the two dependent issues being committed first, and those are really more framework manager-y. :(

webchick’s picture

Assigned: webchick » Unassigned
Issue summary: View changes

Tweaks + unassigning.

larowlan’s picture

Title: [PP-2] Provide a way for users to moderate content » [PP-1] Provide a way for users to moderate content

#2852067-69: Add support for rendering computed fields to the "field" views field handler has been committed and pushed to 8.5.x

One blocker down.

See comments over there in relation to this issue.

Sam152’s picture

Rerolling now one of the blockers has been resolved.

The last submitted patch, 73: 2902187-73-combined.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 73: 2902187-73.patch, failed testing. View results

webchick’s picture

Title: [PP-1] Provide a way for users to moderate content » Provide a way for users to moderate content
Issue summary: View changes
amateescu’s picture

Title: Provide a way for users to moderate content » [PP-1] Provide a way for users to moderate content

Almost jumped off my chair when I saw the title change here :) But the second blocker is actually #2862041: Provide useful Views filters for Content Moderation State fields, so back to PP-1 for a bit longer.

webchick’s picture

Oh, crap, I'm so sorry for the false hope! I was looking at the wrong issue.

amateescu’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
71.64 KB
106.14 KB
35.2 KB
34.81 KB

@webchick, thanks for the new issue summary and for reviewing this again :)

Updated the path for the moderated content view (and fallback) to admin/content/moderated.. not sure why we didn't do that in the first place.

Since one of the blockers is still not in yet, I'm ok with doing more work in this issue, so I added a view and a fallback for custom blocks as well, plus tests. The thing is.. moderating custom blocks doesn't really do anything useful right now, you can change moderation states on them all you want but it won't publish/unpublish them automatically until #2820848: Make BlockContent entities publishable lands, so maybe we can get that committed as well :)

Status: Needs review » Needs work

The last submitted patch, 79: 2902187-79-combined.patch, failed testing. View results

timmillwood’s picture

It was /admin/content/node/moderated because the standard content view is /admin/content/node although not sure why that doesn't resolve.

amateescu’s picture

Status: Needs work » Needs review
FileSize
71.56 KB
106.13 KB
2.05 KB

Forgot to change the path in the tests :/

webchick’s picture

Hm, wow. #2820848: Make BlockContent entities publishable is a whole entire can and a half of worms... :\

[Note: this just an opinion/question, not a decree]

Given that:

a) It's not even possible right now to unpublish a block until #2820848: Make BlockContent entities publishable goes in (which has an upgrade path, and thus is probably not something we'd want to target for 8.4.x at this late stage, given RC is in ~10 days)
b) Even if it is possible programmatically do to so (once that patch goes in), there's no UI for it until #2821174: Set and enforce publishing state on BlockContent happens, and there's no patch, let alone a spec, there yet
c) One of the goals of the Workflow team for 8.5.x (I think?) is to focus on #2725433: WI: Phase A: Use the revision API in more places as part of the underpinnings of getting Workspaces in, which is only going to exponentially increase the surface of these problems to more entities

...I'm wondering if the better approach is just to ship 8.4.x without the ability (at least in the UI) to put workflows on custom blocks at all (including both the setting at admin/config/workflow and this View), and tackle this problem space more holistically in 8.5.x where we have ~5 more months to hash out some of these implementation details.

Thoughts?

amateescu’s picture

None of my thoughts are going to override a release manager's decision, and you're probably right that it's very unlikely for #2820848: Make BlockContent entities publishable to get into 8.4.0 :/

So in the interest of keeping this issue shippable at any time, I've split the block_content parts of this patch to a separate issue: #2904997: Provide a way for users to moderate custom blocks

Bojhan’s picture

I will start picking up b), which should be resolvable.

Shipping without a UI sounds fine to me.

webchick’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
FileSize
204.04 KB
175.61 KB
134.32 KB

Since the issue this issue is blocked on is blocked on ;) release manager review atm, ran this patch through its paces one last time.

  1. Enabled Content Moderation / Workflows modules
  2. Created a Basic page + an Article with no workflows attached to them.
  3. Went to admin/config/workflow/workflows/manage/editorial and turned it on for Articles but not Pages
  4. Created an Article and saved as Draft

admin/content looks like this:

Shows the three nodes listed above.

admin/content/moderated (thanks for that) looks like this:

Shows just article draft.

If I edit the draft article and move it to published, the moderated content view now shows empty, as expected:

Empty text.

In other words, exactly what we talked about. :) GREAT work!! :D

So I would call this RTBC, even though of course it can't be committed until #2862041: Provide useful Views filters for Content Moderation State fields is in. Updated the issue summary to reflect the remaining blocker, and the splitting off of the custom block stuff.

webchick’s picture

FileSize
120.8 KB

Oopsie. Wrong screenshot.

timmillwood’s picture

Thanks for the review @webchick, I too see no reason to not put this in 8.4.x along with #2862041: Provide useful Views filters for Content Moderation State fields, also worth noting #2852067: Add support for rendering computed fields to the "field" views field handler was only committed to 8.5.x, so needs to be cherry picked to 8.4.x.

Then once done we can commit #2897130: Mark workflows module as stable and #2897132: Mark Content Moderation module as stable

jibran’s picture

#2797583: Dynamically provide action plugins for every moderation state change will allow bulk update the moderation state. We can add the bulk form to the views added here.

xjm’s picture

Status: Reviewed & tested by the community » Postponed

Let's mark this RTBC once the blocker is in so that committers (me) don't repeatedly look at a patch that's not actually committable. :)

amateescu’s picture

If some miracle happens and #2862041: Provide useful Views filters for Content Moderation State fields is committed in the next couple of days, this one should be ready as well, it just needs a few minor updates for the changes in that issue.

larowlan’s picture

Title: [PP-1] Provide a way for users to moderate content » Provide a way for users to moderate content
Status: Postponed » Needs work

Blocker is in!

timmillwood’s picture

Status: Needs work » Needs review
FileSize
37.27 KB

Here's a reroll fixing a conflict in ViewsData.

Manuel Garcia’s picture

This is so exciting!!
Couldn't help myself so I tested the rerolled patch:

  1. pulled latest 8.5.x, applied #93 and installed from scratch
  2. enabled content moderation module
  3. edited editorial workflow and enabled it for Articles
  4. used devel_generate to generate some articles
  5. edited the moderated_content view in search of errors, everything seems perfect, and the UI is working nicely

Anything we should be looking out while testing manually?

Manuel Garcia’s picture

I'm clearly late for this party, but from a user perspective, I see this inconsistency regarding the Archived moderation state, which I think this will confuse content editors:

  • On admin/content - an archived content shows with Status: Unpublished
  • On admin/content/moderated - it shows with Moderation state: Archived

Could it be a better approach if content_moderation instead of providing a new tab for its UI, took over the view on admin/content to:

  • Swap the Status column for Moderation state
  • Swap the Published status exposed filter for Moderation state filter

This way, it would all be under the same screen, no context switching etc.

Only problem I can see is what could happen if the specific site is already taking over this view, but then the site owner would be responsible for handling this situation I suppose.

amateescu’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
37.23 KB
620 bytes

@Manuel Garcia, this was discussed previously in #30, and we need to have the Content Moderation as stable before doing anything about it.

I looked through the patch as well and I found a small thing that needed to be changed, we need a different description for the view instead of the copy/pasted "Find and manage content." :)

This was RTBC before #90 and nothing really changed since then.

Manuel Garcia’s picture

Ah fair enough @amateescu - thanks for clarifying!

Berdir’s picture

+++ b/core/modules/content_moderation/content_moderation.routing.yml
@@ -1,3 +1,11 @@
+content_moderation.admin_moderated_content:
+  path: '/admin/content/moderated'
+  defaults:
+    _controller: '\Drupal\content_moderation\Controller\ModeratedContentController::nodeListing'
+    _title: 'Moderated content'
+  requirements:
+    _permission: 'view any unpublished content'

At least 50% of this patch is the non-views fallback. I assume we more or less only do that because of #2804195: Views does not create parent local task for a default local task.

Fine to unblock content moderation, but trying to resolve that other issue would IMHO be really beneficial for a lot of sites, because this is a pattern that can be re-used for site-specific administration views, we often have a number of views for specific node types and so on, which we either have to put in the primary local tasks (which gets annoying when they are all collapsed together) or add custom code that tends to break easily.

amateescu’s picture

At least 50% of this patch is the non-views fallback. I assume we more or less only do that because of #2804195: Views does not create parent local task for a default local task.

Nope, the non-views fallback is there just to provide a way to moderate content for sites that don't have views enabled :) See the second part ("In summary") of #30.

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
  1. +++ b/core/modules/content_moderation/config/optional/views.view.moderated_content.yml
    @@ -0,0 +1,817 @@
    +          perm: 'view any unpublished content'
    

    Should this consider 'access content overview' in some way?

  2. +++ b/core/modules/content_moderation/content_moderation.routing.yml
    @@ -1,3 +1,11 @@
    +    _controller: '\Drupal\content_moderation\Controller\ModeratedContentController::nodeListing'
    

    Pity we can't use _entity_list here and let EntityRouteEnhancer do the work we're doing in the ModeratedContentController? Would allow us to drop that class altogether. Can we get a follow up to make EntityRouteEnhancer more flexible - to support this type of use-case?

  3. +++ b/core/modules/content_moderation/src/ModeratedNodeListBuilder.php
    @@ -0,0 +1,124 @@
    +    foreach ($this->getEntityRevisionIds() as $entity_id => $revision_id) {
    +      $entities[$entity_id] = $this->storage->loadRevision($revision_id);
    +    }
    ...
    +    $query = $this->entityTypeManager->getStorage('content_moderation_state')->getAggregateQuery()
    +      ->aggregate('content_entity_id', 'MAX')
    +      ->groupBy('content_entity_revision_id')
    +      ->condition('content_entity_type_id', $this->entityTypeId)
    +      ->condition('moderation_state', 'published', '<>')
    +      ->sort('content_entity_revision_id', 'DESC');
    +
    

    didn't we add a dedicated method/api to entity query for loading the latest revision?

    can we use that here?

Berdir’s picture

2. I think this is the first time we've had that use case at least in core (adding additional list builders), not sure trying to generalize it is worth it without more use cases? And we would need to go much further than that, e.g. introducing a list_builders annotation with a nested array similar to form handlers but I'm not convinced yet that the complexity/impact is really worth (possibly deprecating the old key and so on..)

larowlan’s picture

Yep, happy for people to say 'not worth it' or discuss is further on a new issue, where the resolution might be 'not needed'.

amateescu’s picture

@larowlan, re #100:

1. It would be nice to also consider 'access content overview' but views does not support any kind of AND/OR permission grouping, so we can only specify a single permission.

In any case, 'view any unpublished content' implies more trust than 'access content overview' so I think we're good with using only that one.

3. We did but we can't use it here because this is an aggregated query on the content_moderation_state entity type, and we want the revision IDs of the *moderated* entities. We can however use the new loadMultipleRevisions() method :)

timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

Think we can go back to RTBC now.

Is #100.2 something that would be better handled in a follow up?

webchick’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +8.5.0 highlights
FileSize
156.26 KB
174.7 KB

Ok, set up a test site with Pages as non-workflow-managed content, Articles as workflow-managed content.

Per the spec outlined by the UX team, without the module enabled, the Content overview page (admin/content) just looks like normal:

Look at my content!

Once the module is enabled, and workflow enabled on one or more content types, it shifts to a "two-tab" model, same as the Comment overview page (admin/content/moderated). The view is restricted to only showing content that is in a workflow state that is not published, so that content authors can best focus on that content which needs attention:

Restricted view of content needing moderation.

In other words: everything working as intended. Hooray! :)

Sounds like the most recent concerns listed have either been addressed, or explained why they can't be addressed. We can always continue to improve the underpinnings here in follow-up issues, but for now, this looks to fulfill the requirements, and is the last remaining blocker to getting this sucker to Stable... Sooooooo....

COMMITTED AND PUSHED TO 8.6.x, and cherry-picked to 8.5.x. HELL YEAH! :D

  • webchick committed 8eac2a1 on 8.6.x
    Issue #2902187 by amateescu, timmillwood, Sam152, webchick, Manuel...

  • webchick committed 535d519 on 8.5.x
    Issue #2902187 by amateescu, timmillwood, Sam152, webchick, Manuel...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.