pennersr / django-allauth

Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.
https://allauth.org
MIT License
9.37k stars 3.01k forks source link

How to access 'Forgot your password?' anchor element. #3964

Open Keacoder opened 1 month ago

Keacoder commented 1 month ago

I have been attempting to access the 'Forgot your password?' anchor element' to add a button class. Running Django in a docker container.

I have read all the documentation I could find and tried a number of possibilities without success (I haven't been able to get access from the templates).

The only way I can see would be to edit the forms.py which to me seems like a hack and not a solution. Although I can read the forms.py from the repo I haven't been able to access it from my development environment in vscode.

Am I on the right track, or have I missed something? Any help would be greatly appreciated.

pennersr commented 1 month ago

It depends a bit how you are styling things. If you copied over the templates, you are free to render that field manually and use custom markup for the help_text. But indeed, there is no trivial way of doing that. Perhaps this bit of code...

            forgot_txt = _("Forgot your password?")
            self.fields["password"].help_text = mark_safe(
                f'<a href="{reset_url}">{forgot_txt}</a>'
            )

... should be changed to render a account/password_reset_help_text.html template instead.

pennersr commented 1 month ago

An alternative option is to treat help texts like error messages. The adapter has a error_messages = {...} dictionary, allowing you to override any error message as you see fit. Similarly, it could feature a help_texts = {...}. Then, you could just set help_texts = { "forgot_password": "custom text or markup"}. Having to override the adapter makes more sense for things like help texts, but on the other hand is a bit of a hassle to just add a class. TBD.

Keacoder commented 1 month ago

It appears to me that the section of code you refer to:

        forgot_txt = _("Forgot your password?")
        self.fields["password"].help_text = mark_safe(
            f'<a href="{reset_url}">{forgot_txt}</a>'
        )

Is executed as part of 'allauth/account/forms.py - class LoginForm'. The code seems to create and inject the anchor into the login form without referencing/querying any allauth templates as it creates the anchor. I don't see how there could be an opportunity to override/customise the anchors creation via templates.

"If you copied over the templates, you are free to render that field manually and use custom markup for the help_text." Could you please elaborate on how I can render the field?

Thanks for your help in guiding me to a solution.

pennersr commented 1 month ago

If you render the field like so:

{{ form.password }}

... then Django renders it, including the help_text specified in the forms.py. You could override Django's django/forms/field.html to influence how the field is rendered. There, you can add classes as you see fit. Alternatively, you could just render the field yourself, something like:

<div>
<input type="password" name="password" id="{{ form.password.auto_id}}" value="{{ form.password.value }}">
<span class="myclass">My help</span>
</div>
Keacoder commented 1 month ago

Thanks for the suggestions.

As mentioned in my initial post I would like to add a class (class="btn btn-primary") to the 'Forgot your password!' anchor element of the login page:

    forgot_txt = _("Forgot your password?")
    self.fields["password"].help_text = mark_safe(
        f'<a href="{reset_url}">{forgot_txt}</a>'
    )

As:

<a class="btn btn-primary" href="{reset_url}">{forgot_txt}

I tried the suggested dtl variable {{ form.password }} which unfortunately just rendered a password input box.

If I add '.help_text' to the variable {{ form.password.help_text }} it renders the 'Forgot your password!' anchor element as originally coded. Unfortunately the DTL reminds me that variables cannot be modified once created so it seems there is no opportunity to override the anchor element using {{ form.password.help_text }}.

I could be wrong but this anchor element seems to be hard-coded and not available to override.