Filemaker est un logiciel puissant, mais ancien et dont l’ergonomie a peu évolué. Depuis quelques années, des systèmes de «tags» ou mots-clés sont apparus dans la plupart des logiciels permettant de gérer des données. Filemaker n’offre aucun système de tags pour classer ses enregistrements, mais il permet d’implémenter un tel système soi-même. Cet article a pour but de décrire une des nombreuses manière de procéder pour y parvenir.
Logique relationnelle
Pour les besoins de l’exemple, on prendra une base de données très simple : une table contient des articles, et l’on doit pouvoir ajouter des tags à ces articles. Il faut donc, pour commencer, deux tables : une table pour les articles, et une table pour les tags.
La table «Articles» contient 3 colonnes (ou «rubriques») : une colonne id contenant un numéro de série (clé primaire) auto-incrémenté et non modifiable par l’utilisateur ; une colonne Titre pour stocker le titre de chaque article et une colonne Texte pour en stocker le contenu. La table «Tags» contient 2 colonnes : une colonne id, comme pour la table Articles, et une colonne Tag destinée à contenir le mot-clé.
Table Articles <ul> <li>id Type: Nombre | Entrée auto Numéro de série, Entrées automatiques non modifiables</li> <li>Titre Type: Texte</li> <li>Texte Type: Texte</li> </ul> <p>Table Tags <ul> <li>id Type: Nombre | Entrée auto Numéro de série, Entrées automatiques non modifiables</li> <li>Tag Type: Texte</li> </ul> <p>Chaque article peut être associé à plusieurs mots-clés, car c’est le principe même des tags : ils permettent une classification transversale des enregistrements (par opposition à une classification hiérarchique, verticale, dans laquelle une sous-catégorie ne peut appartenir qu’à une seule super-catégorie). Chaque mot-clé peut être associé à plusieurs articles, qui correspondent à un thématique précise. Par conséquent, la relation entre la table Articles et la table Tags est de type many-to-many. Pour établir ce genre de relations, dans Filemaker qui ne connaît que les relations one-to-many, il faut créer une table supplémentaire, dite «table de jointure» ou join table. Cette table contient 2 colonnes : une colonne article_id, liée à la colonne id de la table Articles, et une colonne tag liée à la colonne Tag de la table Tags.
Table join_table <ul> <li>article_id Type: Nombre</li> <li>tag Type: Texte</li> </ul> <p>Une fois les trois tables créées (Articles, Tags, join_table), il faut établir les liens entre ces tables. Attention : le lien entre la table Articles et la join_table ne doit pas permettre de créer automatiquement de nouveaux enregistrements. La création de nouveaux enregistrements sera réalisée par des scripts. Si le lien entre les deux tables permet la création automatique de nouveaux enregistrements, deux tags seront créés : le premier automatiquement, il restera vide, et le second par le script.
- Articles::id => join_table::article_id
- join_table::tag => Tags::Tag
Modèles
Un seul modèle sera modifié : le modèle correspondant à la table Articles, sur lequel on associera les tags à l’article actif. Il est cependant nécessaire de conserver les modèles relatifs aux deux autres tables, avec des champs de texte correspondant à chaque rubrique de ces tables, car ils seront utilisés dans des scripts.
Sur le modèle de la table Article, on veut pouvoir ajouter des tags à l’article actif, d’une certaine manière et sous certaines conditions.
- Tous les tags doivent être affichés à la suite les uns des autres.
- Lorsqu'on a terminé d'écrire un tag, on doit pouvoir en écrire un autre sans utiliser la souris, en appuyant sur la touche Entrée. Cette touche doit donc 1) valider le premier tag, 2) en créer un second.
- Il ne doit pas être nécessaire d'écrire les tags en entier : ceux-ci doivent être suggérés par le logiciel lorsqu'on écrit les premières lettres.
- On doit pouvoir accéder d'un clic à la liste des articles correspondant à un tag donné.
Pour satisfaire ces conditions, le mieux est de créer un portail qui affiche les enregistrements de la table join_table et qui contient un champ correspondant à la rubrique tag de cette table.
On crée ensuite un bouton pour afficher la liste des articles correspondant au tag choisi. Ce bouton doit lancer l’action Activer enregistrements liés dans le modèle Tags.
Scripts
Les scripts permettent de mettre en oeuvre la logique comportementale du logiciel. Ce sont eux qui réalisent les opérations permettant de créer de nouveaux tags automatiquement, et d’associer les tags aux articles.
La logique des scripts est la suivante :
- Si le tag existe déjà, aucun nouveau tag ne doit être créé, il faut simplement associer le tag existant à l'article actif.
- Si le tag n'existe pas, il faut le créer avant de pouvoir l'associer à l'article actif.
- Dans les deux cas, il faut associer le tag, créé ou existant, à l'article actif.
- Tout cela doit se dérouler sans intervention de l'utilisateur, et sans le déranger.
On crée donc 3 scripts.
Le premier script crée un nouvel enregistrement dans la table join_table, qui correspond au tag que l’utilisateur vient d’écrire. Pour chaque tag, il existe un enregistrement dans la table join_table, même si le tag existe déjà dans la table Tags. On n’a donc pas à se préoccuper de savoir si telle ou telle condition est remplie : l’enregistrement est toujours créé. Le script est par conséquent relativement simple :
Script 1 : Ajouter Tag
- Gestion erreurs [ Oui ]
- Définir variable [ $articleid; Valeur :Articles::id ]
- Activer modèle [ “join_table” (join_table) ]
- Nouvel enreg./requête
- Définir rubrique [ join_table::article_id; $articleid ]
- Activer modèle [ modèle d'origine ]
- Rafraîchir fenêtre [ Vider résultats de jointure en mémoire cache ]
- Activer rangée externe [ Sélectionner; Dernièr(e) ]
- Activer rubrique [ join_table::tag ]
- Fin de script [ ] </ul>
- Gestion erreurs [ Oui ]
- Définir variable [ $tag; Valeur :join_table::tag ]
- Activer modèle [ “Tags” (Tags) ]
- Mode Recherche [ ]
- Définir rubrique [ Tags::Tag ]
- Exécuter la requête [ Requêtes de recherche définies : Rechercher des enregistrements; Critères : Tags::Tag: “$tag” ] [ Rétablir ]
- Si [ Obtenir ( NombreEnregTrouvés ) > 0 ]
- Définir variable [ $tagid; Valeur :Tags::id ]
- Sinon
- Nouvel enreg./requête
- Insérer résultat du calcul [ Tags::Tag; $tag ] [ Sélectionner ]
- Valider enreg./requêtes [ Sans fenêtre ]
- Définir variable [ $tagid; Valeur :Tags::id ]
- Fin de si
- Afficher tous les enreg.
- Activer modèle [ modèle d'origine ]
- Si [ Code ( Obtenir ( FrappeClavierDéclencheur ) ) =13 Or Code ( Obtenir ( FrappeClavierDéclencheur ) ) =10 ]
- Valider enreg./requêtes [ Sans fenêtre ]
- Exécuter script [ “Script 1 : Ajouter Tag” ]
- Fin de script [ Résultat : False ]
- Fin de si
- Fin de script [ Résultat : True ]
Le deuxième script vérifie dans la table Tags si le tag que l'on vient de créer dans la table join_table existe déjà. Si tel n'est pas le cas, il le crée. Le script récupère l'id du tag créé ou utilisé, dansla table Tags, sans toutefois l'utiliser : on peut imaginer de l'utiliser pour informer l'utilisateur de la création du tag, pour consigner la création du tag dans un log, ... les possibilités sont nombreuses.
Script 2 : Nouveau Tag
Le dernier script a pour but d'intercepter la touche Entrée ou Retour : c'est une touche spéciale, car lorsqu'on appuie dessus, le tag doit être validé et le logiciel doit nous offrir la possibilité d'en écrire un autre.
Script 3 : touche entrée
Reste à assigner ces scripts à des déclencheurs, afin qu'ils soient exécutés au bon moment. Le Script n°3 : touche entrée doit être assigné à la rubrique join_table::tag dans le portail du modèle Articles, sur l'évènement SurFrappeClavierObjet. Le Script n°2 : Nouveau Tag doit être assigné à la même rubrique, sur l'événement SurEnregistrementObjet.
Il faut ensuite créer un bouton et lui assigner le Script n°1 : Ajouter Tag afin de créer le premier tag d'un article (les tags suivants seront créés par la touche Entrée).
Pour finir, on crée une liste de valeurs contenant les enregistrements de la rubrique Tag de la table Tags, et on l'assigne au champ tag du portail sur le modèle Articles. Ce champ devrait être une liste déroulante avec l'option compléter automatiquement avec la liste des valeurs activée.
Conclusion
Cette solution, pour rajouter un système de mots-clés dans les bases de données Filemaker, n'est pas la seule qui existe.
On pourrait imaginer un système différent, et certainement plus cohérent d'un point de vue de logique relationnelle : une table Globals contenant une colonne tag avec stockage global ; un champ de texte représentant le contenu de cette colonne sur le modèle Articles et un script qui rajoute le mot-clé de ce champ de texte dans la join table. On pourrait ainsi laisser Filemaker créer lui-même les nouveaux enregistrements, par le biais du lien entre les tables. La join table pourrait être plus classique, et contenir deux foreign keys : article_id et tag_id, au lieu de la rubrique tag qui contient le texte complet du mot-clé.
On doit également pouvoir imaginer d'autres variantes. Le système présenté ici étant très basique, chaque lecteur pourra concevoir sa propre variante, en modifiant le comportement des scripts, en rajoutant des conditions et des contrôles, etc. La base de données exemple élaborée dans cet article peut être téléchargée en suivant le lien ci-dessous ; elle fournira un premier support à ceux qui voudront aller plus loin en adaptant le système de tags à leurs besoins.