I found this in Workbench Access issue queue: https://www.drupal.org/project/workbench_access/issues/2982941#comment-12670744

It seems as if I need to deactivate the translate *bundle* *node* permissions, because if those are set, the permission will be short circuited and no other access restrictions may apply, and create a hole bunch of new *translate *bundle* *node* *language* permissions on my own. In my case we have 15 node types and 6 languages. That would result in 90 new permissions. That is overwhelming.

Original Question

I'm trying to restrict the access to creating and editing of nodes in the Drupal admin section to only one language for a user. I didn't find a module which provides for this feature. Is there any module that does this?

I then tried to create my own module. I came up with this solution

File: custom_i18n_access.module


use Drupal\node\NodeInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;

 * Implements hook_node_access().
 * Prevent editor role to edit and/or delete fr/en nodes. Quick and dirty.
function custom_i18n_access_node_access(NodeInterface $node, $op, AccountInterface $account)

    $roles = $account->getRoles();

    if (in_array('administrator', $roles)) {
        return AccessResult::neutral();

    if ($op !== 'update' && $op !== 'delete') {
        return AccessResult::neutral();

    // Access should be restricted only if this permission is set
    if (!$account->hasPermission('custom_i18n_access_restrict')) {
        return AccessResult::neutral();
    $current_language = \Drupal::languageManager()->getCurrentLanguage();
    $lang             = $current_language->getId();

    if ($account->hasPermission("custom_i18n_access_{$lang}_allow")) {
        return AccessResult::neutral();
    return AccessResult::forbidden();

File: custom_i18n_access.permissions.yml

  - Drupal\custom_i18n_access\Permissions::permissions

File: src/Permissions.php


namespace Drupal\custom_i18n_access;

class Permissions {
    public function permissions() {
        $languages = \Drupal::languageManager()->getLanguages();

        $permissions["custom_i18n_access_restrict"] = [
            'title' => t("Restrict language access"),
            'description' => 'Restrict the edit access of nodes',

        foreach($languages as $lang) {
            $permissions["custom_i18n_access_{$lang->getId()}_allow"] = [
                'title' => t("Allow to edit @lang content", ['@lang' => $lang->getName()]),

        return $permissions;

This custom module successfully restricts the editing and deleting of existing content to only the language I specified in the permissions. But it does not prevent new translations of the content into other languages.

As I see it, the HOOK_node_access hook is not called for every language when on the translations subtask page. How can I achieve this? Is there a different hook for that? I didn't find any help online.


1 Answer 1


I would suggest here checking NodeTranslationHandler class, in entityFormAlter you could find a way how to restrict a user from creating a new translation.

  • Thanks for your answer. I'll take a look into it.
    – yunzen
    Jul 8, 2020 at 20:31
  • Basically, each entity type is using their own translation handler ContentTranslationHandler, you could try to even override this handler using hook_entity_type_alter() f.e. /** * Implements hook_entity_type_alter(). */ function MY_MODULE_entity_type_alter(array &$entity_types) { $entity_types['node']->setHandlerClass('translation', CustomTranslationHandler::class); } Jul 8, 2020 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.