Extensions de la syntaxe de Jelly

  • Rversion finale: Xanadu
  • Mis à jour 1 août 2024
  • 10 minutes de lecture
  • La syntaxe Jelly d’Apache est utilisée pour afficher les formulaires, les listes, les pages de l’interface utilisateur et bien d’autres éléments rendus au ServiceNowformat .

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

    Important :
    Cette fonction 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’appel 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 « 2 » se produisent dans la première phase du 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 du choix d’utiliser la phase 1 ou la phase 2 pour l’efficacité et des résultats corrects.

    En plus des espaces de noms, la syntaxe utilisée pour insérer des valeurs dans du contenu statique diffère en fonction de la phase qui doit fournir la valeur. Un dollar avec des accolades autour d’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 de gélatine. Un dollar avec des parenthèses entourant une valeur insère la valeur dans 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 en tant que 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 les tests

    Vous pouvez utiliser les instructions if dans les scripts Jelly.

    Tester si quelque chose est vrai ou non peut être fait 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 déclaration fonctionne, c’est que, dans Jelly, un terme comme jvar_something est « véridique » dans une balise if if :
    1. c’est booléen et vrai
    2. il s’agit d’une chaîne de caractères et = « vrai », « oui », « activé » ou « 1 »

    Tester si quelque chose existe peut être fait 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 zéro
    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

    Définit une variable sur 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 gelée 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 :call>

    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 aura le même aspect après un appel qu’avant l’appel. Cela signifie que vous ne pouvez pas définir une variable globale ici et la lire ultérieurement. 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.

    La transmission de 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 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 voulez avoir des valeurs par défaut ou requises, 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 la forme d’une 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 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 sur 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()"/>

    objet="vrai »

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

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

    jelly="vrai »

    Si vous souhaitez accéder aux variables Jelly à l’intérieur d’une évaluation, incluez jelly="true » dans l’évaluation et ajoutez « jelly. » avant le nom de la variable Jelly. Par exemple, pour accéder au 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 à l’aide du paramètre jelly="true ». La valeur de jvar_h a été définie précédemment et nous pouvons y accéder à l’intérieur de 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="vrai »

    Si vous avez besoin de prendre les résultats d’une évaluation qui a lieu dans la phase 1 et de les propager à la phase 2, utilisez copyToPhase2="true ». Il existe une certaine protection contre l’échappement 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. Méfiez-vous des problèmes d’échappement ici (les guillemets doubles dans jvar_rows poseraient 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 de passer en production.

    < exemple :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 de saisie sur une page qui permet aux utilisateurs de saisir 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.

    < exemple :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.

    < exemple :dialog_buttons_ok_cancel/>

    Cette balise place sur la page d’interface utilisateur des boutons 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 envoyer le formulaire et lancer le script de traitement. Le script de traitement peut naturellement accéder aux champs du formulaire. Par exemple, si votre formulaire contient 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, faites référence au 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 » soit unique. 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.
    Remarque :
    L’attribut « colonnes » ne s’applique qu’à l’auto-complétion.
    <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 à

    Comme pour les esperluettes, les signes inférieurs à (« < ») peuvent également causer des problèmes dus au fait que Jelly est XML. Ce problème peut être résolu en inversant votre test de sorte 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 « différent de » qui n’a pas de problèmes d’échappement. Par exemple :

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

    Espaces

    Normalement, les espaces blancs sont supprimés par Jelly. Pour le conserver, vous devez préciser qu’il ne doit pas être 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>

    Gelée de traçage

    ServiceNow a une fonctionnalité 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 elle génère 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.