A year ago, I began the long odyssey of creating Assign Blame, a multi-user blog where I had editorial control over published content, but I didn’t intend to be the primary creator of content. This was a great idea, of course, except for the fact that nobody else wanted to be the primary creator of content either and as such, the site has languished since November; nearly six months, now, it’s sat, waiting. I haven’t bothered with it much, lately, because it’s still running under 4.6. Still, despite the site languishing, creating the proper tools to make that site work and contributing them back to Views has, in fact, been one of my driving desires.

I believe I now have the tools necessary to do what I want, so that I can share with everyone the method for doing what I want. And that, namely, is publishing content. Oh yes, Drupal can already do that. But I want to moderate content. Yes, Drupal can do that too…but not really. Unless, of course, you give your content moderators ‘administer nodes’ privileges and basically give them complete access to all content on the site. That’s hardly right. I wanted to be able to give editorial control of certain sections to people who were not necessarily site administrators.

The Tools

  • Views
  • Dashboard
  • Node Queue
  • Workflow
  • Actions
  • na_arbitrator
  • workflow_access
  • some custom code, which I’m calling publishing.module

That’s a pretty long list of tools. If you’ve been reading my previous articles, you already know what some of this stuff is for, and I don’t really need to get into how Views is used, and what Node Queue is good for. Workflow, however, is something I haven’t particularly talked about, and it is something that can be extremely useful, but currently lacks a little bit of support.

[Editor's Note: These patches have now been committed, and you should no longer need them. The text of the paragraph is left for reference.] First, you need to be sure to get my patches for Workflow. If they are not already committed, you need the comment history patch and the _submit patch. The latter patch lets it work with the na_arbitrator and workflow_access modules. Now those are bleeding edge access control modules but they do seem to work and need some good burn-in testing to get the wrinkles out.

The Recipe

  1. Install all of the above modules.
  2. Go to Workflow and create a new workflow. Call it Publishing unless you like something else more.
  3. Add the following roles: content author, editor. Attach the permissions from the publishing module to these roles.
  4. Don’t confuse the role, ‘content author’ with the ‘author’ role which means author of the node. All we’re really going to use ‘content author’ for is to control the ability to actually create the content.
  5. Add the following states: Draft, Review, Rework and Published.
  6. Allow the following transitions: (creation) => Draft: author. Draft => Review: author. Review => Rework: author, editor. Review => Published: editor. Published => Rework: Editor.
  7. Set the following permissions: Draft: author view/update/delete; editor view. Review: author view; editor view, edit, delete. Rework: author view, edit; editor view; Published: anonymous view, authenticated view. [nobody gets edit privs on published content].
  8. Edit the publishing module to ensure that the State IDs in the defines are the same as in your database.
  9. Create a user and give it author privileges. Go to the author dashboard and submit some content. Set it for review.
  10. Create a user and give it editor privileges. Go to the editor dashboard and review the content. Publish it.

Unpublished content isn’t visible on the system, so you don’t really have to worry about it. You can organize the content by whatever traditional means you like. In order to create the front page I like:

Create a node queue named Lead Articles. Give it a maximum of 3 or so.

Create a dashboard. In the top, use the dashboard to display only the article in the back of the lead article queue, and display the teaser. On the left side of the dashboard, display the remaining teasers. On the right side of the dashboard, use Views to display content by your favorite taxonomy categories.

AttachmentSize
publishing.module.txt8.98 KB

4.6?

Thanks for sharing this.

Sometimes, Drupal is needlessly difficult to use because non-coders can't wrap their heads around exactly how to use various modules together to accomplish what they want. I have always liked assignblame.com, so this article sharing the methodology used for building it is most useful.

Just one clarification: Do I need to use the latest 4.6 versions of the following modules? The last time I checked, na_arb and workflow_access seemed to be cvs only.

# Workflow [with my patches]
# Actions
# na_arbitrator
# workflow_access

I also assume the publishing.module will work on 4.6

No, this is 4.7 only

Sorry, it seems I wasn't actually clear.

This is bleeding edge stuff; you need 4.7 RC2 at least to get any of this to work.

nice one

quite cool. this might deprecate workspace.module and add lots of new possibilities. Very plone-like (in a good way).

we need some more thinking on dashboard.module. it is a good start but there has to be a more intuitive way. at one time we were going to let modules declare block regions but that never got in.

Dashboard module

we need some more thinking on dashboard.module. it is a good start but there has to be a more intuitive way. at one time we were going to let modules declare block regions but that never got in.

I agree completely. The dashboard module, really, is a hack whose primary purpose is just to make it easy to use the theme() functions to separate a space into 4 or 6 spaces. (There's a hidden dashboard-three theme function that I quietly added and never doc'd =)

There's a lot of different things that people would like to see in a dashboard. My initial vision did, in fact, involve giving lists of blocks and letting people place them in various areas. And maybe this is still a good idea. Especially with a decent drag & drop that makes it easy enough and intuitive to do.

But then I realized...not all content is in blocks. Maybe if dashboard existed that way, more and more modules would publish mini-content, but of course, organization would become an issue. (In a way, it already is. I often find myself wishing admin/blocks put the blocks in collapsible fieldsets by module.

In any case, I ran out of steam on it. dashboard is 'good enough' in the sense that it filled my immediate need, and the niceties beyond that never really gelled for me in a way that made me go out and write the code.

Writer cannot access his nodes!

Hi,

thanks for putting this great package together... just yesterday I've been wondering how to integrate such a dashboard and finer privileges...

And that's my problem...

the author user still cannot access the node for viewing...

that means the links that he sees are like

For a post in mode "draft"

this fails: /my-draft1.htm
this fails: /node/27/view
this works: /node/27/edit

For a post in mode "review"

this fails: /my-review1.htm
this fails: /node/28/view
this works: /node/28/edit

But this looks like the whole privilege system is out of order...

I actually enabled view+edit for both
I enabled edit for "draft", disabled it for "review"

any clues what I could diagnose? I am poking around for 2 hours now all that code,
printing stuff from the node_grants hooks,
querying your workflow_node/_acess tables (those ARE NOT used, eh???)

please advise & best regards

Christoph

using book content-type

FYI - I am using book content-type

status=0?

And I set the default for "publishing" to 0 ,
so all the nodes that I create have a status=0

I noticed with this the display fails in node.mode - node_access

// If the module did not override the access rights, use those set in the
// node_access table.
if ($op != 'create' && $node->nid && $node->status) {

acutally this if only works for all published nodes... not for the unpublished

and I need them unpublished, as the scheduler shall later put them live by that...

When using this system, you

When using this system, you need to use something *other* than the published flag. There is no way around it with the current Drupal. Using this method, you use the workflow state rather than the published flag; you might switch to using the moderate flag, if possible.

"published" turned off as a default

The problem occured because I had "published" turned off as a default on the settings> content types. It also appears that publishing removes the ability to revision nodes. Is that true or am I missing a setting?

-Ann

Same problem

Was there any answer to this? I have the same problem with the latest releases. WORKFLOW_CREATION=1.

Thanks-
Ann

Uhh

You mean other than the answer I posted just above your comment?

Some feedback

I finally got a chance to install this and play around. It is amazing to see all these disparate pieces working so nicely together. Yeah, Drupal. Thanks so much for making this work AND documenting the recipe. JVD deserves mad props too.

This article is currently our best documentation for this feature. Lets make it even clearer. So I propose these edits (can be done on angrydonuts or i will copy and edit to drupal.org/handbook - merlin's call):
- explicitly instruct the user to assign Publishing workflow to one or more node types
- instruct user to handle the rework => review transition performed by author

Is actions.module truly needed? it seems workflow.module can live without it. We never fire an action in this recipe.

I would omit the node queue stuff. the article is dense enough, and I feel that home page presentation is a different topic.

I would omit the historical info about patches that have been accepted

Feature request - enhance the Workflow+Views integration so that the workflow comment is available to Views. Moshe will submit a patch for this.

Na_arbitrator or workflow_access is adding rows to the node_access table with no grants. IMO, thats just gonna bloat this table which already threatens to get real large with a scheme like this.

IMO, publishing module is a bit rickety since it is based upon dashboard, and the defines have to be customized. Instead, I propose to replace both of its dashboards with the View below. It uses exposed fields to deliver the same info as the dashboards. This View could ship along with workflow.module ... Soon, I wish to add to it the most recent workflow comment and edit/delete links if user has access. Those links should fields in views_node.inc anyway.

  $view = new stdClass();
  $view->name = 'workflow_dashboard';
  $view->description = 'Lists nodes by workflow state';
  $view->access = array (
  0 => '3',
  1 => '4',
);
  $view->view_args_php = '';
  $view->page = TRUE;
  $view->page_title = 'workflow dashboard';
  $view->page_header = '<?phprnrn$sql = "SELECT type FROM {workflow_type_map} WHERE wid > 0\";\r\n$result = db_query($sql);\r\nwhile ($row = db_fetch_object($result)) {\r\n  if (node_access(\'create\', array(\'type\' => $row->type))) {\r\n    $name = node_get_name($row->type);\r\n    $items[] = l(\"Create $name\", \"node/add/$row->type\", array(\'title\' => t(\'Add a new %s.\', array(\'%s\' => $name))));  \r\n  }\r\n}\r\n\r\nif ($items) {\r\n  return theme(\'item_list\', $items);\r\n}\r\n\r\n?>\r\n';
  $view->page_header_format = '2';
  $view->page_footer = '';
  $view->page_footer_format = '1';
  $view->page_empty = 'No posts.';
  $view->page_empty_format = '1';
  $view->page_type = 'table';
  $view->url = 'wfd';
  $view->use_pager = TRUE;
  $view->nodes_per_page = '30';
  $view->menu = TRUE;
  $view->menu_title = 'Workflow dashboard';
  $view->menu_tab = FALSE;
  $view->menu_tab_default = FALSE;
  $view->menu_weight = '';
  $view->sort = array (
    array (
      'tablename' => 'node',
      'field' => 'changed',
      'sortorder' => 'DESC',
      'options' => '',
    ),
  );
  $view->argument = array (
  );
  $view->field = array (
    array (
      'tablename' => 'node',
      'field' => 'title',
      'label' => 'Title',
      'handler' => 'views_handler_field_nodelink',
      'sortable' => '1',
    ),
    array (
      'tablename' => 'node',
      'field' => 'changed',
      'label' => 'Updated',
      'handler' => 'views_handler_field_date_small',
      'sortable' => '1',
      'defaultsort' => 'DESC',
    ),
    array (
      'tablename' => 'users',
      'field' => 'name',
      'label' => 'Author',
      'sortable' => '1',
    ),
    array (
      'tablename' => 'workflow_states',
      'field' => 'state',
      'label' => 'State',
      'sortable' => '1',
    ),
  );
  $view->filter = array (
    array (
      'tablename' => 'workflow_node',
      'field' => 'sid',
      'operator' => 'OR',
      'options' => '',
      'value' => array (
  0 => '2',
  1 => '5',
  2 => '3',
  3 => '4',
),
    ),
    array (
      'tablename' => 'node',
      'field' => 'currentuid',
      'operator' => '=',
      'options' => '',
      'value' => '***CURRENT_USER***',
    ),
  );
  $view->exposed_filter = array (
    array (
      'tablename' => 'workflow_node',
      'field' => 'sid',
      'label' => 'State',
      'optional' => 1,
      'is_default' => 1,
      'operator' => 1,
      'single' => 0,
    ),
    array (
      'tablename' => 'node',
      'field' => 'currentuid',
      'label' => 'Author',
      'optional' => 1,
      'is_default' => 0,
      'operator' => 0,
      'single' => 0,
    ),
  );
  $view->requires = array(node, users, workflow_states, workflow_node);
  $views[$view->name] = $view;

1) This is definitely

1) This is definitely handbook material, so I definitely think edits should go there, but I would be more than happy to revise this article to include edits from there, as a lot of people now have this bookmarked. But the handbook would get even more exposure. And the edits you mention I agree with.

2) Exposing workflow comments to Views is a good idea, but may be a little tricky. I don't think workflow records which one is the most recent comment, which makes it hard to pick the most recent one. That said, it's a relatively minor patch + db update to do so, and I think very worthwhile, so I'm very much in favor of that.

3) You're right, with workflow access we don't actually use the actions module at all. I think it's a good idea to have that if you're using workflow, though, but that should possibly be an addendum rather than a requirement. Good catch.

4) You've got me torn on the view you posted. I like it, but I also like being able to see all my states at the same time. However, instead of using defines, perhaps the publishing module could be modified to instead load the workflow (like your view does) (and we can designate which workflow by a setting) and just show a single view with for each state available in that workflow. I still like the dashboard, though. If we do this, the publishing module may need to go into CVS rather than simply be a glue module that is downloaded. Bonus: In 4.8, the publishing module could be a bit of an install profile.

5) Na_arbitrator or workflow_access is adding rows to the node_access table with no grants. IMO, thats just gonna bloat this table which already threatens to get real large with a scheme like this.

You're right, records with 0 access need not actually be written. A simple patch to na_arbitrator can check that before adding them to the query.

6) Finally, thank you! I've been hoping for some feedback from someone actually using the system! And it's feedback that will lead to improvements!

reply

replying to your points ...

1. I will make the neeeded page on drupal.org and post the url here

2. workflow history records a timestamp on each transition so it is easy to pick the best one. I'd love for you to help me with the Views integration here, because I am unsure if we just want the most recent workflow_history record for a given node and if so, how to configure that.

3. OK

4. For the drupal.org recipe, I really want to ditch both publishing module and dashboard. KISS. Having said that, I do have some fondness for your dashboard UI. I think I'll introduce a new View type called 'Multiple tables'. That view type will list each record in a table but it will end the table each time the sort by field's value changes. At that point, it wlll write a header with the new value of the Sort by field and then table list the additional records with that value. So in this workflow View, we will sort by State and thus each State gets its own table. Hope that makes sense. Are you interested in a patch for this? ... I used to write reports that looked like this on a mainframe system about 100 years ago.

Make it a plugin, it doesn't

Make it a plugin, it doesn't need to be a patch, at least to start with. I think it'd be a great feature though, I like it.

The problem with 'pickign the best one' is doing it in a simple query. I've never figured out how to actually do that.

Nothing seems to work

I've followed the instructions to set this up but while everything seems to be functional, entering a story via the author dashboard leads to it disappearing (as far as the dashboard is concerned).

Only appears in the usual content list via administer when logged in as admin.

I'm pretty sure I've added all the permissions correctly during the workflow process, but they are quite tricky to read.

Is this a problem that anyones come across before?

Aha

The bit I didn't do was to assign the Publishing workflow to the appropriate content it should control. This is in the Workflow settings in Admin, and consists of setting the dropdown next to the content to 'Publishing' (or whatever you've named your workflow).

This, and a lot of access control setting configuration (mainly trial and error) got things seemingly working as they should be.

Problems

Has anyone found issues with path / pathauto modules not working correctly with this set up?

Thanks!

Thanks for the very useful tutorial. It required a bit of tweaking to get to work nicely (the comments above helped), but it will work excellently for my publication. Thanks!

Hi, is there going to be

Hi, is there going to be anything like this recipe for drupal 5? If so, is there a guesstimate of timeline? Thanks a ton!

Yes

...but I don't have a guestimate of the timeline because it depends upon workflow and actions module being ported and stable. I don't know how long it will take for these things to happen.

Error with PHP5

I'm getting this error:

Fatal error: Only variables can be passed by reference in ....publishing.module on line 357

I'm running PHP5 on my development system. Help!

publishing labels

Hi, we've got the publishing module set up with workflow. Our client needed a more complicated workflow, wherein there was a master administrator above the editor. The editor reviews and handles content until s/he sets it as "Approved". Once it's Approved, it takes the Master Administrator to make it publicly available, either just for the "Board" of directors, or fully for the "Public".

Everything about this seems to be working beautifully, with two complaints from the client:

1) The two additional workflow states "Approved" and "Board" aren't labeled with the box at the top like Draft, Rework and Review. I see in lines 270-315 a switch block that creates the labels. What I don't quite get is where the variables tested for in the various cases come from.

2) Though the workflow states are listed in the proper order, meaning by weight, in the admin listing of the workflow itself, the states aren't listed in that order when they're offered on the Workflow tab. I see a number of queries for workflow state in the workflow module. Is there any reason why including an "Order by weight" in those queries wouldn't solve the problem? Seems so obvious that I feel like I must be missing something.

Thanks for this great recipe and module and for any help solving these last details.

Hall

Oh hey. Both of these are

Oh hey. Both of these are really interesting. Can you file them as issues against the module itself? Both of them are going to require some investigation, and in the issue queue they're less likely to get lost forever.

And I'm really glad to see that the module is being used successfully!

Issues filed

I filed one on workflow and one on publishing.... thanks for any help you can offer.

Drupal 5 support

Did you get a chance to make any progress on the Publishing module for Drupal 5?

Thanks.

Drupal 5

So, did you get a chance to make any progress on the Publishing module for Drupal 5?

Alas, I've been focusing

Alas, I've been focusing strongly on Panels 2, Views 2 and Nodequeue 2, and I just haven't had a chance to bring this module into the modern era. :/

How is this done with Drupal 6?

How is this done with Drupal 6?

Is there a ready made solution?

Workflow in drupal 6

can you guide me how to so this with drupal 6...

I have installed the workflow module. I've the actions module and created some states and actions..but its no working.. Anybody can publish.. even without permissions to do it...

I don't see my workflow moving..

Please help..

Post new comment

The content of this field is kept private and will not be shown publicly.