1

We have a multi lingual site that default is "en".

Sometimes editors are creating content in another language like "de" and than translate it to "en".

My problem is that we use Layout builder visibility rules for blocks.

And the form action attribute that is rendered as example below.

Does not have a language prefix.

And therefore ends up in a 403 response for every content page that is not created in sites default language.

My question is how can I add the language prefix to the action attribute the most drupalish way?

/**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL, $delta = NULL, $uuid = NULL) {
    $this->sectionStorage = $section_storage;
    $this->delta = $delta;
    $this->uuid = $uuid;

    // Any visibility conditions that have already been added to the block.
    $visibility_conditions_applied_to_block = $this->getCurrentComponent()->get('visibility') ?: [];

    // Visibility condition types that can be added to a block.
    $conditions_available_to_block = [];
    foreach ($this->conditionManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage)) as $plugin_id => $definition) {
      $conditions_available_to_block[$plugin_id] = $definition['label'];
    }

    $items = [];
    foreach ($visibility_conditions_applied_to_block as $visibility_id => $configuration) {
      /** @var \Drupal\Core\Condition\ConditionInterface $condition */
      $condition = $this->conditionManager->createInstance($configuration['id'], $configuration);
      $options = [
        'attributes' => [
          'class' => ['use-ajax'],
          'data-dialog-type' => 'dialog',
          'data-dialog-renderer' => 'off_canvas',
          'data-outside-in-edit' => TRUE,
        ],
      ];
      $items[$visibility_id] = [
        'label' => [
          'data' => [
            'condition_name' => [
              '#type' => 'html_tag',
              '#tag' => 'b',
              '#value' => $condition->getPluginId(),
            ],
            'condition_summary' => [
              '#type' => 'container',
              '#markup' => $condition->summary(),
            ],
          ],
        ],
        'edit' => [
          'data' => [
            '#type' => 'link',
            '#title' => $this->t('Edit'),
            '#url' => Url::fromRoute('layout_builder.add_visibility', $this->getParameters($visibility_id), $options),
          ],
        ],
        'delete' => [
          'data' => [
            '#type' => 'link',
            '#title' => $this->t('Delete'),
            '#url' => Url::fromRoute('layout_builder.delete_visibility', $this->getParameters($visibility_id), $options),
          ],
        ],
      ];
    }

    if ($items) {
      $form['visibility'] = [
        '#prefix' => '<div class="configured-conditions">',
        '#suffix' => '</div>',
        '#theme' => 'table',
        '#rows' => $items,
        '#caption' => $this->t('Configured Conditions'),
        '#weight' => 10,
      ];
    }

    $form['condition'] = [
      '#type' => 'select',
      '#title' => $this->t('Add a visibility condition'),
      '#options' => $conditions_available_to_block,
      '#empty_value' => '',
      '#weight' => 20,
    ];

    // Determines if multiple conditions should be applied with 'and' or 'or'.
    $form['operator'] = [
      '#type' => 'radios',
      '#title' => $this->t('Operator'),
      '#options' => [
        'and' => $this->t('And'),
        'or' => $this->t('Or'),
      ],
      '#default_value' => $this->getCurrentComponent()->get('visibility_operator') ?: 'and',
      // This field is not necessary until multiple conditions are added.
      '#access' => count($items) > 0,
      // If there are two or more visibility conditions, this field appears
      // above the list of existing conditions. If there is only one visibility
      // condition, and a second one is being added, then this field appears
      // between the 'Add a visibility condition' dropdown and the submit
      // button.
      '#weight' => count($items) === 1 ? 30 : 3,
    ];

    // This is a submit button that only appears once two or more visibility
    // conditions are present. This submit button appears so the user can
    // update the visibility operator, a setting that impacts the entire block.
    // This is different than the default submit button/handler for this form,
    // which is used to add a visibility condition to the block.
    $form['update_operator'] = [
      '#type' => 'submit',
      '#access' => count($items) > 1,
      '#weight' => 5,
      '#value' => $this->t('Update operator'),
      '#submit' => ['::updateOperator'],
    ];

    if (count($items) === 1) {
      // If there is only one visibility condition, hide the operator field
      // until a second condition is selected to be added to the block.
      $form['operator']['#states'] = [
        'invisible' => [
          '[name="condition"]' => ['value' => ''],
        ],
      ];
    }

    $form['actions']['#weight'] = 40;
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Add condition'),
      // Submit button is only visible if a condition is selected.
      '#states' => [
        'invisible' => [
          '[name="condition"]' => ['value' => ''],
        ],
      ],
    ];

    $form['#attributes']['data-layout-builder-target-highlight-id'] = $this->blockUpdateHighlightId($this->uuid);

    if ($this->isAjax()) {
      $form['actions']['submit']['#ajax']['callback'] = '::ajaxSubmit';
      $form['actions']['submit']['#ajax']['event'] = 'click';
      $form['update_operator']['#ajax']['callback'] = '::ajaxSubmit';
      $form['update_operator']['#ajax']['event'] = 'click';
    }

    return $form;
  }

Example won't work:

<form class="layout-builder-configure-visibility" data-layout-builder-target-highlight-id="28411f7a-940c-44a5-bf49-43ca6dfa3acd" data-drupal-selector="layout-builder-configure-visibility" action="/layout_builder/visibility/block/overrides/node.220/1/28411f7a-940c-44a5-bf49-43ca6dfa3acd/user_role?destination=/layout_builder_iframe_modal/redirect" method="post" id="layout-builder-configure-visibility" accept-charset="UTF-8">

Example work:

<form class="layout-builder-configure-visibility" data-layout-builder-target-highlight-id="28411f7a-940c-44a5-bf49-43ca6dfa3acd" data-drupal-selector="layout-builder-configure-visibility" action="/de/layout_builder/visibility/block/overrides/node.220/1/28411f7a-940c-44a5-bf49-43ca6dfa3acd/user_role?destination=/layout_builder_iframe_modal/redirect" method="post" id="layout-builder-configure-visibility" accept-charset="UTF-8">

1 Answer 1

0

Found a solution that works for me. This form above is a modal form rendered as Iframe. So in my .module file. I had to adjust the action attribute itself:

/**
 * Implements hook_preprocess_HOOK().
 */
function freitag_layout_visibility_control_preprocess_form(&$variables) {      
  if (isset($variables['attributes']['id']) && $variables['attributes']['id'] === 'layout-builder-configure-visibility') {
    $langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
    $variables['attributes']['action'] = '/' . $langcode . $variables['attributes']['action'];
  }
}

Not the nicest solution but it works.

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.