Rename scripts in JScript, VBScript and PerlScript

Updated Aug 29, 2017, for Directory Opus 12.

You do not have to use scripting to batch-rename files in Opus. You can use simple wildcards, find & replace, regular expressions, and so on. Rename scripts are just an option for when you need more power.

When using a rename script, Opus will call a function for each file or folder. The function is passed information about each thing being renamed, such as its old name and proposed new name (including any other effects of the Rename dialog's non-script settings). The script can then approve, reject or change the proposed new name based on whatever logic you wish to use.

New rename scripts should implement a function called OnGetNewName which will be passed a getNewNameData object with various information about the item being renamed, including access to its metadata. (The data this object provides may be expanded over time, without breaking existing scripts.)

In Opus 12, if you open the rename script editor and select JScript or VBScript, you'll get a default script which walks you through the basic details. (You can also save your own default script to use as a starting point, to save time in the future.)

Important details are documented in these manual pages:

Instead of OnGetNewName, older rename scripts may use the legacy Rename_GetNewName or Rename_GetNewName2 functions, which were passed details via multiple parameters. There is no reason to use those in new scripts, and they are only worth knowing about in case you find an old script which uses them.

(In a couple of old JScript posts, you may see Rename::GetNewName or Rename::GetNewName2 used. The :: turn into _ behind the scenes and they run the same legacy functions as in the previous paragraph.)

Below are two simple rename script examples in JScript and VBScript.

The examples do the same same thing: Add a TEST suffix to each filename, before any file extension. The examples are not supposed to be useful by themselves; they exist purely to demonstrate the appropriate syntax for rename scripts in various languages. More complex examples can be found in the forum.

They also show how you can use DOpus.Output to print debugging information to the panel below the script editor.

After making changes to a script, click the Refresh Preview button above the editor to see the results. Also note that if you modify parameters in the main part of the Rename dialog, it can cause your script to be re-run to update the preview. Keep that in mind if your script has any external side-effects (such as modifying files on its own).


JScript:

JScript support is built into Windows.

Set the Script Type field to JScript.

function OnGetNewName(getNewNameData)
{
	var item = getNewNameData.item;
	var result = item.name_stem + " TEST" + item.ext;

	DOpus.Output("Name      = " + item.name);
	DOpus.Output("Name Stem = " + item.name_stem);
	DOpus.Output("Extension = " + item.ext);
	DOpus.Output("Result    = " + result);
	DOpus.Output("---------");

	return result;
}


VBScript:

VBScript support is built into Windows.

Set the Script Type field to VBScript.

Option Explicit
Function OnGetNewName(ByRef getNewNameData)
	Dim item, result
	Set item = getNewNameData.item
	result = item.name_stem & " TEST" & item.ext

	DOpus.Output "Name      = " & item.name
	DOpus.Output "Name Stem = " & item.name_stem
	DOpus.Output "Extension = " & item.ext
	DOpus.Output "Result    = " & result
	DOpus.Output "---------"

	OnGetNewName = result
End Function


PerlScript:

To use PerlScript you must install ActivePerl, or an equivalent ActiveScripting version of Perl.

If you plan to make rename scripts to share on the forums, please consider using JScript or VBScript instead of PerlScript, so that people can use the scripts they download out-of-the-box.

You'll also generally find it easier to use JScript or VBScript as there are more examples on the forum, more people who can help with them here, and you're less likely to run into unexpected language-level issues due to Opus's scripting support being mostly designed and tested around the built-in languages.

Credit for this example goes to the combined efforts of @MrC and @myarmor.

Note that this example prefixes the filename with Test_, slightly different to the other examples.

Set the Script Type field to perlscript (if it is not in the drop-down already, you can type it manually).

use v5.14;
use strict;
use warnings;
use warnings qw(FATAL utf8);
use utf8;
use Win32::OLE qw(CP_UTF8 CP_ACP);
use Win32::OLE::Variant qw(Variant VT_BSTR);
Win32::OLE->Option(Warn => 3, CP => CP_UTF8);
sub OnGetNewName{
  my ($GetNewNameData)=@_;
  my $ret="Test_".$GetNewNameData->item->name;
  return Variant(VT_BSTR, $ret);  
}

(Most of the perlscript example is boilerplate code to make perlscript use Unicode. In contrast, Unicode support is automatic with JScript and VBScript.)

From @myarmor:

Note that Opus rename editor uppercases the "s" in "sub", so you'll have to change that by doubling the "s" then use backspace on the first. Now when the initial "s" is lowercase you can save it as usual, and it will run correctly even though the editor displays it as "Sub" whenever the saved script is selected.


Other Languages:

In theory, if a language has an ActiveScripting port which is installed on your system (and is compiled for 64-bit, if using 64-bit Windows), then you can use it to write scripts in Opus, including rename scripts.

In practice, it can be an uphill battle, as many scripting languages have wildly different rules about argument passing (references vs values, etc.), reserved names and other keywords, properties vs methods, and other issues you probably don't want to deal with. If you know one language already, it is usually easy to learn another (the differences tend to be quite minor), and we recommend using JScript or VBScript.

If you don't know JScript or VBScript, learning JScript is probably the most useful, as it is closely related to JavaScript (it is essentially a slightly older version of JavaScript), and you'll find JavaScript is useful to know for almost everything that involved the web. But it doesn't matter a great deal, and if you learn one it is easy to then learn the other.


Saving your Rename Script for use in the Rename dialog

You would normally save your script into a Rename Preset, which saves the setup of the rename dialog into a named preset. The list of presets is on the left of the Rename dialog in Opus 12, and on the right in earlier versions. The buttons above the list let you load and save presets, among other things.


Using your Rename Script outside the Rename Dialog

If you wish to run your script from a toolbar button, instead of from within the Rename window, there are several ways to do it. Which you choose depends on where you want the script to be defined.

Although it is not required, it is usually nice to use @nodeselect with buttons that rename files, since you often want to keep them selected to do other things with them afterwards. The examples below include this.

  1. Reference a Rename Preset from a button:

    If you have the script saved in a rename preset then you can make a button which refers to the preset. If the preset is called Multi-RegExp then the button's command would be like this:

    @nodeselect
    Rename PRESET="Multi-RegExp"
    

    Rename Preset via Button

  2. Use the Rename Preset menu:

    If you've saved your script into a rename preset, and you're using the default toolbars that come with Opus 12 or above, you'll find the preset is already accessible via the menu attached to the Rename button.

    Rename Preset Menu

  3. Everything in a Button:

    If you only want to run the script from one button, and don't want the script cluttering up the list of presets in the Rename window, then you can put everything including the script into your button:

    Note that the button's Function Type should be set to Standard Function and not Script Function. While there is a script in the button, it is underneath the standard, non-scripting Rename command. (If this seems odd to you, it is because rename scripts predate generic script functions by several years.)

    @nodeselect
    RENAME PATTERN="*" TO="*"
    @script vbscript
    Option Explicit
    Function OnGetNewName(ByRef getNewNameData)
    	Dim item
    	Set item = getNewNameData.item
    	OnGetNewName = item.name_stem & " TEST" & item.ext
    End Function
    

    Rename Script in Button

  4. Not using a rename script at all:

    A third option is to not use the Rename command at all. You can run scripts in Opus buttons which can do anything they want. Your script could calculate command-lines to run the Rename command on files (essentially, your script would call the Rename command instead of the Rename command calling your script). Your script could even rename the files directly, using the Windows scripting API. Or your script could do something that wasn't renaming at all.

    Using the Rename command and a rename preset and/or script often simplifies things, since you don't have to worry about looping through the selected files and can just write a small script that only has to worry about one file at a time, but sometimes the other approaches are better. It depends what you are doing.

1 Like

Thread has been updated and cleaned up for Opus 12.

Thanks @Leo, this post was most helpful. I was originally trying to create a rename button script but forgot the built-in Rename option has scripting, which is what I needed. My use-case for this was wanting to read JSON files (Qualtrics survey template files) and parse a JSON parameter to use as the rename value. Here is the javascript code I used:

function OnGetNewName(getNewNameData)
{
	var item = getNewNameData.item;
	// open the survey template file and extract the JSON data
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	var fh = fso.OpenTextFile(getNewNameData.item.realpath, 1);	// open the file for reading
	var fText = fh.ReadAll();
	var objSurvey = JSON.parse(fText);
	fh.Close();
	// rename the template file to the survey ID defined in the data
	var result = objSurvey.SurveyEntry.SurveyID+".json";
	// testing output
	/*
	DOpus.Output("Name      = " + item.name);
	DOpus.Output("Name Stem = " + item.name_stem);
	DOpus.Output("Extension = " + item.ext);
	DOpus.Output("Result    = " + result);
	DOpus.Output("Path    = " + getNewNameData.item.realpath);
	DOpus.Output("---------");
	*/
	return result;
}

DOpus is a lifesaver!