Oct/090
Mise en oeuvre de l’authentification (3 - niveau navigateur)
On met en oeuvre la partie utilisateur/interface.
Tout d’abord, on rajoute un lien dans l’en-tête du site afin de diriger sur l’url /login.html
(priv/templates/views/index.haml
) :
%body #header #ids Guest %a{ 'data-event' => "login:start", :href => "/login.html" } (login)
Ce lien possède un attribut particulier data-event
. Cet attribut est correct selon les normes HTML 5, et peut être utilisé sans problème dès aujourdh’ui. Pour plus d’informations, vous pouvez lire cet article de John Resig.
Cet attribut personnalisé va nous permettre de définir des liens demandant un déclenchement d’événement lors d’un click. Cet événement est la valeur de l’attribut lui même. Le comportement générique sera de ne pas déclencher le click normal (navigateur) mais de le remplacer par le déclenchement de l’événement.
On peut alors intercepter le click sur tout lien de ce type :
$("[data-event]").live("click", function() { console.log("Event triggered -> " + $(this).attr("data-event")); $(this).trigger($(this).attr("data-event")); return false; });
Ici, on utilise le mécanisme d’event delegation
(voir cet article ou celui ci) afin de répercuter ce comportement sur l’ensemble des éléments existants ou à venir, c’est à dire ajoutés par manipulation du DOM.
La réaction à un tel événement sera appliquée de cette façon :
$.extend({ displayLogin: function(event, status) { url = "/login.html"; //$(event.target).attr("href")); $("#main").load(url); } }); $(function() { $(document).bind("login:start", $.displayLogin); });
Tout ceci peut paraître plus complexe que nécessaire. Cependant, (a) de nombreux comportements seront cablés de cette manière et (b) cela permet de réutiliser de façon expressive les événements comme décrit ci dessous (et il se peut que la suite du développement remette tout ce fonctionnement en cause).
En effet, lors du click sur un lien « privé », c’est à dire nécessitant une authentification, on va réexploiter ce comportement en modifiant notre méthode ajax globale de cette manière :
$.extend({ globalAjaxErrorEvent: function (event, request, ajaxOptions, thrownError) { msg = request.statusText; if (request.status == 403) { msg = $.messages.forbidden; $(this).trigger("login:start"); } else if (request.status == 502) { msg = $.messages.server_error; } $("#global_msg").text(msg); } });
Le résultat est que tout lien renvoyant une erreur 403 affichera automatiquement la mire d’authentification !
Pour illustrer d’avantage ce principe de réutilisabilité, voici l’équivalent de ce qui est fourni comme page de login
:
%form %ul %li %label Login %input{ :type => "textfield" } %li %label Password %input{ :type => "password" } .actions %input{ :type => "button", :value => "login" } or %a{ "data-event" => "login:cancel", :href => "/index.html" } Cancel
Ce qui génère ce code HTML :
<a href="/index.html" data-event="login:cancel">Cancel</a>
La réaction à un événement d’annulation est codé comme suit :
$.extend({ cancelLogin: function(event) { ... } }); $(document).bind("login:cancel", $.cancelLogin);
Au final, le rattachement d’un comportement à un événement utilisateur et tag HTML est simplifié, et les vues HTML n’ont aucun comportement cablé en dur (non-obtrusive javascript).
Il nous reste à transmettre et valider les données utilisateur.