Extensões à sintaxe do Jelly

  • Versão de lançamento: Xanadu
  • Atualizado 1 de ago. de 2024
  • 9 min. de leitura
  • A sintaxe Jelly do Apache é usada para renderizar formulários, listas, páginas de IU e muitas outras coisas renderizadas em ServiceNow.

    Com o Jelly, a lógica pode ser incorporada ao conteúdo estático e os valores calculados podem ser inseridos no conteúdo estático.

    Importante:
    Esta funcionalidade requer um conhecimento do Apache Jelly (um mecanismo de script e processamento baseado em Java e XML para transformar XML em código executável).

    Esta página do Apache tem um resumo dos marcadores Jelly padrão: http://commons.apache.org/jelly/tags.html

    Namespaces

    O Jelly geralmente inclui vários namespaces ao invocar marcadores.

    Os namespaces "j" são Jelly padrão, enquanto os namespaces "g" são exclusivos para scripts ServiceNow. Por exemplo, o<g:evaluate> O marcador é fornecido por ServiceNow para permitir que você calcule um valor usando JavaScript. O marcador Jelly padrão<j:test> é usado para avaliar uma condição.

    Fases

    Normalmente, há duas fases indicadas por namespaces<j> versus<j2> e versus<g2> .

    Os namespaces sem o "2" acontecem na primeira fase do processamento e são armazenados em cache, exceto quando usados em uma página de IU. Os que têm o "2" nunca são armazenados em cache. É preciso ter cuidado ao selecionar se deseja usar a fase 1 ou a fase 2 para obter resultados corretos e eficientes.

    Além dos namespaces, a sintaxe usada para inserir valores em conteúdo estático difere dependendo de qual fase deve fornecer o valor. Um dólar com chaves em torno de um valor insere o valor na fase 1. Por exemplo, ${jvar_ref} insere o valor jvar_ref durante a fase 1 do processo Jelly. Um dólar com colchetes em torno de um valor insere o valor na fase 2. Por exemplo, $[jvar_ref] insere o valor jvar_ref durante a fase 2. Um valor entre aspas é tratado como uma cadeia de caracteres. Por exemplo, '[jvar_ref]' insere o valor jvar_ref como uma cadeia de caracteres durante a fase 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}" />

    Testes If

    Você pode usar instruções "if" em scripts Jelly.

    Testar se algo é verdadeiro ou não pode ser feito da seguinte forma:

    <j:if test="${jvar_something}">...do something...</j:if>
    <j:if test="${!jvar_something}">...do something...</j:if>
    O motivo pelo qual essa declaração funciona é que, em Jelly, um termo como jvar_something é "verdadeiro" em um marcador if se:
    1. é booliano e verdadeiro
    2. é uma cadeia de caracteres e = "verdadeiro", "sim", "em" ou "1"

    Testar se algo existe pode ser feito da seguinte forma:

    <j:if test="${empty(jvar_something)}">...do something...</j:if>
    O motivo pelo qual esta declaração funciona é que a função JEXL vazia retornará verdadeiro se o argumento for:
    1. nulo
    2. uma cadeia de caracteres vazia
    3. uma coleção de comprimento zero
    4. um mapa sem chaves
    5. uma matriz vazia
    Nota:
    Você não pode misturar variáveis javascript e jvar em uma expressão JEXL. Eles devem ser divididos em expressões separadas.

    Definir_se

    Define uma variável com um de dois valores diferentes, dependendo se um teste é verdadeiro ou falso.

    <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>versus<g:inline> versus<g:call>

    Esta página fornece uma explicação comparativa de três marcadores:<g:insert> ,<g:inline> , e<g:call> .

    <g:insert>

    O<g:insert> O marcador insere um arquivo Jelly no seu Jelly em um novo contexto. Isso significa que você não pode acessar as variáveis estabelecidas anteriormente em seu Jelly.

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

    <g:inline>

    O<g:inline> O marcador insere um arquivo Jelly em seu Jelly no mesmo contexto. Isso significa que o Jelly inserido pode acessar as variáveis que você estabeleceu anteriormente e pode mudar os valores dessas variáveis.

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

    <g:call>

    Para um melhor encapsulamento, o<g:call> O marcador pode ser usado. Sua função só terá acesso aos valores passados para ela. O contexto do Jelly terá a mesma aparência após uma chamada e antes da chamada. Isso significa que você não pode definir uma variável global aqui e lê-la mais tarde. Isso também significa que você não pode definir por engano uma variável global chamada "jvar_temp" e substituir uma variável na qual outra pessoa estava dependendo.

    A passagem de valores, se necessário, é feita explicitamente, incluindo o nome do parâmetro no<g:call> linha seguida pelo sinal de igual seguido pelo valor entre aspas:

    <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}"/>

    Se os valores forem passados e você quiser ter parâmetros padrão ou obrigatórios, o Jelly referenciado na função deverá incluir uma linha para declarar se os parâmetros são necessários ou têm um valor padrão:

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

    O exemplo acima indica que 3 parâmetros são necessários e um parâmetro é uma opção com um valor padrão em branco. Observe que se você não estiver passando valores ou se quiser ter valores padrão ou obrigatórios, não será necessário incluir o<g:function> linha em tudo. Em geral, no entanto, convém incluir um<g:function> linha.

    O valor pode ser referenciado em seu modelo anexando o prefixo "jvar_" ao nome do parâmetro:

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

    Para<g:call> , os parâmetros também podem ser passados implicitamente como uma lista de variáveis nomeadas em um parâmetro "argumentos":

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

    Como alternativa à passagem de variáveis para a função por meio de argumentos de marcador separados, é possível passar uma lista de variáveis em um único argumento de "argumentos". Todas as variáveis identificadas por nome (separadas por vírgulas) no parâmetro argument são reintroduzidas na função com exatamente o mesmo nome (por exemplo, dentro do modelo de função, temos as variáveis sysparm_view, ref_parent e jvar_target_text disponíveis).

    O modelo de função pode retornar um valor para o modelo de chamada usando o atributo " return= ". Na função, a variável jvar_answer define o valor de retorno.

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

    <g:evaluate>

    O<g:evaluate> O marcador é usado para avaliar uma expressão escrita em JavaScript Rhino e, às vezes, para definir uma variável para o valor da expressão.

    A última declaração na expressão é o valor que a variável conterá.

    <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()"/>

    objeto="verdadeiro"

    Se você quiser que a avaliação retorne um objeto (por exemplo, uma matriz), use o argumento object="true".

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

    Jelly="verdadeiro"

    Se você quiser acessar variáveis Jelly dentro de uma avaliação, inclua Jelly="true" em Evaulate e adicione "jelly". antes do nome da variável Jelly. Por exemplo, para acessar o GlideJellyContext:

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

    Outro exemplo de acesso a um jvar usando o parâmetro Jelly="true". O valor de jvar_h foi definido anteriormente e podemos acessá-lo dentro da avaliação:

    $[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="verdadeiro"

    Se você precisar obter os resultados de uma avaliação que ocorre na fase 1 e propagá-la para a fase 2, use copyToPhase2="true". Há alguma proteção para escape neste uso. Por exemplo:

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

    Se você não precisar avaliar algo, poderá fazer isso de forma mais direta. Cuidado com os problemas de escape aqui (aspas duplas em jvar_rows causariam um problema no exemplo):

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

    <g:breakpoint/>

    Este marcador pode ser usado para exibir as variáveis atuais do Jelly e seus valores no log.

    Certifique-se de remover este marcador antes de ir para a produção.

    <g:ui_form/>

    Este marcador define um formulário na página de IU.

    Por exemplo, se o seu formulário contiver o campo application_sys_id, o g:ui_form poderá se beneficiar de um script de processamento.

    <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>

    Para obter mais informações, consulte Macros de IU.

    <g:ui_input_field />

    Este marcador adiciona uma referência a uma macro de IU que cria um campo de entrada em uma página que permite aos usuários inserir informações. O ui_input_field passa um rótulo, nome, valor e tamanho para a macro de IU.

    Aqui está um exemplo de uma página de IU:
    <g:ui_input_field label="sys_id" name="sysid" value="9d385017c611228701d22104cc95c371" size="50"/>

    Para obter mais informações, consulte Macros de IU.

    <g:ui_checkbox/>

    Este marcador coloca uma marca de seleção editável pelo usuário em uma página. O nome e o valor são passados para a macro de IU.

    Aqui está um exemplo de uma tabela em uma página de IU:

    <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>

    Para obter mais informações, consulte Macros de IU.

    <g:dialog_buttons_ok_cancel/>

    Este marcador coloca botões na página de IU que executam um script de processamento especificado se o marcador retornar verdadeiro.

    Se a sua página de IU contiver um formulário (usa o<g:form> tag), você pode enviar o formulário e fazer com que o script de processamento seja executado. O Script de processamento pode acessar naturalmente os campos do formulário. Por exemplo, se o seu formulário contiver o campo 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/>

    Este marcador adiciona uma referência a uma página que pode ser referenciada por um script de processamento.

    O exemplo a seguir cria uma referência definida por parâmetros de nome, ID e tabela no marcador:

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

    Em seguida, no Script de processamento, faça referência ao campo de nome da seguinte forma:

    newTask.assigned_to = request.getParameter("QUERY:active=true^roles=itil");
    Você pode especificar um qualificador de referência para que o atributo "nome" possa ser exclusivo. O exemplo a seguir cria uma referência definida por nome, ID e parâmetros de tabela no marcador.
    Nota:
    O atributo "colunas" se aplica somente ao preenchimento automático.
    <g:ui_reference name="parent_id" id="parent_id" table="pm_project" query="active=true" completer="AJAXTableCompleter" 
    columns="project_manager;short_description"/>

    E comercial

    Os e comerciais no Jelly podem causar problemas porque o Jelly é XML.

    Use ${AMP} para inserir um e comercial no Jelly. Se você estiver escrevendo o JavaScript que aparece na parte HTML de, digamos, uma página de IU ou macro de IU que será realmente executada no navegador, é melhor colocar este código no campo "script de cliente" para evitar problemas de escape . No entanto, se você realmente precisar colocá-lo no campo "HTML", precisará fazer algo como isto:

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

    E

    Use ${AND} para inserir um JavaScript e no Jelly.

    Por exemplo:

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

    Como alternativa, em um teste Jelly, você usaria &&. Por exemplo:

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

    Menos de

    Semelhante aos e comerciais, os sinais de menor que ("<") também podem causar problemas devido ao fato de o Jelly ser XML. Isso pode ser resolvido revertendo o teste de forma que ele não seja necessário ou usando ${AMP}lt; no lugar do sinal de menor que.

    <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>

    Muitas vezes, você pode evitar o operador "menor que" usando apenas "não é igual a", que não tem problemas de escape. Por exemplo:

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

    Espaço em branco

    Normalmente, o espaço em branco é removido pelo Jelly. Para mantê-lo, você deve especificar que ele não seja cortado.

    Por exemplo, o seguinte mantém o espaço após os dois pontos.

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

    Espaços

    Para codificar um espaço sem quebra ( ), você pode usar $[SP].

    Por exemplo:

    <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>

    Rastreamento do Jelly

    ServiceNow tem um recurso que permite que a avaliação do Jelly seja rastreada.

    O rastreamento é enviado para o log. Isso só deve ser ativado durante a depuração, pois produz muitos registros em log. Para ativar o rastreamento, defina a propriedade glide.ui.template.trace como verdadeira. Por exemplo, o script a seguir pode ser executado para fazer isso:

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

    Se você quiser ver suas entradas de log no navegador da Web na parte inferior de cada página, navegue até Diagnóstico do sistema > Depurar Log.