WordPress | Prevent redirect on login error on custom login page.

For a customer i created a login page ( basically a page with two form, first for able users to register at the site, and the second with a Login purpose).

With the first form, there hasen’t any problem, is made with “Gravity form” and the Add-on”User Registration Add-On”, the second is build with the wordpress function


Basically i passed to this function some args :

$args = array(
'echo'           => true,
'redirect'       => '',
'form_id'        => 'loginform',
'label_username' => __( '' ),
'label_password' => __( '' ),
'label_remember' => __( 'Ricordami' ),
'label_log_in'   => __( 'Accedi' ),
'id_username'    => 'user_login',
'id_password'    => 'user_pass',
'id_remember'    => 'rememberme',
'id_submit'      => 'wp-submit',
'remember'       => true,
'value_username' => '',
'value_remember' => true,
wp_login_form( $args );

All works fine except for the login errors:
If the login form goes in error, it redirect to the wp-login.php page.
I need that in case of errors, the user still remain on same page and see the error message.
So after some googling and some test, i found the right way:
Open function.php and add

/* prevent redirect on login error in a custom login page */

add_filter('login_redirect', 'choose_login_redirect', 10, 3);
function choose_login_redirect($redirect_to, $requested_redirect_to, $user) {
if (is_wp_error($user)) {
//Login failed, find out why...
$error_types = array_keys($user->errors);
//Error type seems to be empty if none of the fields are filled out
$error_type = 'both_empty';
//Otherwise just get the first error (as far as I know there will only ever be one)
if (is_array($error_types) && !empty($error_types)) {
$error_type = $error_types[0];
// Url of our custom login page
wp_redirect( home_url() . "/register/?login=failed&reason=" . $error_type );

We go to check if form has error, and if so, reload page with parameters about the errors in url.
Now we need to associated every type of errors with the correct Error message.
Open the template file and, where you want error appear, add this line of code:

<div id="validation_message_login_custom" class="gfield_description validation_message" aria-live="polite" style="margin-bottom: 10px; color: #FBD200; font-weight: bold; font-size: .75rem;">
<!--?php if(isset($_GET['reason'])) {
if($_GET['reason'] == 'empty_username'){
echo __("Il campo E-mail è vuoto.", "zotup"); // Message if e-mail is empty
}else if( $_GET['reason'] == 'empty_password'){
echo __("Il campo Password è vuoto.", "zotup"); // Message if password is empty
}else if( $_GET['reason'] == 'invalid_email'){
echo __("E-mail errata o non registrata.", "zotup");// Message if e-mail isn't valid or isn't in the registered email db
}else if( $_GET['reason'] == 'incorrect_password'){
echo __("Password errata per l'emeail inserita", "zotup");//Message if the password isn't associated with the email
} ?-->

That’s all
Implement and test it !!