Jak wykonać przekierowanie na niestandardową stronę po zapisaniu lub usunięciu węzła?

10

To, co próbuję zrobić, nie działa, nadal jestem przekierowywany do / 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
źródło
2
To znalazłem w /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
Możesz użyć modułu [ drupal.org/project/rules](Rules) .
Sumit Aggarwal
1
Czy jesteś pewien, że twoja niestandardowa funkcja przesyłania jest nawet wywoływana?
Eyal
1
Może się również zdarzyć, że inna funkcja przesyłania zastąpi później niestandardowe przekierowanie.
Eyal

Odpowiedzi:

7

Zasadniczo kod będzie działał tylko dla akcji wysyłania, ale formularz zapisu węzła drupal ma wiele akcji, myślę, że zalogowałbyś się jako administrator i próbowałeś go, a następnie postępuj zgodnie z poniższym kodem.

jeśli chcesz, aby działało to również w przypadku innych działań, oznacza to, że zaloguj się jako administrator i zobacz przycisk zapisz węzeł, będziesz mieć opcję „zapisz i opublikuj”, „zapisz i cofnij publikację”. jak wspomniano

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');
}
Karthikeyan Manivasagam
źródło
4

Używając hook_form_alter, musisz zrobić dwie rzeczy

1) upewnij się, że jest to formularz węzła 2) dodaj niestandardową procedurę obsługi przesyłania do każdego przycisku przesyłania.

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';
      }
    }
  }
}

Następnie dla funkcji wysyłania możesz użyć dowolnej logiki. Możesz porównać z NodeForm :: save, gdzie wysyła cię do strony węzła kanonicznego lub do strony głównej w oparciu o uprawnienia dostępu bieżącego użytkownika.

Jeśli chcesz zmienić to zachowanie, aby pozostało w bieżącej formie węzła, możesz to zrobić:

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>');
    }
  }
}

Jeśli chcesz użyć niestandardowej strony docelowej, po prostu zastąp przekierowanie kodem, którego już używasz:

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

Pamiętaj, że nie zastąpi to parametru „docelowego” $ _GET, na przykład na stronie / admin / content.

Aby usunąć parametr docelowy ze strony / admin / content, usuń zaznaczenie pola wyboru „miejsce docelowe” w obszarze „Treść: Linki operacji (operacje)” w tych polach widoków.

wprowadź opis zdjęcia tutaj

oknate
źródło
1

Miałem sukces przy użyciu Symfony RedirectResponse:

function callback_set_redirect($form, FormStateInterface $form_state) {
  $url = Url::fromRoute("custom.landing.page")->toString();
  $response = new RedirectResponse($url);
  $response->send();
}
rpayanm
źródło
Nie powinieneś używać odpowiedzi, ponieważ nie pozwala ona modułom aktywowanym na zmianę przekierowania, jeśli to konieczne.
kiamlaluno
Pracowałem też dla mnie.
Insasse
0

Nie mogę znaleźć nic złego w oryginalnym kodzie, więc coś innego jest prawdopodobnie nie tak. Działa dla mnie dobrze.

Jednak custom.landing.pagemusi to być określona trasa, a parametry (jeśli takie istnieją) muszą zostać przekazane w następujący sposób:

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

Aby uzyskać szczegółowe informacje, zobacz FormState :: setRedirect () .

colan
źródło
0

Do tej funkcji zawsze używam modułu Node Save Redirect . Dodaje opcję do typu treści, która mówi „co robić po zapisaniu nowej treści”.

Co to jest?

Ten moduł zapewnia metodę określania lokalizacji, która ma zabrać użytkownika po zapisaniu fragmentu treści.

Stef Van Looveren
źródło
Ten moduł nie został jeszcze w pełni przeniesiony do Drupala 8.
dxvargas