Extensions de la syntaxe Jelly

  • Rversion finale: Zurich
  • Mis à jour 31 juil. 2025
  • 10 minutes de lecture
  • La syntaxe Jelly d’Apache est utilisée pour afficher des formulaires, des listes, des pages d’interface utilisateur et bien d’autres choses rendues dans ServiceNow.

    Avec Jelly, la logique peut être intégrée dans le contenu statique et les valeurs calculées peuvent être insérées dans le contenu statique.

    Important :
    Cette fonctionnalité nécessite une connaissance d’Apache Jelly (un moteur de script et de traitement basé sur Java et XML pour transformer XML en code exécutable).

    Cette page d’Apache contient un résumé des balises Jelly standard : http://commons.apache.org/jelly/tags.html

    Espaces de noms

    Jelly inclut souvent plusieurs espaces de noms lors de l’invocation de balises.

    Les espaces de noms « j » sont des Jelly standard tandis que les espaces de noms « g » sont uniques aux ServiceNow scripts. Par exemple, la balise <g :evaluate> est fournie par ServiceNow pour vous permettre de calculer une valeur à l’aide de JavaScript. La balise Jelly standard <j :test> est utilisée pour évaluer une condition.

    Phases

    Habituellement, il y a deux phases indiquées par des espaces de noms <j> par rapport à <j2> et <g> par rapport à <g2>.

    Les espaces de noms sans le « 2 » se produisent dans la première phase de traitement et sont mis en cache sauf lorsqu’ils sont utilisés dans une page d’interface utilisateur. Ceux avec le « 2 » ne sont jamais mis en cache. Des précautions doivent être prises lors de la sélection de l’utilisation de la phase 1 ou de la phase 2 pour l’efficacité et les résultats corrects.

    En plus des espaces de noms, la syntaxe utilisée pour insérer des valeurs dans le contenu statique diffère selon la phase de fourniture de la valeur. Un dollar avec des accolades entourant une valeur insère la valeur dans la phase 1. Par exemple, ${jvar_ref} insère la valeur jvar_ref pendant la phase 1 du processus jelly. Un dollar entouré d’une valeur entre crochets insère la valeur de la phase 2. Par exemple, $[jvar_ref] insère la valeur jvar_ref pendant la phase 2. Une valeur entourée de guillemets est traitée comme une chaîne. Par exemple, « [jvar_ref] » insère la valeur jvar_ref sous forme de chaîne pendant la phase 2.

     <script>
    if (confirm("$[gs.getMessage('home.delete.confirm') ]"))
       ...
    </script>
    <input type="hidden" id="${jvar_name}" name="${jvar_name}" value="${jvar_value}" class="${jvar_class}" />

    Si tests

    Vous pouvez utiliser des instructions if dans les scripts Jelly.

    Tester si quelque chose est vrai ou non peut être effectué comme suit :

    <j:if test="${jvar_something}">...do something...</j:if>
    <j:if test="${!jvar_something}">...do something...</j:if>
    La raison pour laquelle cette affirmation fonctionne, c’est que, dans Jelly, un terme comme jvar_something est « véridique » dans une balise if if :
    1. il s’agit d’une valeur booléenne et vraie
    2. il s’agit d’une chaîne et = « true », « yes », « on » ou « 1 »

    Tester l’existence de quelque chose peut être effectué comme suit :

    <j:if test="${empty(jvar_something)}">...do something...</j:if>
    La raison pour laquelle cette instruction fonctionne est que la fonction vide JEXL renvoie true si son argument est :
    1. null
    2. une chaîne vide
    3. Une collection de longueur nulle
    4. une carte sans clés
    5. un tableau vide
    Remarque :
    Vous ne pouvez pas mélanger des variables javascript et jvar dans une expression JEXL. Ils doivent être divisés en expressions distinctes.

    Set_If

    Attribue à une variable l’une des deux valeurs différentes selon qu’un test est vrai ou faux.

    <g2:set_if var="jvar_style" test="$[gs.getPreference('table.compact') != 'false']" 
       true="margin-top:0px; margin-bottom:0px;" 
       false="margin-top:2px; margin-bottom:2px;" />

    <g :insert> par rapport à <g :inline> par rapport à <g :call>

    Cette page fournit une explication comparative de trois balises : <g :insert>, <g :inline> et <g :call>.

    <g :insérer>

    La balise <g :insert> insère un fichier Jelly dans votre Jelly dans un nouveau contexte. Cela signifie que vous ne pouvez pas accéder aux variables précédemment établies dans votre Jelly.

    <g:insert template="get_target_form_function.xml" />

    <g :inline>

    La balise <g :inline> insère un fichier Jelly dans votre Jelly dans le même contexte. Cela signifie que la Jelly insérée peut accéder aux variables que vous avez précédemment établies et qu’elle peut modifier les valeurs de ces variables.

    <g:inline template="element_default.xml" />

    <g :appel>

    Pour une meilleure encapsulation, la balise <g :call> peut être utilisée. Votre fonction n’aura accès qu’aux valeurs qui lui sont transmises. Le contexte Jelly sera le même après un appel qu’avant l’appel. Cela signifie que vous ne pouvez pas définir une variable globale ici et la lire plus tard. Cela signifie également que vous ne pouvez pas définir par erreur une variable globale appelée « jvar_temp » et écraser une variable sur laquelle quelqu’un d’autre s’appuyait.

    Le passage des valeurs, si nécessaire, se fait explicitement en incluant le nom du paramètre sur la ligne <g :call> suivi du signe égal suivi de la valeur entre guillemets :

    <g:call function="collapsing_image.xml" id="${jvar_section_id}" image="$[jvar_cimg]" 
       first_section_id="${jvar_first_section_id}" image_alt="${jvar_cimg_alt}"/>

    Si des valeurs sont passées, et que vous souhaitez avoir des paramètres par défaut ou obligatoires, votre Jelly référencé dans la fonction doit alors inclure une ligne pour déclarer si les paramètres sont obligatoires ou ont une valeur par défaut :

    <g:function id="REQUIRED" image="REQUIRED" image_prefix="" image_alt="REQUIRED"/>

    L’exemple ci-dessus indique que 3 des paramètres sont requis et qu’un paramètre est une option avec une valeur par défaut vide. Notez que si vous ne transmettez pas de valeurs ou si vous souhaitez avoir des valeurs par défaut ou obligatoires, vous n’avez pas du tout besoin d’inclure la ligne <g :function>. En général, cependant, vous voudrez inclure une ligne <g :function>.

    La valeur peut ensuite être référencée dans votre modèle en ajoutant le préfixe « jvar_ » au nom du paramètre :

    <img id="img.${jvar_id}" src="images/${jvar_image}" alt="${jvar_image_alt}"     onclick="toggleSectionDisplay('${jvar_id}', '${jvar_image_prefix}','${jvar_first_section_id}');"/>

    Pour <g :call>, les paramètres peuvent également être passés implicitement sous forme de liste de variables nommées dans un paramètre « arguments » :

     <g:call function="item_link_default.xml" arguments="sysparm_view,ref_parent,jvar_target_text"/>

    Comme alternative au passage de variables dans la fonction via des arguments de balise séparés, il est possible de passer une liste de variables dans un seul argument 'arguments'. Toutes les variables identifiées par leur nom (séparées par des virgules) dans le argument paramètre sont réintroduites dans la fonction sous exactement le même nom (par exemple, à l’intérieur du modèle de fonction, nous aurions des variables sysparm_view, ref_parent et jvar_target_text à notre disposition).

    Le modèle de fonction peut renvoyer une valeur au modèle appelant à l’aide de l’attribut return= . Dans la fonction, la variable jvar_answer définit la valeur de retour.

    <g:call function="item_body_cell_calc_style.xml" arguments="jvar_type" return="jvar_style"/>

    <g :évaluer>

    La balise <g :evaluate> est utilisée pour évaluer une expression écrite en JavaScript de Rhino et parfois pour définir une variable à la valeur de l’expression.

    La dernière instruction de l’expression est la valeur que la variable contiendra.

    <g2:evaluate var="jvar_page" jelly="true">
         var page = "";
         var pageTitle = "";
         var pageGR = new GlideRecord("cmn_schedule_page");
         pageGR.addQuery("type", jelly.jvar_type");
         pageGR.query();
         if (pageGR.next()) {
            page = pageGR.getValue("sys_id");
            pageTitle = pageGR.getDisplayValue();
         }
         page;
    </g2:evaluate>
    <g2:evaluate var="not_important" expression="sc_req_item.popCurrent()"/>

    object="true »

    Si vous souhaitez que l’évaluation renvoie un objet (par exemple un tableau), utilisez l’argument object="true ».

    <g2:evaluate object="true" var="jvar_items" expression="SncRelationships.getCMDBViews()" />

    jelly="true »

    Si vous souhaitez accéder aux variables Jelly dans une évaluation, incluez jelly="true » dans l’évaluation et ajoutez « jelly. » avant le nom de la variable Jelly. Par exemple, pour accéder à GlideJellyContext :

    <g2:evaluate var="jvar_row_no" jelly="true">
       var gf = jelly.context.getGlideForm();
       var row = gf.getRowNumber();
       row;
    </g2:evaluate>

    Un autre exemple d’accès à un jvar en utilisant le paramètre jelly="true ». La valeur de jvar_h a été définie précédemment et nous pouvons y accéder dans l’évaluation :

    $[NLBR:jvar_h.getHTMLValue('newvalue')]
    <g2:evaluate var="jvar_fix_escaping" jelly="true">
        var auditValue = jelly.jvar_h.getHTMLValue('newvalue');
        gs.log("************ " + auditValue);
    </g2:evaluate>

    copyToPhase2="true »

    Si vous avez besoin de prendre les résultats d’une évaluation qui se produit en phase 1 et de les propager à la phase 2, utilisez copyToPhase2="true ». Il existe une certaine protection contre l’évasion dans cette utilisation. Par exemple :

    <g:evaluate var="jvar_has_special_inc" copyToPhase2="true">
       var specialInc = gs.tableExists("special_incident");
       specialInc;
    </g:evaluate>
    $[jvar_has_special_inc]

    Si vous n’avez pas besoin d’évaluer quelque chose, vous pouvez le faire plus directement. Attention aux problèmes d’échappement ici (les guillemets doubles dans jvar_rows causeraient un problème dans l’exemple) :

    <j2:set var="jvar_rows" value="${jvar_rows}"/>

    <g :point d’arrêt/>

    Cette balise peut être utilisée pour afficher les variables Jelly actuelles et leurs valeurs dans le journal.

    Assurez-vous de supprimer cette balise avant d’aller en production.

    <g :ui_form/>

    Cette balise définit un formulaire sur la page de l’interface utilisateur.

    Par exemple, si votre formulaire contient le champ application_sys_id , le g :ui_form peut bénéficier d’un script de traitement.

    <g:ui_form>
        <p>Click OK to run the processing script.</p>
        <g:dialog_buttons_ok_cancel ok="return true" />
        <input type="hidden" name="application_sys_id" value="499836460a0a0b1700003e7ad950b5da"/>
     </g:ui_form>

    Pour plus d'informations, consultez Macros d'interface utilisateur.

    <g :ui_input_field />

    Cette balise ajoute une référence à une macro d’interface utilisateur qui crée un champ d’entrée sur une page permettant aux utilisateurs d’entrer des informations. Le ui_input_field transmet une étiquette, un nom, une valeur et une taille dans la macro d’interface utilisateur.

    Voici un exemple tiré d’une page d’interface utilisateur :
    <g:ui_input_field label="sys_id" name="sysid" value="9d385017c611228701d22104cc95c371" size="50"/>

    Pour plus d'informations, consultez Macros d'interface utilisateur.

    <g :ui_checkbox/>

    Cette balise met une coche modifiable par l’utilisateur sur une page. Le nom et la valeur sont transmis dans la macro d’interface utilisateur.

    Voici un exemple tiré d’une table sur une page d’interface utilisateur :

    <table>
        <tr>
          <td nowrap="true">
              <label>Time Card Active:</label>
          </td>
          <td>
              <g:ui_checkbox name="timecard_active" value="${sysparm_timecard_active}"/>
          </td>
       </tr>
    </table>

    Pour plus d'informations, consultez Macros d'interface utilisateur.

    <g : dialog_buttons_ok_cancel/>

    Cette balise place des boutons sur la page d’interface utilisateur qui exécutent un script de traitement spécifié si la balise renvoie la valeur vrai.

    Si votre page d’interface utilisateur contient un formulaire (utilise la balise <g :form>), vous pouvez soumettre le formulaire et exécuter le script de traitement. Le script de traitement peut naturellement accéder aux champs du formulaire. Par exemple, si votre formulaire contenait le champ application_sys_id :

    <g:ui_form>
        <p>Click OK to run the processing script.</p>
        <g:dialog_buttons_ok_cancel ok="return true" />
        <input type="hidden" name="application_sys_id" value="499836460a0a0b1700003e7ad950b5da"/>
     </g:ui_form>

    <g :ui_reference/>

    Cette balise ajoute une référence à une page qui peut être référencée par un script de traitement.

    L’exemple suivant crée une référence définie par le nom, l’ID et les paramètres de table dans la balise :

    <g:ui_reference name="QUERY:active=true^roles=itil" id="assigned_to" table="sys_user" />

    Ensuite, dans le script de traitement, référencez le champ nom comme ceci :

    newTask.assigned_to = request.getParameter("QUERY:active=true^roles=itil");
    Vous pouvez spécifier un qualificatif de référence, afin que l’attribut « nom » puisse être unique. L’exemple suivant crée une référence définie par le nom, l’ID et les paramètres de table de la balise.
    Remarque :
    L’attribut « columns » ne s’applique qu’à la complétion automatique.
    <g:ui_reference name="parent_id" id="parent_id" table="pm_project" query="active=true" completer="AJAXTableCompleter" 
    columns="project_manager;short_description"/>

    Esperluette

    Les esperluettes dans Jelly peuvent vous causer du chagrin parce que Jelly est XML.

    Utilisez ${AMP} pour insérer une esperluette dans Jelly. Si vous écrivez du JavaScript qui apparaît dans la partie HTML d’une page d’interface utilisateur ou d’une macro d’interface utilisateur qui va réellement s’exécuter sur le navigateur, vous feriez mieux de mettre ce code dans le champ « script client » et de cette façon vous pouvez éviter d’échapper aux problèmes. Cependant, si vous devez vraiment le mettre dans le champ « HTML », vous devrez faire quelque chose comme ceci :

    ta = ta[1].split('$[AMP]');

    Et

    Utilisez ${AND} pour insérer un JavaScript et dans Jelly.

    Par exemple :

    if (d ${AND} e)
       var color = d.value;

    Alternativement, dans un test Jelly, vous utiliseriez &&. Par exemple :

    <j:if test="${jvar_form_name == 'sys_form_template' && !RP.isDialog()}">

    Inférieur à

    Semblable aux esperluettes, les signes inférieurs à (« < ») peuvent également causer des problèmes car Jelly est XML. Cela peut être résolu en inversant votre test de manière à ce qu’il ne soit pas nécessaire ou en utilisant ${AMP}lt ; à la place du signe inférieur à.

    <g2:evaluate var="jvar_text">
         var days = "";
         var selectedDays = '$[${ref}]';
         for (var i = 1; i ${AMP}lt;= 7; i++) {
            if (selectedDays.indexOf(i.toString()) >= 0) {
               days += gs.getMessage("dow" + i);
               days += " ";
            }
         }
         days;
     </g2:evaluate>

    Souvent, vous pouvez éviter l’opérateur « inférieur à » en utilisant simplement « pas égal » qui n’a pas de problèmes d’échappement. Par exemple :

    for (var i=0; i != ta.length; i++) {
    }

    Espaces

    Normalement, l’espace blanc est supprimé par Jelly. Pour le conserver, vous devez spécifier qu’il ne soit pas coupé.

    Par exemple, ce qui suit conserve l’espace après les deux-points.

    <j2:whitespace trim="false">${gs.getMessage('Did you mean')}: </j2:whitespace>

    Espaces

    Pour coder un espace insécable ( ), vous pouvez utiliser $[SP].

    Par exemple :

    <span id="gsft_domain" style="display: inline">
        ${gs.getMessage('Domain')}:$[SP]
        <span id="domainDD" class="drop_down_element" style="text-decoration: none; color: white">
            ${gs.getMessage("Loading...")}
       </span>
    </span>

    Jelly de traçage

    ServiceNow possède une fonction qui permet de tracer l’évaluation de Jelly.

    La trace est envoyée au journal. Cette option ne doit être activée que pendant le débogage, car cela produit beaucoup de journalisation. Pour activer la trace, définissez la propriété glide.ui.template.trace sur vrai. Par exemple, le script suivant peut être exécuté pour ce faire :

    GlideProperties.set ( 'glide.ui.template.trace' , true ) ;

    Si vous souhaitez afficher vos entrées de journal sur votre navigateur Web au bas de chaque page, accédez à Diagnostics du système > Journal des débogages.