You can process entries with Javascript through the Edit->Extended Edit -> Process with Javascript form. This enables you to do complex changes across an entire tree of entries.
Processing
Note: This facility has the potential to change a large number of entries and their properties. When processing make sure you test your code by checking off the "Save changes to entries" checkbox.
The Javascript form allows you to select which entries to process -
  • The initial entry
  • The children of the initial entry
  • All of the descendents entries
  • You can also specify that only entries of a certain type are processed

The tabs on the right are code snippets that, when clicked on, are added to the Javascript form. When processing there is always a current "entry" variable whose state can be accessed and changed.
images/extedit_js.png?version=450
The Javascript code with if/else, looping etc. The ctx object is the context of the call and allows you to print a message when running, to pause for a given time, to stop processing or to cancel the processing. The ctx functions are listed under the Control tab. e.g.:
if(entry.getName()=='') {	
     entry.setName('This entry has no name');
} else {
    ctx.print('entry has a name:',entry);
}
Basic Commands
These commands allow you to access and/or set the name, description, dates and location of the entry. For example, you can check if the name matches a certain pattern and then set the name to something else:
if (entry.getName().matches('.*Mining Issues.*')) {
    entry.setName('Some text:' + entry.getName());
    ctx.print('Processing: ' + entry.getName());
}
The entry.getChildren() returns a list of the entry's children entries. This list can then be iterated on:
var children = entry.getChildren();
for(var i=0;i<children.size();i++) {
     var child = children.get(i);
     ctx.print("Child:" + child.getName());
}
The entry.getChildren() function can also have a number of arguments. To access children entries of a certain type do by passing in "type:<some entry type>" where "some entry type" is the entry types identifiers that are listed on the /repository/entry/types.html page.
var children = entry.getChildren('type:some entry type');
For example if you wanted to select only Archive Items do:
var children = entry.getChildren('type:type_archive_item');
The children can be sorted with
var children = entry.getChildren('sort:some sort field');
Where "some sort field" can be one of: -pre name date fromdate todate changedate size type entryorder number -pre e.g.:
var children = entry.getChildren('sort:name');
The sort order can be specified by appending an "_up" or "_down": e.g.:
var children = entry.getChildren('sort:name_up');
var children = entry.getChildren('sort:name_down');
You can specify a child entry type and a sort order with:
var children = entry.getChildren('type:stype_archive_item','sort:name');
Metadata Commands
These commands allow you to access the columns of an entry and the attached metadata properties. When accessing the columns you need to have the column ID which can be viewed through the /repository/entry/types.html page.

For example, here we are accessing a column value "size" and setting it if it is 0.
var size = entry.getColumnValue('size');
if(size!=0) return;
size=22;
entry.setColumnValue('size',size);
ctx.print(entry.getName() +" size:" + size);
Here we check if the entry has metadata of a certain type. You can always list the available metadata types at - /repository/metadata/types.html
if(entry.hasMetadata('archive_note')) {
     ctx.print('Has metadata: '+ entry.getName());
}
Here we check if the entry has metadata of a certain type that also has a value of "History" for its first element.
if(entry.hasMetadata('archive_note','History')) {
     ctx.print('Has metadata: '+ entry.getName());
}
Here we are accessing the list of archive_note metadata with first value of "History"
var list = entry.getMetadata('archive_note','History');
ctx.print('Metadata count: '+ entry.getName() +' ' + list.size());
Here we are finding the list of metadata and deleting the elements.
As noted this will delete the metadata so it is best to click off the "Save changes to entries" checkbox first then evaluate the script to ensure it is doing what you intend
var list = entry.getMetadata('archive_note','History');
//Be careful because this will actually delete the metadata 
//if the Save changes to entries is checked
entry.deleteMetadata(list);
The permissions associated with a metadata element can be set, e.g.:
var list = entry.getMetadata('archive_note');
entry.setMetadataPermission(list,"admin")
Image Commands
The image commands allow you to apply operations on the image as well as generate a thumbnail image if one does not exist.
//Make a thumbnail and delete the existing one
if(entry.isImage()) {
     entry.makeThumbnail(true);
}
You can resize the image or convert it to gray scale with:
entry.resizeImage(400)
entry.grayscaleImage()
LLM Commands
If you have an LLM AI API configured (e.g., ChatGPT, Google Gemini, Anthropic Claude) you can use the following Extended Edit Javascript commands:
  entry.addLLMMetadata('metadata_type','prompt',check_if_exists)
metadata_type: The metadata type can be found by viewing the /repository/metadata/types.html.

prompt: The prompt has to be crafted to tell the LLM to only return the text that you desire for the metadata element. If there are multiple metadata elements specify that they should be separated by a semi-colon. You have to be stern sometimes. Something to the effect:
Extract no more than three keywords from the document. 
Only return the keywords in your response. Do not return anything else except the keyword.
If there are multiple keywords then they must be separated by a semi-colon ;
A good way of figuring out the prompt to use is to use the Document Chat facility on the entry. Go to the Entry Popup Menu and choose "Document Chat". This is an interactive facility where you can try out the prompt and see the result. Once you have a prompt that gives an acceptable result

check_if_exists: true or false. If true check if there already is a metadata on the entry. If there is do not add a new one.

For example there is a metadata type "tribe_name". The below call extracts the tribe name from the document
entry.addLLMMetadata('tribe_name',
'Extract the native american tribe names that are mentioned by  the document. Only return the tribe names in your response. Do not return anything else except the names. If there are multiple names  then they must be separated by a semi-colon ;',true)
Using LLM to add location
If you have an LLM AI API configured (e.g., ChatGPT, Google Gemini, Anthropic Claude) you can extract the geographic location (lat/lon) from a document with the command:
entry.addLLMGeo('')
The default prompt if one is not given is:
Give the latitude and longitude of the area that this document describes.
Just give the 2 numbers, nothing else. Give it in the form
<latitude>,<longitude>