Publish Content

Enables granular publish and unpublish permissions for content types without requiring the 'administer content' permission.

publishcontent
16,901 sites
57
drupal.org

Install

Drupal 11, 10 v8.x-1.7
composer require 'drupal/publishcontent:8.x-1.7'
Drupal 9, 8 v8.x-1.6
composer require 'drupal/publishcontent:8.x-1.6'

Overview

The Publish Content module provides a lightweight solution for managing content workflows by enabling granular control over who can publish and unpublish content. Instead of granting users the broad 'administer content' permission, site administrators can assign specific publish/unpublish permissions at multiple levels: globally for all content, for content the user can edit, per content type, or per user's own content.

The module adds convenient UI elements for content management: a Publish/Unpublish tab (local task) on node pages for one-click status toggling, and optionally a checkbox on the node edit form. It also integrates with Views to provide publish/unpublish links in content listings, making it ideal for editorial workflows.

For developers, the module provides a robust API including hooks to customize access logic and events dispatched when content is published or unpublished, enabling integration with other workflow systems. Full multilingual support allows managing the publication status of individual translations.

Features

  • Global permissions to publish or unpublish any content regardless of content type
  • Permissions to publish or unpublish content that the user has edit access to
  • Per-content-type permissions for granular control (e.g., 'Article: publish any node type')
  • Permissions to publish or unpublish only the user's own content per content type
  • Configurable Publish/Unpublish local task tab on node view pages for one-click status changes
  • Optional checkbox on node edit forms to toggle publish status inline
  • Views field handler providing Publish/Unpublish links for content administration views
  • Full multilingual support with per-translation publish status management
  • Automatic revision creation option when publishing/unpublishing content
  • Logging option to track all publish/unpublish actions in watchdog
  • Customizable button and status text labels for publish/unpublish actions
  • Developer API hooks (hook_publishcontent_publish_access, hook_publishcontent_unpublish_access) for custom access logic
  • Events (PublishContentPublishEvent, PublishContentUnpublishEvent) dispatched for integration with other systems

Use Cases

Editorial workflow for content editors

Grant content editors the ability to publish and unpublish articles they can edit, without giving them full administrative access. Use the 'publish editable content' and 'unpublish editable content' permissions. Editors can then use the Publish/Unpublish tab to quickly toggle content status while reviewing.

Author self-publishing for specific content types

Allow authors to publish their own blog posts but not other content types. Assign the 'Blog: publish own node type' permission to the author role. Authors can publish their drafts when ready without waiting for editorial review.

Content moderation dashboard

Create a Views-based content moderation dashboard by adding the Publish/Unpublish field to a view of unpublished content. Moderators can quickly publish approved content directly from the list without opening each node.

Multilingual content management

On multilingual sites, use the module to manage publication status per translation. Content managers can publish the English version while keeping the German translation unpublished until it's reviewed.

Custom workflow integration

Subscribe to PublishContentPublishEvent and PublishContentUnpublishEvent to integrate with custom workflows. For example, send email notifications when content is published, or update external systems when content is unpublished.

Conditional publish access

Implement hook_publishcontent_publish_access to add custom business logic. For example, only allow publishing articles that have a featured image, or prevent unpublishing content that is currently featured on the homepage.

Tips

  • Use 'publish editable content' instead of 'publish any content' when possible for better security - users can only publish content they can edit anyway.
  • Enable 'Create new revision when publishing/unpublishing' for accountability and to maintain content history.
  • Enable 'Create a log entry' for audit trails, especially on sites with compliance requirements.
  • Combine with the View Unpublished module to create a complete editorial workflow where editors can see, edit, and publish unpublished content.
  • Use the Views integration to create content dashboards showing publish links, reducing clicks for editorial workflows.
  • Implement access hooks to enforce business rules like requiring certain fields before publishing.

Technical Details

Admin Pages 1
Publish Content Settings /admin/config/workflow/publishcontent

Configure how users interact with the publish and unpublish functionality, including UI preferences, accountability options, and text labels.

Permissions 11
Publish any content

Allows to publish any content regardless of content type or ownership.

Publish editable content

Allows to publish content which the user has edit access to.

Unpublish any content

Allows to unpublish any content regardless of content type or ownership.

Unpublish editable content

Allows to unpublish content which the user has edit access to.

Access publish content settings

Allows access to the Publish Content module settings page.

[Content Type]: publish any node type

Allows to publish any node of this specific content type. Generated dynamically for each content type.

[Content Type]: publish own node type

Allows to publish the user's own nodes of this specific content type. Generated dynamically for each content type.

[Content Type]: publish editable node type

Allows to publish nodes of this content type that the user can edit. Generated dynamically for each content type.

[Content Type]: unpublish any node type

Allows to unpublish any node of this specific content type. Generated dynamically for each content type.

[Content Type]: unpublish own node type

Allows to unpublish the user's own nodes of this specific content type. Generated dynamically for each content type.

[Content Type]: unpublish editable node type

Allows to unpublish nodes of this content type that the user can edit. Generated dynamically for each content type.

Hooks 2
hook_publishcontent_publish_access

Allows modules to grant or deny access to publish a specific node. Called after permission checks pass, enabling custom access logic based on node fields or other conditions.

hook_publishcontent_unpublish_access

Allows modules to grant or deny access to unpublish a specific node. Called after permission checks pass, enabling custom access logic based on node fields or other conditions.

Troubleshooting 5
The Publish/Unpublish tab does not appear on node pages

Ensure the 'Publish and unpublish via local task' setting is enabled at /admin/config/workflow/publishcontent. Also verify the user has appropriate publish/unpublish permissions for the content type.

Users can see the status checkbox but cannot change it

This is expected behavior when 'Publish and unpublish via checkbox' is enabled but the user lacks publish/unpublish permissions. Either grant the appropriate permissions or disable the checkbox UI option.

New content is being created as published even though user lacks permission

The module prevents users without permissions from changing publish status, and defaults new content to unpublished when the user cannot publish. Verify permissions are correctly configured.

The Publish/Unpublish link does not appear in my View

Add the 'Publish/Unpublish' field from the Content category to your View. Ensure the View is showing content (nodes), not other entity types.

Events are not firing when publishing content

Events only fire when using the Publish Content toggle routes (/node/{node}/toggleStatus). Publishing via the node edit form does not trigger these events. Use hook_entity_presave or hook_entity_update for form-based publish changes.

Security Notes 4
  • The module does not bypass Drupal's core access system - users must still have edit access where 'editable' permissions are used.
  • CSRF protection is enforced on all publish/unpublish toggle routes.
  • Dynamic permissions are generated per content type, allowing fine-grained control over which roles can publish which content types.
  • Consider carefully before granting 'publish any content' or 'unpublish any content' - these are powerful permissions that apply to all content types.