script editor (tool)


The features described on this page are only available inAmetys v4.2 and higher. 

 

The script editor lets you write and run scripts from the back-office tool.
This tool features a grid for displaying the content returned by script, in addition to the text display of messages and results. It features a function for formatting returned content, and for specifying the columns to be displayed in the grid.
In addition, it can take into account content currently selected (from a search tool, for example) at the time of execution of script, by means of a "selection" variable.

  1. Scripts
    1. Tool presentation
    2. Scripting language
  2. Variables and functions Ametys
    1. Variables
    2. Functions
  3. Sample scripts
    1.  Display programs with the same component as the selected program
    2. Generate a report on programs and pedagogical elements
  4. Script files
    1. Tutorials
    2. Variables
    3. Functions

 

Scripts

Tool presentation

To access the tool, you must have the "Tool Script" right in the "Other tools" category. The tool is then available in the Home tab.

This tool is divided into 3 zones:

- At the top, the script area, where script can be written inside a "main" function. Below the script area, there's an "Execute" button to run the script function.

- At bottom left, taking up the entire width by default, is an empty grid for displaying the contents returned by the execution of script.

- In the bottom right-hand corner, reduced by default, you'll find the"Console", i.e. the result of the script execution in text format.

After successful execution of a script , the script part is retracted to display the grid and the console with the results of the script.

Scripting language

The script editor uses Java 8's JavaScript engine, called"Nashorn". The expected syntax is therefore Nashorn syntax. As this engine runs at Java, it allows access to and manipulation of Java methods and classes, in addition to JavaScript . For example, Nashorn

var ArrayList = Java.type('java.util.ArrayList');           
var list = new ArrayList();           

Another commonly used feature is the"print()" method for displaying text in console output.

print("Sélection actuelle : " + selection)           

Refer to the Nashorn syntax to write your own scripts.

 

Variables and functions Ametys

Ametys provides a number of variables and functions to enable you to useAmetys 's features within your scripts.

For versions Ametys 4.3 and higher
To open the script help tool, click on the help button next to the script execution button:

Help is divided into 3 categories: variables, functions and tutorials.
A filter is available at the top to quickly search for one or the other by name.
Available examples can be selected with the mouse and then copied to the clipboard using the shortcut CTRL+C.

For versions Ametys 4.2 and earlier
To view the list of variables and functions available in the tool at any time, just move your mouse over the "?" in the top right-hand corner of the scripts tool :

To go further
You can add your own functions to the file "WEB-INF/param/scripts.xml" (see below). Within plugin, you can also use the "org.ametys.plugins.core.ui.script.ScriptBindingExtensionPoint" extension point to add other variables and functions.

 

The functions and variables available depend on the current context.
For example, the contents function and the selection variable are only available in CMS, you will not have access to this function in the Script tool of the administration interface.

Variables

-"sourceResolver" is a shortcut for the "org.apache.excalibur.source.SourceResolver" component, used to resolve URI fromAmetys. For example:

var newsletterTemplateSource = sourceResolver.resolveURI("context://skins/" + skinId + "/newsletter/" + id + "/stylesheets/template.xsl")           

-selection" is the list of currently selected contents, or an empty list if no contents are selected.

for each (var content in selection) {           
 print(content.getId())           
}           

-"session" give read and write access to the repository. For example :

var rootNode = session.getRootNode().getNode("ametys:root");           

-"ConsoleHelper" is a shortcut to the "org.ametys.workspaces.repository.ConsoleHelper" class, a helper that provides methods such as "setProperty" or "convertSingleToMultipleProperty" to assist with repository operations.

-avalonContext" corresponds to the avalon context of the request. It contains information such as the current site.

var site = avalonContext.get(org.apache.cocoon.components.ContextHelper.CONTEXT_REQUEST_OBJECT).getAttribute("siteName");           

-"ametysResolver" resolves Ametys objects using their identifier or "path".

var creator = ametysResolver.resolveById("courseContent://471545a1-2c75-4f75-b774-dda2bf0fa960").getCreator();         
var site = ametysResolver.resolveByPath("ametys:sites/www");           

-"repository" represents the repository, and allows you to change the session workspace, for example:

var credentials = new javax.jcr.SimpleCredentials('ametys', []);           
session = repository.login(credentials, 'archives');           

-"serviceManager" is used to retrieve the avalon components owned by Ametys : 

var contentTypesHelper = serviceManager.lookup(org.ametys.cms.contenttype.ContentTypesHelper.ROLE)           

-"progressionTracker" (from Ametys 4.8 onwards) allows script progress to be notified and displayed in logs (and in the task scheduler for asynchronous scripts):

progressionTracker.setSteps([
  {
    id: 'init',
    label: "Initialisation",
  },
  {
    id: 'work',
    label: "Travail",
    weight: 100,
    children: [
        {
          id: 'workContent',
          label: "Contenus",
          weight: 20
        },
        {
            id: 'workPages',
            label: "Pages",
            weight: 20,
            children: [
                {
                  id: "workPagesSitemap",
                  label: "Plan du site"
                }
            ]
        },
        {
          id: 'workAlias',
          label: "Alias"
        },
    ]
  },
  {
    id: 'finish',
    label: "Finalisation"
  }
])
// ...
progressionTracker.increment('init'); // Default size is 1, so incrementing here is going to complete the step
// ...
progressionTracker.setSize('workContent', 2);
// ...
progressionTracker.increment('workContent'); // Increment of 1
// ...
progressionTracker.increment('workContent');
// ...
progressionTracker.setSize('workPagesSitemap', 10);
// ...
progressionTracker.increment('workPagesSitemap', 10); // Increment of 10
// ...
progressionTracker.setSize('workAlias', 20);
// ...
progressionTracker.increment('workAlias', 5); // Increment of 5, total progress is 5
// ...
progressionTracker.increment('workAlias', 10); // Increment of 10, total progress is 15
// ...
progressionTracker.increment('workAlias', 2); // Increment of 2, total progress is 17
// ...
progressionTracker.increment('workAlias', 3); // Increment of 3, total progress is 20
// ...
progressionTracker.setSize('finish', 3);
// ...
progressionTracker.increment('finish', 2); // Increment of 2
// ...
progressionTracker.increment('finish'); // Increment of 1

Functions

-jcrXPathQuery" executes an XPath query JCR to retrieve a list of nodes

for each (var content in jcrXPathQuery("//element(*, ametys:content)[jcr:like(@ametys-internal:contentType, 'odf-enumeration.%')]")) {          
 print(content.getId())          
}          

-printSqlQuery" executes the "sqlQuery" function (see below), and displays the result directly in the console, formatted as follows

printSqlQuery("SELECT * FROM users", "SQL-j2c1c5hc")          

-migrateContent" is a helper function for executing a list of migration functions, while marking previous versions as incompatible or not, and adding a tag ("live" for example) to new versions or not.

function _titleMigration(content) { /* migrate title ... */ }          
 migrateContent(content, [_titleMigration], true /*old versions incompatible*/, null /*no tag*/, false /*not verbose*/);          

-"sqlQuery" executes a sql query on the dataSource passed as the 2nd parameter. The dataSource parameter can also be the identifier of a dataSource, for simplicity's sake.

var dataSource = serviceManager.lookup("org.ametys.core.datasource.SQLDataSourceManager").getSQLDataSource("SQL-j2c1c5hc");          
var result = sqlQuery("SELECT * FROM users", dataSource)          

-contents" is a helper function used to format contents for display in the results grid. The first parameter is an array with the various columns to be displayed. If the value is an empty table, all content fields will be displayed in the grid. The second parameter is a list of contents.

return contents([], selection); // affiche la sélection courante dans la grille          

-"sqlUpdate" can be used to run a query SQL to modify existing data (update, delete, etc.).

sqlUpdate("UPDATE users SET FIRSTNAME='Firstname' WHERE FIRSTNAME='admin'", "SQL-j2c1c5hc");          

 

Sample scripts

The examples given below are examples that can be executed in an application Ametys ODF .

 Display programs with the same component as the selected program

var showContentsIds = [];          
selection.forEach(function (content) {          
  var orgUnits = content.getOrgUnits();         
          
  orgUnits.forEach(function (orgUnit) {          
    // Nashorn supporte la syntaxe "for each(var ... in ...)" ci dessous, mais on peut également utiliser le "list.forEach(callback)" de java, ligne au dessus        
    for each (var contentWithOrgUnit in jcrXPathQuery("//element(*, ametys:programContent)[@ametys:orgUnit = '" + orgUnit + "']")) // jcrXPathQuery permet d’exécuter un XPATH sur le repository        
    {          
      if (showContentsIds.indexOf(contentWithOrgUnit.getId()) == -1)          
      {          
        showContentsIds.push(contentWithOrgUnit.getId());          
      }          
    }          
  });          
});          

var returnContents = [];          
showContentsIds.forEach(function (contentId) {          
  returnContents.push(ametysResolver.resolveById(contentId));  // utilisation du ametysResolver pour transformer les ids en contents        
})          

return contents([], returnContents); // retourner "contents()" permet d'afficher des contenus dans la grille de résultats          

If the script returns an object with a "results" property that contains a list of contents, they will be displayed in the grid. If the script returns an object with a "columns" property, the grid will be configured to display these columns. If columns is an empty array, then the contents field(s) will be used to define the grid columns. The "contents(columns, contents)" method makes it easy to return an object with the right properties to fill the grid.

 

Generate a report on programs and pedagogical elements

var StringUtils = Java.type("org.apache.commons.lang3.StringUtils");         

function doProgram(program) {         
  var out = program.getTitle();         
  out += ";";         
           
  out += program.getLanguage();         
  out += ";";         

  program.getOrgUnits().forEach(function (orgUnit) {         
    var org = ametysResolver.resolveById(orgUnit);         
    if (org != null) {         
      out += org.getTitle() + ",";         
    }         
  });         
  out += ";";         

  out += "ects (" + (StringUtils.isEmpty(program.getEcts()) ? "EMPTY" : "OK") + ")";         
  out += ";";         

  out += ";"; // parcours - Titre (vide)         

  print(out);         

  traverseProgramPart(program, {program: program});         
}         

function traverseProgramPart(part, data) {         
  traversePattern(part, "getProgramPartChildren", traverseProgramPart, data);         
  traversePattern(part, "getCourses", doCourse, data);         
}         

function doCourse(course, data) {         
  var out = data.program.getTitle();         
  out += ";;;;"; // ;lang;Composante;Champs texte; (vide)         
  out += course.getTitle();         

  print(out);         

  traversePattern(course, "getCourseLists", traverseProgramPart, data);         
}         

// Méthode helper pour traverser les noeuds de l'arbre des program/subprogram/container/courseList/course        
function traversePattern(traversable, getChildrenFctName, traverseChildFct, data) {         
  if (typeof traversable[getChildrenFctName] == "function")         
  {         
    traversable[getChildrenFctName]().forEach(function (child) {         
      traverseChildFct(child, data);         
    });         
  }         
}         

var contents = [];         
print("Formation;lang;Composante;Champs texte;Parcours - Titre"); // entête du fichier csv         
jcrXPathQuery("//element(*, ametys:programContent)").forEach(doProgram);         

 This script displays in the console, in csv format, the list of all available courses, with the name of the parent component, the language, whether the "ects" text field is empty or not, and the title of the teaching elements under the course.

 

Script files

Either via the extension point or via the WEB-INF/param/scripts file.xml it is possible to add elements to the scripting tool.

From Ametys 4.3 onwards, the file format changes, and it is this format that is described in this documentation.

The format is as follows

<?xml version="1.0" encoding="UTF-8"?>     
<binding>     
  <tutorials>...</tutorials>     
  <variables>...</variables>     
  <functions>...</functions>     
</binding>     

Tutorials

Describes tutorials.

A tutorial consists of :

  • a wording
  • a main text
  • examples
    • an introductory text for the example
    • example code (directly or in a separate file)
<tutorial>     
  <name type="i18n">MYI18NIZEDNAME</name>     
  <text type="i18n">MYI18NIZEDTEXT</name>     
  <examples>     
    <example>     
      <text type="i18n">MYINTROTOSAMPLE</text>     
      <script file="tuto.js"/>     
    </example>     
    <example>     
      <text type="i18n">MYINTROTOSAMPLE</text>     
      <script>onlinetuto();</script>     
    </example>     
  </examples>     
</tutorial>     

Variables

Variables are encoded in the extension point at Java (and therefore cannot be added from WEB-INF/param/scripts.xml). However, they are documented in the XML file.

They are set up in the same way as the tutorials, with the addition of :

  • Signature: their signature
    • Type : their type (java or javascript)
    • Subtype: if the type is an object, describes the object with a signature.
<variable>     
  <name>myVariable</name>     
  <text type="i18n">MYVARIABLETEXT</text>     
  <signature>     
    <type>my.variable.Type</type>     
  </signature>     
  <examples><!-- voir les exemples dans les tutoriels --></examples>     
</variable>     

Functions

Functions such as tutorials, plus

  • Script tag: the function code (directly or in a separate file). This tag can be used several times to load multiple files.
  • Signature: their signature
    • Type : their return type (java or javascript)
    • Subtype: if the type is an object, describes the object with a signature.
    • Text associated with the return value
    • Arguments.
      • Argument name
      • Argument type
      • Subtype: if the type is an object, describes the object with a signature.
      • Text argument
      • Default value of argument if optional. Set null to indicate that the element is optional, but without displaying a default value.
<function>     
  <name>myFunction</name>     
  <text type="i18n">MYFUNCTIONTEXT</text>     
  <script file="myfunction.js"/>     
  <signature>     
    <type>MyReturnType</type>     
    <text type="i18n">RETURNTYPETEXT</text>     
    <arguments>     
      <argument>     
        <name>my1stArg</name>     
        <type>MyFirstArgType</type>     
        <subtype>  
            <argument>  
                <name>subtype</name>  
                <type>Boolean</type>  
            </argument>  
        </subtype>  
        <text type="i18n">MYFIRSTARGTEXT</text>     
        <optional>"My default string value"</optional>    
      </argument>     
    </arguments>     
  </signature>     
  <examples><!-- voir les exemples dans les tutoriels --></examples>     
</function>     

Pour une fonction, il faut toujours placer la balise <arguments> même si elle est vide dans le cas où la fonction ne prend pas d'arguments.

Back to top