Dans cet article nous verrons comment mettre en place un système de complétion automatique d'un champ texte d'une page web. Le système que nous développerons fonctionnera comme suit. L'utilisateur de notre application web (écrite en golang) accédera à une page web puis commencera à saisir du texte dans un champ (INPUT). À partir du quatrième caractère, le système complétera sa saisie en lui suggérant des possibilités sur la suite du mot qu'il est en train de taper.
Exemple de champ texte à complétion automatique
Les mots possibles seront issus d'un corpus contenant presque exhaustivement tous les mots de la langue française. Dès la 4ème lettre entrée dans le champ, un script en JavaScript et jQuery interrogera en AJAX une application écrite en go avec les caractères déjà saisis. Cette application côté serveur interrogera un index avec la chaîne de caractères reçue et évaluera quel pourrait être le mot complet (celui que l'utilisateur a l'intention de saisir). En retour, ce code serveur enverra une liste de mots possibles et, pour chaque mot, un score de similitude entre ce qui a déjà été saisi et le mot proposé (la liste des mots sera classée en fonction de ce score de probabilité).
La liste des mots de la langue française est issue d'un travail universitaire : elle a été générée à partir du dictionnaire Francais-Gutenberg de Christophe Pythoud. Ce fichier est disponible ici et il contient 336531 entrées.
Il est préférable de convertir ce fichier de l'ANSI à l'UTF-8 sans BOM avant de commencer à l'utiliser.
Notre application go utilisera la bibliothèque gocleo. Il s'agit du portage en golang de la bibliothèque JAVA utilisée par LinkedIn dans son système de suggestion (lien vers le projet cleo).
Cette bibliothèque n'est pas encore complète, mais c'est une bonne base de code qui fonctionne et que vous pourrez facilement intégrer à vos projets en la modifiant. Par exemple, elle utilise un fichier texte pour construire l'index des mots à suggérer. Vous pourriez la modifier afin qu'elle tire le corpus d'une base de données.
Dans mon exemple, j'utilise Boostrap 2.3.1 ainsi le plug-in typeahead (voir le code source côté client). Le plug-in typeahead permet de créer une boîte de texte à complétion automatique. Le principe étant que l'utilisateur commence à saisir un texte et une liste de suggestion apparaît sous le champ.
On peut faire plus minimal ou utiliser la bibliothèque Gorilla, voire un framework MVC. Il ne s'agit que d'un exemple. Le principe est d'importer la bibliothèque gocleo. Cette dernière contient une fonction init qui ajoutera un contrôleur cleo à votre application web. Il est de votre responsabilité de démarrer le serveur web. Le code ci-après répond à ces deux adresses :
package main import ( "net/http" "html/template" "github.com/jamra/gocleo" ) var templates = template.Must(template.ParseFiles("cleo.html")) type Page struct { Title string } func main() { cleo.BuildIndexes("liste.txt", nil) http.HandleFunc("/home", homeHandler) err := http.ListenAndServe(":9999", nil) if err != nil { panic(err) } } func homeHandler(w http.ResponseWriter, r *http.Request) { p := Page{Title: "Test de Cleo"} err := templates.ExecuteTemplate(w, "cleo.html", p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
Sous Windows, l'exécutable pèse environ 8 Mo et occupe 49Mo de RAM une fois le corpus chargé. Ce qui reste raisonnable pour une application web complète.
Le code est assez simple : il scrute toute modification du champ texte et si le champ contient plus de quatre caractères, il interroge le serveur afin d'obtenir une liste de suggestions. Étant donné que le plug-in typeahead s'attend à avoir une liste de chaînes de caractères et que gocleo retourne un tableau listant les mots possibles et le score associé, on contruit une liste de chaînes de caractères en extrayant ce qui nous interrésse dans la réponse à notre requête AJAX.
J'utilise des CDN pour ne pas avoir à servir de ressources statiques.
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>{{ .Title }}</title> <link type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet"/> <link type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap-responsive.min.css" rel="stylesheet"/> <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"> <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script> <script type="text/javascript" src="http://cdn.jsdelivr.net/bootstrap/2.3.2/js/bootstrap-typeahead.js"></script> </head> <body> <div class="container-fluid"> <div class="row-fluid"> <div class="span12"> <label for="txtWord">Essayez-moi</label> <input id="txtWord" name="txtWord" type="text" class="typeahead" autocomplete="off" placeholder="commencez à saisir" /> <script type="text/javascript"> $(document).ready(function() { $('#txtWord').typeahead({ source: function (query, process) { if ($("#txtWord").val().length >= 4) { return $.ajax({ url: '/cleo', type: 'get', data: { query: query }, dataType: 'json', success: function (result) { var index; var resultList = []; for (index = 0; index < result.length; index++) { resultList.push(result[index].Word); } return process(resultList); } }); } } }); }); </script> </div> </div> </div> </body> </html>
Une traduction du blog officiel de golang expliquant le mécanisme de la réflexion en Go. Lire »
Traduction d'un article du blog officiel expliquant comment échanger des données entre deux programmes golang grâce à un format natif Lire »
La bibliothèque standard de go ne gère pas les variables de session d'une application. Il existe une solution avec le toolkit Gorilla Lire »
Exemples d'utilisation du type chan et des go routines stateful et stateless Lire »
Préconisations officielles pour la gestion des erreurs dans un programme golang. Cet article complète les explications sur panic, defer et recover Lire »
Soyez le premier à commenter cet article
Tous les commentaires sont soumis à modération. Les balises HTML sont pour la plupart autorisées. Les liens contextuels et intéressants sont en follow.