Mustache.js: Ajouter une option : avertissement sur les variables inconnues

Créé le 14 sept. 2016  ·  18Commentaires  ·  Source: janl/mustache.js

Parfois, nous faisons des fautes de frappe sur les noms de variables (même avec la suggestion automatique).
Ce serait formidable s'il y avait une configuration pour que moustache-js génère un avertissement sur les variables « inconnues », au lieu de renvoyer une chaîne vide (même si elle est conforme aux spécifications).

La page de manuel Moustache dit :
By default a variable "miss" returns an empty string. This can usually be configured in your Mustache library. The Ruby version of Mustache supports raising an exception in this situation, for instance.

Commentaire le plus utile

Je préférerais une erreur matérielle, de sorte que, par exemple, lors de l'utilisation avec Express, cela devienne une réponse 500 et pas seulement un journal quelque part pendant que l'utilisateur final voit une page mal rendue (potentiellement très mal rendue, selon la façon dont le variable était censée être utilisée); cela pourrait être encore plus utile en production qu'en développement local, selon la qualité de votre page 500 par rapport à la qualité des pages mal rendues pour les fonctionnalités de votre application. L'utilisation de sections pourrait toujours permettre aux modèles d'ignorer les variables manquantes même avec des erreurs matérielles pour une utilisation directe. Et toute utilisation de niveau supérieur qui doit enregistrer le problème contrôlerait le système de journalisation, nous n'aurions donc pas à nous soucier, disons, du mécanisme d'avertissement interne de Moustache qui écraserait la sortie des exécuteurs de test ou des choses comme ça.

J'ai un prototype fonctionnel sur https://github.com/ScottFreeCode/mustache.js , bien que je puisse avoir besoin d'aide pour savoir comment écrire un test pour cela.

Tous les 18 commentaires

J'adore cette fonctionnalité d'autres frameworks tout en développant localement, donc +1 de ma part ! Je pense qu'il est important que cela ait un impact minime ou nul sur les performances. Peut-être même faisable tout en gardant le noyau tel quel ? Par exemple en remplaçant certaines méthodes internes pour permettre ce type de comportement lors du développement.

Peut-être un mustache.dev.js qui est construit en utilisant mustache.js et la fonction remplace contenant la logique de vérification ?

Je préférerais une erreur matérielle, de sorte que, par exemple, lors de l'utilisation avec Express, cela devienne une réponse 500 et pas seulement un journal quelque part pendant que l'utilisateur final voit une page mal rendue (potentiellement très mal rendue, selon la façon dont le variable était censée être utilisée); cela pourrait être encore plus utile en production qu'en développement local, selon la qualité de votre page 500 par rapport à la qualité des pages mal rendues pour les fonctionnalités de votre application. L'utilisation de sections pourrait toujours permettre aux modèles d'ignorer les variables manquantes même avec des erreurs matérielles pour une utilisation directe. Et toute utilisation de niveau supérieur qui doit enregistrer le problème contrôlerait le système de journalisation, nous n'aurions donc pas à nous soucier, disons, du mécanisme d'avertissement interne de Moustache qui écraserait la sortie des exécuteurs de test ou des choses comme ça.

J'ai un prototype fonctionnel sur https://github.com/ScottFreeCode/mustache.js , bien que je puisse avoir besoin d'aide pour savoir comment écrire un test pour cela.

Hmm, donc utiliser l'existence d'un objet en tant que if ( {{#thing}} ) générerait une erreur ? (je pense que c'est assez courant)

Ou seul le rendu réel des variables ( {{ id }} ) générerait une erreur ? A quoi étais tu en train de penser?

Edit: fonctionnalité très intéressante que je +1 pour activer par défaut dans une majeure au cas où cela ne serait pas un problème.

Dans mon esprit, le premier devrait être une erreur, le second un « avertissement ».
Pour les deux, je voudrais savoir qu'il y a une valeur manquante.

Même si dans le second cas, cela pourrait ne pas se casser techniquement, cela pourrait avoir un impact énorme sur la page.

Aussi, l'inverse serait sympa : des variables inutilisées… Mais c'est beaucoup plus d'impact à faire, je pense ! :RÉ

Le 8 novembre 2016, à 14h19, David da Silva [email protected] a écrit :

Hmm, donc utiliser l'existence d'un objet comme un if ({{#thing}}) renverrait une erreur ? (je pense que c'est assez courant)

Ou seul le rendu réel des variables ({{ id }}) déclencherait une erreur ? A quoi étais tu en train de penser?

-
Vous recevez ceci parce que vous avez créé le fil.
Répondez directement à cet e-mail, consultez-le sur GitHub https://github.com/janl/mustache.js/issues/599#issuecomment -259133973, ou coupez le fil https://github.com/notifications/unsubscribe-auth/ AJ8FmSptdhysYrQpg1ODkIrm12A_TXcYks5q8HbbgaJpZM4J8lKe.

Dans mon esprit, le premier devrait être une erreur, le second un « avertissement ».
Pour les deux, je voudrais savoir qu'il y a une valeur manquante.

@MatthijsZw je vois. Je viens de me rappeler que vous pouviez stocker une null pour la propriété, ce qui serait la bonne chose à faire, et donc aucune exception ne se produirait. (en particulier pour le cas if )

Edit : Ma position actuelle est que je préférerais me tromper sur les deux. Je préfère les comportements cohérents, et vous imposeriez l'utilisation de null pour les valeurs manquantes vides, ce qui, à mon avis, est préférable.

Aussi, l'inverse serait sympa : des variables inutilisées… Mais c'est beaucoup plus d'impact à faire, je pense ! :RÉ

Je pense que ce serait cool d'obtenir en quelque sorte le schéma pour les données qu'un modèle attend, et de l'utiliser pour générer une requête GraphQL... ou quelque chose de similaire.

Après réflexion, je pense qu'une partie du problème ici est que les données manquantes sont invalides _parce que_ -- et donc _uniquement si_ -- le modèle _attend_ ces données. Ainsi, les données manquantes que le modèle afficherait simplement sont toujours invalides par cette logique, mais il est concevable qu'un modèle puisse à un endroit s'attendre à ce qu'une certaine donnée soit disponible et se brancher dessus comme une sorte d'indicateur vrai/faux (c'est donc invalide s'il n'est pas tant faux que manquant et ne répond donc pas à cette attente), mais dans un autre, il peut s'attendre à ce que les données soient disponibles ou non et se ramifient si elles le sont (auquel cas elles ne sont jamais invalides).

Dans cette perspective, utiliser null pour contrôler cela n'a pas vraiment de sens pour moi :

  • Si les données sont erronées (ne répondent pas aux attentes), comment pouvons-nous nous attendre à ce que les données erronées contrôlent le comportement du modèle concernant la gestion des données erronées ?
  • L'attente est vraiment dans le modèle de toute façon.
  • null pourrait être une valeur fausse pour les branches sur la véracité qui attendent des données et les considèrent comme invalides pour les données manquantes, mais cela nous laisse toujours le besoin de déterminer précisément si les données ont été fournies parce que nous attendez-vous à ce que les données ne soient pas remplies (même pas avec null , à moins qu'elles ne proviennent d'une source qui utilise null pour les données manquantes, par exemple SQL - et en fait, cela suggère que s'il faut traiter null comme manquant ou non doit être configurable en fonction de la source de données).

Ce dont nous avons besoin, c'est de deux types de branches, pour les différentes attentes de la part du modèle. Ce qui, à ma connaissance, est malheureux car la spécification Moustache indépendante du langage, alors qu'elle permet (mais n'impose pas) de configurer si les données manquantes sont une erreur, pour autant que je sache, n'a rien pour un type différent de branche qui différerait sur ce point. Hmm...


D'un autre côté, je pense actuellement que les données superflues/surplus/inutilisées ne sont pas vraiment une question de données invalides, c'est une question de modèle invalide s'il n'utilise pas ces données lorsque l'application/données/ modèle s'attend à ce qu'il soit utilisé. C'est-à-dire que si certains éléments sont potentiellement utilisables mais que le modèle peut décider s'ils sont pertinents, cela n'a pas d'importance si le modèle imprime ces éléments, mais si certains éléments doivent vraiment être affichés pour l'utilisateur, alors si le modèle ne le fait pas. t l'afficher c'est une erreur. Comme une sorte de renversement, l'attente se situe en dehors du modèle (dans le modèle ?) et l'invalidité de ne pas répondre à cette attente réside dans le modèle. Il vaut probablement mieux aborder cela séparément, je suppose.


Ce qui précède sont, je suppose, des opinions fortes faiblement tenues.

IMO interpréter les valeurs null comme des valeurs inexistantes est faux.

{ name: null }

cet objet a une propriété name avec une valeur fausse et ne devrait donc jamais être considéré comme invalide et donc pas une raison de le lancer.

Une vérification plus appropriée serait de vérifier si une propriété demandée a été définie comme nous le faisons dans moustache.hasProperty() .

mais dans un autre, il peut s'attendre à ce que les données soient disponibles ou non et se branchent sur le fait qu'elles le sont (auquel cas elles ne sont jamais invalides).

Ce que j'essayais de faire comprendre, c'est que, si vous vous branchez en fonction de la clé X (par exemple {{#X}} , les données fournies devraient avoir une valeur pour la clé X , soit un vrai ou valeur fausse, mais certainement pas undefined .

  • null implique "oui, je sais qu'il n'y a pas de valeur. Je marque explicitement qu'il n'y a pas de valeur".
  • undefined implique principalement que la clé X n'est même pas définie (si vous définissez une clé avec une valeur de undefined vous feriez mieux d'utiliser null ) . Et si la clé n'est pas définie, c'est soit parce que vous êtes "paresseux" en déclarant les données (par exemple, ne pas utiliser null lorsqu'une référence d'objet est manquante) ou à cause d'une erreur humaine (typo, slip, confusion)

Donc, dans ce cas, je verrais des avantages à lancer une erreur. (en essayant de créer une branche sur une clé qui a une valeur de undefined )

Dans l'autre cas, en essayant de rendre undefined ou null , vous ne savez pas s'il existe un cas d'utilisation pour cela. Peut-être que vous vous trompez aussi sur celui-là.

à moins qu'il ne provienne d'une source qui utilise null pour les données manquantes, par exemple SQL

Autant que je sache, la philosophie de Moustache n'est pas d'utiliser les modèles tels quels, mais de générer une « vue » à partir d'eux. Vous pouvez ajouter des null au cas où votre fournisseur ne le ferait pas.

Je pense actuellement que les données superflues/surplus/inutilisées ne sont pas vraiment une question de données invalides, c'est une question de modèle invalide s'il n'utilise pas ces données lorsque l'application/données/modèle s'y attend être utilisé

Hmm, je pense qu'il est assez courant de ne pas utiliser toutes les données fournies. J'ai lancé l'idée principalement pour les subtilités de l'outillage, comme la génération de requêtes GraphQL que j'ai suggérée.

si certaines choses doivent vraiment être affichées à l'utilisateur, alors si le modèle ne les affiche pas, c'est une erreur

Mais qui/qu'est-ce qui décide quelles « trucs doivent vraiment être affichés à l'utilisateur » ? L'écrivain modèle je suppose? Si vous forcez les utilisateurs à utiliser toutes les données de la vue, vous les forcez à générer une vue personnalisée pour chaque modèle qu'ils ont l'intention de rendre.

Remarque : mon cas d'utilisation était une configuration manuelle sans branchement.

J'ai demandé à « d'autres personnes » de créer les données (événements) manuellement et dans ce cas, je n'avais aucun moyen de vérifier qu'elles avaient rempli tous les champs ou fait des fautes de frappe dans les noms de variables.

Mon modèle dirait « {{ event.name }} le {{ event.date }} ». Dans ce cas, une valeur manquante créerait une page horrible.
Tous les champs étaient obligatoires, donc ajouter une logique pour ne pas afficher {{ event.date }} n'aurait pas de sens.

Dans ce cas, les variables « non utilisées » seraient également intéressantes à connaître, pour vérifier les fautes de frappe ou les éléments qu'ils ont ajoutés en pensant qu'ils apparaîtraient « par magie » sur la page :)

Je suis sûr que ce cas d'utilisation viole l'idéologie de Moustache d'une manière ou d'une autre, mais c'est un scénario réel.
Et ce serait formidable pour les deux situations (valeurs manquantes + valeurs inutilisées) de générer un avertissement.

Le 9 novembre 2016, à 10h53, David da Silva [email protected] a écrit :

mais dans un autre, il peut s'attendre à ce que les données soient disponibles ou non et se branchent sur le fait qu'elles le sont (auquel cas elles ne sont jamais invalides).

Ce que j'essayais de transmettre, c'est que, si vous créez une branche en fonction de la clé X (par exemple {{#X}}, les données fournies devraient avoir une valeur pour la clé X, soit une valeur vraie ou fausse, mais certainement pas indéfinie.

null implique "oui, je sais qu'il n'y a pas de valeur. Je marque explicitement qu'il n'y a pas de valeur".
undefined implique principalement que la clé X n'est même pas définie (si vous définissez une clé avec une valeur indéfinie, vous feriez mieux d'utiliser null). Et si la clé n'est pas définie, c'est soit à cause d'être « paresseux » en déclarant les données (par exemple, ne pas utiliser null lorsqu'une référence d'objet manque) ou à cause d'une erreur humaine (typo, slip, confusion)
Donc, dans ce cas, je verrais des avantages à lancer une erreur. (en essayant de créer une branche sur une clé qui a une valeur indéfinie)

Dans l'autre cas, en essayant de rendre indéfini ou nul, je ne sais pas s'il existe un cas d'utilisation pour cela. Peut-être que vous vous trompez aussi sur celui-là.

à moins qu'il ne provienne d'une source qui utilise null pour les données manquantes, par exemple SQL

Autant que je sache, la philosophie de Moustache n'est pas d'utiliser les modèles tels quels, mais de générer une « vue » à partir d'eux. Vous pouvez ajouter des valeurs nulles au cas où votre fournisseur ne le ferait pas.

Je pense actuellement que les données superflues/surplus/inutilisées ne sont pas vraiment une question de données invalides, c'est une question de modèle invalide s'il n'utilise pas ces données lorsque l'application/données/modèle s'y attend être utilisé

Hmm, je pense qu'il est assez courant de ne pas utiliser toutes les données fournies. J'ai lancé l'idée principalement pour les subtilités de l'outillage, comme la génération de requêtes GraphQL que j'ai suggérée.

si certaines choses doivent vraiment être affichées à l'utilisateur, alors si le modèle ne les affiche pas, c'est une erreur

Mais qui/qu'est-ce qui décide quelles « trucs doivent vraiment être affichés à l'utilisateur » ? L'écrivain modèle je suppose? Si vous forcez les utilisateurs à utiliser toutes les données de la vue, vous les forcez à générer une vue personnalisée pour chaque modèle qu'ils ont l'intention de rendre.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub https://github.com/janl/mustache.js/issues/599#issuecomment -259374603, ou coupez le fil https://github.com/notifications/unsubscribe-auth/ AJ8FmcFicDWYjSqibyWac-Sqjg-iFetnks5q8ZgqgaJpZM4J8lKe.

Je suis sûr que ce cas d'utilisation viole l'idéologie de Moustache d'une manière ou d'une autre, mais c'est un scénario réel. Et ce serait formidable pour les deux situations (valeurs manquantes + valeurs inutilisées) de générer un avertissement.

Les deux semblent réalisables. Cela pourrait être utile pour CI.

Je préférerais voir le paramètre directement dans la vue pour le débogage.

Mon cas d'utilisation est un peu différent : j'utilise Moustache pour transformer les modèles Terraform à l'aide de Gulp. Une variable manquante peut empêcher les instances de démarrer correctement, en particulier lors de la substitution dans des chaînes de forme libre. J'ai mis au point un patch singe rapide pour obtenir cette fonctionnalité, mais ce n'est pas idéal :

var mustache = require("mustache");

var errors = [];
var lookup = mustache.Context.prototype.lookup;

mustache.Context.prototype.lookup = function(name) {
    var value = lookup.bind(this)(name);

    if (value === undefined) {
        console.error("Unknown symbol", name);
        errors.push(name);
    }

    return value;
}

var render = mustache.render;

mustache.render = function(template, view, partials) {
    var result = render.bind(this)(template, view, partials);

    if (errors.length > 0) {
        throw {message: "Unknown symbols: " + errors.join(", ")};
    }

    return result;
}

Remarques:

  • Il ne vous donne pas de numéros de ligne ou de noms de symboles complets
  • C'est probablement totalement dangereux si vous travaillez dans un environnement multithread

Cependant, cela a bien fonctionné pour mes besoins et je suis sûr que quelqu'un peut l'adapter si nécessaire.

L'utilisation de Moustache comme moteur de création de modèles dans tout type d'environnement de gestion de configuration nécessite des erreurs matérielles sur les variables manquantes. J'ai un cas d'utilisation similaire à @steverukuts , transformant les documents de déploiement de kubernetes. Les variables manquantes sont toujours des erreurs dans ce cas d'utilisation.

@stefaneg quelques mois après avoir écrit qu'en fait, j'ai découvert que Terraform prend en charge la configuration écrite au format JSON, alors maintenant je l'utilise au lieu d'utiliser Moustache. C'est beaucoup mieux et plus programmable. Nous avons maintenant déprécié l'utilisation de Moustache pour cela et il sera supprimé dans la prochaine révision de notre pipeline de déploiement.

Après avoir consulté la documentation de déploiement de Kubernetes, je constate qu'il s'agit de fichiers YAML. La plupart des langages de programmation ont des bibliothèques qui peuvent lire et écrire YAML, je vous suggère donc de le faire à la place. De mon expérience, j'ai appris que lorsque vous essayez de manipuler un format lisible par machine, vous avez presque toujours une meilleure option que Moustache.

Remarque : bien que je n'utilise plus Moustache pour rien, je pense toujours qu'il s'agit d'une demande de fonctionnalité valide.

La solution consiste à utiliser handlebars , qui prend en charge la même syntaxe, et a également une option stricte qui est exactement ce qui est nécessaire dans ce cas d'utilisation.

@steverukuts Vous avez raison sur la manipulation du format lisible par machine, si vous avez une manipulation prédéterminée que vous devez prendre en charge, et surtout si vous avez besoin d'avoir une certaine intelligence intégrée. Pour un outil de configuration ouvert, cela devient très vite trop rigide, d'où la nécessité de créer des modèles. Essayez d'écrire un outil prenant en charge l'insertion de valeurs arbitraires à des endroits arbitraires et... vous aurez très bientôt un moteur de création de modèles.

Au travail, nous avons utilisé kontemplate pour configurer les ressources Kubernetes ces dernières années. Il s'agit essentiellement du moteur de création de modèles, avec quelques fonctions pratiques de sprig et des fonctions personnalisées dans ce projet. Il a été conçu comme une approche plus légère que la barre par exemple.

En ce qui concerne la discussion ci-dessus ; il explosera également sur des variables inconnues.

La solution consiste à utiliser handlebars , qui prend en charge la même syntaxe, et a également une option stricte qui est exactement ce qui est nécessaire dans ce cas d'utilisation.

Ce problème m'a également obligé à utiliser des guidons. C'est dommage que ce ne soit pas pris en charge dans la moustache.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

chlab picture chlab  ·  11Commentaires

barbalex picture barbalex  ·  5Commentaires

funston picture funston  ·  7Commentaires

Immortalin picture Immortalin  ·  12Commentaires

rlightner picture rlightner  ·  7Commentaires