Как выполнить перенаправление на пользовательскую страницу после сохранения или удаления узла?

10

То, что я пытаюсь сделать, не работает, я все еще перенаправлен в / node / {id}:

function hook_form_alter(&$form, $form_state, $form_id) {
  $form['actions']['submit']['#submit'][] = 'callback_set_redirect';
}
function callback_set_redirect($form, FormStateInterface $form_state) {
  $form_state->setRedirect('custom.landing.page');
}
olsav
источник
2
Это то, что я нашел в /core/modules/node/src/NodeForm.php If saving is an option, privileged users get dedicated form submit buttons to adjust the publishing status while saving in one go. @todo This adjustment makes it close to impossible for contributed modules to integrate with "the Save operation" of this form. Modules need a way to plug themselves into 1) the ::submit() step, and 2) the ::save() step, both decoupled from the pressed form button.
olsav
1
Вы можете использовать модуль [ drupal.org/project/rules](Rules) .
Сумит Аггарвал
1
Вы уверены, что ваша пользовательская функция отправки даже вызывается?
Eyal
1
Также может случиться так, что другая функция отправки позже переопределит ваш пользовательский редирект.
Eyal

Ответы:

7

В основном код будет работать только для отправки действия, но форма сохранения узла drupal имеет много действий, я думаю, вы бы вошли в систему как администратор и попробовали бы его, а затем следуйте приведенному ниже коду.

если вы хотите, чтобы это работало и для других действий, это означает, что войдите в систему как администратор и увидите кнопку сохранения узла, у вас будет возможность выбрать «сохранить и опубликовать», «сохранить и отменить публикацию». как уже упоминалось

use Drupal\Core\Form\FormStateInterface;

//hook_form_alter
function hook_form_alter(&$form, $form_state, $form_id) {
  foreach (array_keys($form['actions']) as $action) {
    if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
      $form['actions'][$action]['#submit'][] = 'callback_submit';
    }
  }
}


function callback_submit($form, FormStateInterface $form_state) {
  $form_state->setRedirect('custom.page');
}
Картикеян Манивасагам
источник
4

Используя hook_form_alter, вам нужно сделать две вещи

1) Убедитесь, что это форма узла. 2) Добавьте пользовательский обработчик отправки для каждой кнопки отправки.

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  if (isset($form['#entity_type']) && $form['#entity_type'] == 'node') {
    foreach (array_keys($form['actions']) as $action) {
      if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
        $form['actions'][$action]['#submit'][] = 'mymodule_node_form_submit';
      }
    }
  }
}

Затем для функции отправки вы можете использовать любую логику, какую захотите. Вы можете сравнить с NodeForm :: save, где он отправляет вас либо на страницу канонического узла, либо на первую страницу в зависимости от прав доступа текущего пользователя.

Если вы хотите изменить это поведение, чтобы оно оставалось в текущей форме узла, вы можете сделать это:

function mymodule_node_form_submit($form, FormStateInterface $form_state) {
  $node = $form_state->getFormObject()->getEntity();
  if ($node->id()) {
    if ($node->access('edit')) {
      $form_state->setRedirect(
        'entity.node.edit_form',
        ['node' => $node->id()]
      );
    }
    else {
      $form_state->setRedirect('<front>');
    }
  }
}

Если вы хотите использовать свою пользовательскую целевую страницу, просто замените перенаправление на код, который вы уже используете:

$form_state->setRedirect('custom.landing.page');

Обратите внимание, что это не будет переопределено при наличии параметра $ _GET «destination», например, на странице / admin / content.

Чтобы удалить параметр адресата со страницы / admin / content, вам нужно снять флажок «destination» в разделе «Content: Operations links (Operations)» в полях этих представлений.

введите описание изображения здесь

oknate
источник
1

Я имел успех, используя Symfony RedirectResponse:

function callback_set_redirect($form, FormStateInterface $form_state) {
  $url = Url::fromRoute("custom.landing.page")->toString();
  $response = new RedirectResponse($url);
  $response->send();
}
rpayanm
источник
Вы не должны использовать ответ, так как он не позволяет модулям при наведении изменить перенаправление, если это необходимо.
kiamlaluno
У меня тоже сработало.
Insasse
0

Я не могу найти ничего плохого в исходном коде, так что, возможно, что-то еще не так. Он отлично работает для меня.

Тем не менее, custom.landing.pageдолжен быть определенный маршрут и параметры (если таковые имеются) должны быть переданы следующим образом:

  $form_state->setRedirect("custom.landing.page", [
    'parameter1' => 42,
  ]);

Посмотрите FormState :: setRedirect () для деталей.

Колан
источник
0

Я всегда использую модуль Node Save Redirect для этой функциональности. Он добавляет опцию к типу контента, который говорит «что делать после сохранения нового контента».

Что это?

Этот модуль предоставляет метод указания местоположения, которое нужно взять пользователю после сохранения фрагмента контента.

Стеф Ван Луверен
источник
Этот модуль еще не был полностью перенесен на Drupal 8.
dxvargas