Search by

faithcatholic / custom_publishing

nketchummjones

Lets anonymous users create unpublished content.

Package info

github.com/FaithCatholic/custom_publishing

Homepage

Issues

Language:Shell

Type:drupal-module

pkg:composer/faithcatholic/custom_publishing

Statistics

Installs: 697

Dependents: 0

Suggesters: 0

Stars: 0

5.0.0 2026-09-10 00:49 UTC

This package is auto-updated.

Last update: 2026-09-11 22:23:25 UTC


README

Holds content back for review when it is submitted by an untrusted role, and tells someone about it. On every node save the module compares the current user's roles and the node's content type against its settings, and if both match it unpublishes the node and shows the author a "submitted for approval" message. When the author is anonymous it also sends a notification email to staff, and optionally a confirmation email back to the person who submitted the content. Both emails support a small set of tokens for the title, link, creation time, content type and site name.

Requirements

Drupal 10.3+ or 11. No contrib dependencies. The module depends on the core Node, User and Path alias modules, which are declared in the info file and installed automatically.

Two things the module assumes about the site, neither of which it creates for you:

  • Anonymous users can create content. Nothing happens until the anonymous role (or whichever role you pick) actually has a "Create new content" permission for the content types you select.
  • A field_contact_email field, on every content type listed in the user confirmation settings. The confirmation email is skipped silently for nodes without that field, or where it is empty. The field name is hardcoded.

Installation

Install as usual at /admin/extend. Out of the box the module does nothing: it ships with no roles and no content types selected, so configure it first.

Configuration

Settings live at /admin/config/content/custom-publishing, under Configuration > Content authoring. The route requires the "administer site configuration" permission.

  • Roles and Content types: the unpublish rule applies when the saving user has one of the selected roles and the node is one of the selected types. Both lists must have a selection for anything to happen.
  • Staff confirmation email: turn on notifications, and optionally set an address, subject and body. The site email address is used if you leave the address blank, and a built-in subject and body are used if you leave those blank.
  • User confirmation email: list the content types that should send a confirmation, and set the reply address, subject and body. These four fields are all-or-nothing, the form rejects a partial set. The content types listed here must also be selected in Content types above.
  • Tokens available in every subject and body: [[title]], [[link]], [[created]], [[type]], [[sitename]].
  • Both emails are only sent for content submitted by an anonymous user. The unpublish rule applies to any role you select.

Development

The repository is a bare module with a DDEV setup around it. web/ and vendor/ are ignored, and the module is symlinked into web/modules/custom/custom_publishing.

ddev start runs the bootstrap in .ddev/post-start.sh: it installs the Drupal codebase with poser, does a site install on an empty database, creates the symlink and enables the module, then prints a one-time login link. The admin account is admin with password 1.

Checks:

ddev phpcs
ddev phpcbf
ddev phpstan --level=6 -c ../../../../phpstan.neon

Pass the config to phpstan explicitly. Plain ddev phpstan symlinks the config into the module directory with a relative path that does not resolve, so it silently runs at level 0 with no Drupal rules. The relative path above is correct because the wrapper changes into web/modules/custom/custom_publishing first.

Add-ons in use: ddev-drupal-contrib, ddev-drupal-contrib-extras, ddev-drupal and pimp-my-shell.

Notes

  • The unpublish rule runs on every save, not only on the first one. There is no new-node check, so a user with a matching role who edits an existing published node of a matching type will unpublish it again and see the approval message. This is long-standing behavior and was left alone. It rarely shows up with the anonymous role, which usually cannot edit, but it does bite if you select an authenticated role.
  • The hooks live in src/Hook/CustomPublishingHooks.php using the class-based hook system. The functions left in custom_publishing.module are thin #[LegacyHook] stubs that exist only for Drupal 10, which has no attribute hooks. Drupal 11 skips them. Once the supported floor is Drupal 11.1 the stubs and custom_publishing.services.yml can both be deleted.
  • The module has no plugins, so there are no annotations left to convert to PHP attributes for Drupal 12.