Intégrer un formulaire de connexion dans une page Wagtail

Lorsqu'un utilisateur enregistré souhaite accéder à des fonctionnalités restreintes sur une page spécifique, il serait plus convivial de lui permettre de se connecter sur cette page au lieu d'être redirigé vers une page de connexion.

12 Juillet 2020 18:00
Thèmes: Authentification

Dans un didacticiel précédent, on a permis aux utilisateurs enregistrés de commenter facilement les articles. Cependant, lorsqu'un utilisateur enregistré n'est pas connecté, il doit se rendre sur la page de connexion, puis revenir à l'article spécifique. Il existe de nombreuses façons de résoudre ce problème, l'une étant un formulaire de connexion pop-up accessible via le menu. Dans ce tutoriel, on va intégrer un simple formulaire de connexion dans la page d'article spécifique.

Les étapes sont les suivantes:

  • ajouter un formulaire de connexion à la page en remplaçant la méthode serve () de la page,
  • ajouter un modèle de formulaire de connexion au modèle de page et le masquer initialement,
  • ajouter un lien pour afficher le formulaire via jQuery,
  • soumettre le formulaire rempli via jQuery,
  • revenir à la page pour permettre à l'utilisateur de soumettre son commentaire.

Pour remplacer la méthode serve (), ajoutez ce qui suit au modèle de page (dans notre cas, ArticlePage):

from allauth.account.forms import LoginForm

def serve(self, request, *args, **kwargs):
    response = super().serve(request, 'cms/article_page.html')
    response.context_data['login_form'] = LoginForm()
    return response

On utilise le LoginForm standard du package allauth; utilisez le vôtre si vous en avez un autre. On appelle d'abord la méthode super() pour obtenir la réponse par défaut. Wagtail renvoie un objet TemplateResponse qui a un champ context_data auquel on peut ajouter le formulaire.

Le code html à ajouter au modèle a juste un champ login (dans notre cas, email), un champ password et un bouton submit:

{% if not request.user.is_authenticated %}
    <div class="container mt-4 ml-0">
        <form method="POST" id="id_login_form" action="{% url 'account_login' %}" style="display: none">
            {% csrf_token %}
            <div class="row align-items-end">
                <div class="col-6 form-group">
                    {% with field=login_form.login %}{% include "account/form_field.html" %}{% endwith %}
                </div>
                <div class="col-4 form-group">
                    {% with field=login_form.password %}{% include "account/form_field.html" %}{% endwith %}
                </div>
                <div class="col-2 form-group">
                    <button id="id_submit_login_form" class="btn btn-outline-primary">{% trans "Sign in" %}</button>
                </div>
            </div>
        </form>
    </div>
{% endif %}

On masque initialement le formulaire en définissant style="display: none" dans la code form. Un lien pour le faire visible est ajouté par:

{% if not request.user.is_authenticated %}
    <div id="id_comment_invite" class="container-fluid mt-4">
        <p>{% trans "Comment on this article ("%}<a href="#" id="id_login_first_link">{% trans "sign in first" %}</a>{% trans " or confirm by name and email below)" %}</p>
    </div>
{% endif %}

Adaptez le texte à vos propres besoins. Wagtail a par défaut un bloc extra_js dans notre modèle de base; ajoutez-le si nécessaire. Puisqu'on va utiliser ajax pour envoyer notre formulaire, assurez-vous que jQuery peut le gérer. Lorsque vous avez déjà utilisé un lien jQuery pour Bootstrap, il peut s'agir d'une version réduite, qui ne peut pas gérer ajax. Copiez le lien de https://code.jquery.com/ et remplacez le lien jQuery existant dans base.html en bas:

<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>

Sur le modèle article_page.html, ajoutez:

{% block extra_js %}
    <script>
        $(document).ready(function(){

            $("#id_login_first_link").click(function(event) {
                event.preventDefault();
                $("#id_login_form").show();
            });

            ADD CODE FOR LOGIN FORM
       });
    </script>
{% endblock %}

Ce code Javascript simple affiche le formulaire de connexion lorsque l'utilisateur clique sur le lien. La commande event.preventDefault () empêche le défilement de la page. Le code du formulaire de connexion à ajouter ci-dessus est une commande ajax:

$("#id_submit_login_form").click(function(event){
    event.preventDefault();

    $.ajax({
        type:"POST",
        url: "{% url 'account_login' %}",
        data: $('#id_login_form').serialize(),
        success: function(response, status){
            $("#id_login_form").hide();
            $("#id_login_first_link").hide();
            location.reload();
       },
        error: function(xhr, status, error){
            $('#id_login_form').submit();
        }
    });
});

L'événement.preventDefault() empêche de soumettre le formulaire, ce qui amènerait l'utilisateur à une autre page. L'URL à laquelle le formulaire POST doit être envoyé est account_login, déclarée dans notre application d'authentification. Les données à envoyer sont le formulaire sérialisé. En cas de succès, on masque le formulaire et le lien et recharge la page. Le rechargement pourrait être évité, mais il nous faudrait alors régénérer un csrf token, pour éviter une erreur lorsqu'un commentaire est envoyé par la suite. De plus, on doit masquer les champs de commentaire dont on n'a pas besoin et modifier d'autres choses, telles que permettre à un utilisateur de répondre à un commentaire donné (ce qui nécessite également d'être connecté). On choisit donc ici l'option paresseuse et recharge la page. Lorsque la connexion échoue, par exemple parce que l'utilisateur n'a pas rempli le bon mot de passe, on soumet le formulaire de connexion. Cela redirige l'utilisateur vers la page générée par l'échec de la connexion. Pour nos besoins ici, on ne veut pas gérer toutes les éventualités de connexion et d'inscription sur la page de l'article.

La migration de la base de données ne devrait pas être nécessaire. Essayez si cela fonctionne comme prévu.

Une note supplémentaire sur Django Comments Xtd. Le paquet a également une option Javascript qui soumet également des commentaires via ajax, sans recharger la page. Il recherche également de nouveaux commentaires. Cela fonctionne vraiment magnifiquement hors de la boîte. Un inconvénient est qu'il n'est pas trivial de changer le style des éléments html; cela nécessite de plonger dans le code React. L'intégration de la fonctionnalité de connexion nécessite un peu plus de travail. On le laisse donc pour le moment et reviendra peut-être une autre fois.

Si vous souhaitez ajouter des formulaires modifiables à vos pages Wagtail, lisez plus.

Commentez cet article (connectez-vous d'abord ou confirmez par nom et email ci-dessous)