Search code examples
formsroutesuser-controlsdrupal-8

How to change the pages for 'register user', 'change password' and 'user edit' in Drupal 8


I wanted to change the pages 'register user', 'change password' and 'user edit'. This is not possible in the Drupal frontend, and you also have to pay a lot of attention in the code. In forums you will usually find little help and if then rather not satisfactory. Therefore, I like to share my solution to save the one or other headache.


Solution

  • The three forms are already available from Drupal standard, if you want to change them you have to access the route and redirect.

    1. For this you first create a module like 'my_forms'.

    2. Second the form or a page that you want to hook into the website. e.g. 'ForgotPasswordForm'

    3. Create a folder inside your my_forms 'Routing' and a file like 'RouteSubscriber.php'

    code:

    <?php
    namespace Drupal\my_forms\Routing;
    class RouteSubscriber extends RouteSubscriberBase{
        protected function alterRoutes( RouteCollection $collection ){
            //enter code here
        }
    }   
    
    1. Now you can change the route to the diffrent pages by adding following -

    code:

    //edit the 'forgot password' page
    if ( $route = $collection->get( 'user.pass' ) ){
        $route->setDefault( '_form', '\Drupal\my_forms\Form\ForgotPasswordForm' );
    }
    

    The keyword 'user.pass' allows you to change the routing. setDefault redirects the route to your own form.

    //edit the 'register' page
    if ( $route = $collection->get( 'user.register' ) )
        {
            $route->setDefaults( array(
                                     '_title'      => 'Register',
                                     '_controller' => '\Drupal\myy_forms\Controller\LocalTaskController::offerRegistrationPage'
                                 )
            );
        }
    

    The keyword for the registration is 'user.register'. By setting the route with setDefaults you can also change the name of the link/button. In this case I used a controller to print out a normal page inside the registration. (more at the end of the post)

    if ( $route = $collection->get( 'entity.user.edit_form' ) ){
        //enter code here
    }
    

    For the 'user edit' page you need to use the keyword 'entity.user.edit_form'.

    1. Last step is to clear your cashes, to register the changes in your Drupal website and refresh your page.

    Load simple page with a Drupal Controller:

    namespace Drupal\my_forms\Controller;
    
    class LocalTaskController extends ControllerBase{
    /** @var  NodeStorage $nodeStorage */
    protected $nodeStorage;
    /** @var  EntityViewBuilder $viewBuilder */
    protected $viewBuilder;
    
    function __construct( $nodeStorage, $viewBuilder )
    {
        $this->nodeStorage = $nodeStorage;
        $this->viewBuilder = $viewBuilder;
    }
    
    public static function create( ContainerInterface $container )
    {
        $nodeStorage = $container->get( 'entity.manager' )->getStorage( 'node' );
        $viewBuilder = $container->get( 'entity_type.manager' )->getViewBuilder( 'node' );
    
        return new static( $nodeStorage, $viewBuilder );
    
    }
    
    public function offerRegistrationPage()
    {
        $node        = $this->nodeStorage->load( 24 );
        $renderArray = $this->viewBuilder->view( $node );
    
        return [
            '#type'   => '#markup',
            '#markup' => render( $renderArray ),
        ];
    }
    

    The '24' is the nid of the simple page, which should be displayed instead of the standard registration.