0

I have Drupal 8 installation, with a custom content type. I would like to redirect to a specific page after node form submission.

What I have tried so far: Using hook_form_alter() and it works, but that's not the point here.

What I want to achieve: Delivering the same functionality in a new OOP code based way.

What I have found so far: https://www.thirdandgrove.com/redirecting-node-pages-drupal-8

This example shows the replacement for the old hook_init().

Update 1: Rules module can achieve the desired functionality.

Update 2: Node_save_redirect module can achieve the desired functionality.

Update 3: A possible answer https://www.foreach.be/blog/how-manipulate-forms-drupal-8 can someone with enough D8 experience actually confirm if that's actually the official way of doing things ?

Regards, Oleg

  • 1
    Good question - one of the most frustrating things for me in 8, is the hybrid we have between event subscribers and the old hook based system. It's one I truthfully don't understand. – user34185 Mar 8 '17 at 10:02
  • yes, this particular question is about form redirect but the topic is way more generic.... OOP altering a form. BrynJ, based on your answer I assume there is no way to do it OOP? – Oleg Videnov Mar 8 '17 at 12:40
  • 1
    I'm not sure to be honest. Here are a list of core Drupal events that you subscribe to: api.drupal.org/api/drupal/core!core.api.php/group/events/8.3.x - there are EntityTypeEvents to subscribe to (create, edit and delete). Very little documentation however, and I'm not sure if this event is fired with instances of an entity type or the entity type itself - it might be worth investigating. – user34185 Mar 8 '17 at 16:22
  • 1
    Good luck with it all. An article I found which is quite good at explaining hooks versus event listeners is this one knpuniversity.com/screencast/drupal8-under-the-hood/… – user34185 Mar 9 '17 at 13:53
  • 1
    And another good article - previousnext.com.au/blog/… – user34185 Mar 9 '17 at 13:54
2

This functionality can easily be implemented using rules. This will ensure your Drupal installation to be upgrade proof.

Start off with installing this module. Once installed, create a new rule to trigger on Node > After saving new content of type {your custom content type}. Set action to System > Page redirect and supply the url and you're done.

  • Thanks, I didn't think about Rules here. Thanks ! – Oleg Videnov Mar 7 '17 at 23:04
  • The problem in the past I had with rules was during the maintenance of a project,where the Rules module didn't have good backwards compatibility...since then I am kind of hesitating before using it. – Oleg Videnov Mar 7 '17 at 23:05
  • Before marking this as the accepted answer, I would like to see if there is also some code based solution. – Oleg Videnov Mar 7 '17 at 23:06
  • 1
    The trade off to using Rules vs a few lines of form alter code is in no way worth it. – Kevin Mar 8 '17 at 0:21
2

While the other solution is perfectly valid, I mark this answer as accepted since it comes closer to what I was looking in first place - the new way to alter forms.

Eventually the solution can be found right here: https://www.foreach.be/blog/how-manipulate-forms-drupal-8

In summary (quoted from the article): 1 ) The first step is to write a service that intercepts the original UserLoginForm and directs to the adapted form

2) Changed the route to return the adapted NewUserLoginForm instead of the original UserLoginForm

3) The new form extends the old form and inside the buildForm method you add in the beginning

$form = parent::buildForm($form, $form_state);

This step was missing in the example tere

2

A route subscriber doesn't work so well because the route 'entity.node.edit_form' uses an entity form.

One approach would be to use hook_entity_type_alter to change the edit form:

function mymodule_entity_type_alter(array &$entity_types) {    
  $handlers = $entity_types['node']->get('handlers');
  $handlers['form']['edit'] = 'Drupal\mymodule\Form\CustomNodeEditForm';
  $entity_types['node']->set('handlers', $handlers);
}

Then you could override the save function of the node.

namespace Drupal\mymodule\Form;

use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeForm;

class CustomNodeEditForm extends NodeForm {

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    parent::save($form, $form_state);

    $node = $this->entity;

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

}

This is heavy-handed and risks conflicts with other customizations, but it assures that the redirects are set in the same place they're set as the node edit form, and are therefore fired before other handlers added by other modules.

A simpler approach is to simply to add another submit handler in form alter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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