Developer Resources
Creating a "Hello World" Extension
While scripts can be run individually, sometimes you want to package them up so they can be run as part of the application, without the script being stored in the project or on in the filesystem, but instead existing as if it were part of the native functionality of the package.
When scripts are packaged up this way and installed, they are called extensions. The extension encapsulates the functionality of the script, along with other resources such as bitmaps or data tables, into a single extension file.
Then, when an extension is installed in Kirix Strata™, the scripts contained in the extension run each time Strata is opened, adding additional functionality to Strata as if it existed natively as part of the package.
You can create an extension for Strata by packaging a script together with an XML file, called "info.xml." This XML file contains the information required to load and run the script as an extension in Strata.
To see this in action, let's create a simple "Hello World" extension that shows a "Hello World" alert when we click on a menu item in the tools folder.
First, create a script file called "main.js" to hold the primary contents of the extension:
- Go to the File menu and select New->Script, which will open a new text editor without any script.
- Go to the File menu and select "Save As External".
- In the "Save As" dialog, save the script as "main.js" to your desktop.
Next, let's create the code that shows the "Hello World". Of course, showing a "Hello World" message is trivial, using the alert function; however, in our example, we want to show "Hello World" when we click on a menu item in Strata's Tools menu, and we want this to run this as an extension. So, we have to:
- Check if the script is running as an extension or standalone.
- If the script is running as an extension, insert a menu item into Strata's Tools menu.
- If the menu item is clicked, or the script is running standalone, show the "Hello World" message.
First, check if the script is running as an extension or standalone. Although we don't need to do this to run the script as an extension, it allows us to develop the script to run as an extension, while still allowing us to run it directly without always inserting new menu items each time we run it, which we really only want to do once when we actually run it as an extension.
So, to check if the script is running as an extension or standalone, use Extension.isContextPackage(), which returns true if the script is running as an extension, and false otherwise:
if (Extension.isContextPackage())
{
// if the script is packaged as an extension, add a
// menu item to the host application and connect the
// menu item click event to a handler
}
else
{
// if the script is not packaged as an extension,
// simply show the alert message
}
// start the application event loop to process
// application events
Application.run();
Next, if the script is running as an extension, insert a menu item into Strata's Tools menu. For now, simply create an empty function "insertToolsMenuItem" that returns a menu item, and include it in the script as follows:
if (Extension.isContextPackage())
{
// if the script is packaged as an extension, add a
// menu item to the host application and connect the
// menu item click event to a handler
var item = insertToolsMenuItem("Hello World...");
}
else
{
// if the script is not packaged as an extension,
// simply show the alert message
alert("Hello World");
}
function insertToolsMenuItem(name)
{
}
// start the application event loop to process
// application events
Application.run();
Finally, if the menu item is clicked, or the script is running standalone, show the "Hello World" message. To do this, create a new function, "onHelloWorldMenuItemClicked", and connect the menu item's click event to this function, so that when the menu item is clicked, this function is run, showing the "Hello World" message:
if (Extension.isContextPackage())
{
// if the script is packaged as an extension, add a
// menu item to the host application and connect the
// menu item click event to a handler
var item = insertToolsMenuItem("Hello World...");
item.click.connect(onHelloWorldMenuItemClicked);
}
else
{
// if the script is not packaged as an extension,
// simply show the alert message
alert("Hello World");
}
function insertToolsMenuItem(name)
{
}
function onHelloWorldMenuItemClicked()
{
alert("Hello World");
}
// start the application event loop to process
// application events
Application.run();
When we run this script, it shows "Hello World", as we expect. However, we still need to actually insert the menu item to show this message, as well as package the script up as an extension. To do this, we need to:
- Get Strata's Tools menu.
- Insert the new menu item into Strata's Tools menu.
First, to get Strata's Tools menu, create a new function, called getToolsMenu(), as follows:
function getToolsMenu()
{
// summary: returns the host application Tool menu item
// get the host application's main menu
var menu_bar = HostApp.getFrameMenu();
var tools_menu;
// get the Tool menu item; if it doesn't exist, create it
var id = menu_bar.findMenu("Tools");
if (id < 0)
{
tools_menu = new Menu("Tools");
menu_bar.insert(tools_menu, menu_bar.getMenuCount()-1);
}
else
{
tools_menu = menu_bar.getMenu(id);
}
return tools_menu;
}
Next, to insert the new menu item into Strata's Tools menu, fill out the insertToolsMenuItem() function we created earlier:
function insertToolsMenuItem(name)
{
// summary: inserts a menu item with the given name in
// an appropriate location in the host application's Tool
// menu item
// get the Tool menu item
var tools_menu = getToolsMenu();
// if the menu item already exists, first remove the
// old menu item before we add the new menu item
var item = tools_menu.findMenuItem(name);
if (item)
tools_menu.remove(item);
// note: the 'click' event for this item must be connected
// after this function is called
item = new MenuItem(name);
// the index of the separator right after the 'Projects...'
// menu item
var projects_pos = tools_menu.findMenuItem("Projects...") + 1;
// the index of the separator right before the 'Options...'
// menu item
var options_pos = tools_menu.findMenuItem("Options...") - 1;
// if we couldn't find one of the menu items, return
if (projects_pos < 0 || options_pos < 0)
return;
// if these two menu items have the same index, we need
// to insert another separator to make the 'Extensions Group'
if (projects_pos == options_pos)
{
// this is the first extension menu item that is being
// inserted in the 'Extensions Group'
tools_menu.insertSeparator(projects_pos++);
tools_menu.insert(item, projects_pos);
}
else
{
// we've already created the 'Extensions Group', all
// we have to do is insert the menu item at the end
// of the area
tools_menu.insert(item, options_pos);
}
return item;
}
Putting the whole script together, and reorganizing it slightly, we have the following:
if (Extension.isContextPackage())
{
// if the script is packaged as an extension, add a
// menu item to the host application and connect the
// menu item click event to a handler
var item = insertToolsMenuItem("Hello World...");
item.click.connect(onHelloWorldMenuItemClicked);
}
else
{
// if the script is not packaged as an extension,
// simply show the alert message
alert("Hello World");
}
function onHelloWorldMenuItemClicked()
{
alert("Hello World");
}
// start the application event loop to process
// application events
Application.run();
function getToolsMenu()
{
// summary: returns the host application Tool menu item
// get the host application's main menu
var menu_bar = HostApp.getFrameMenu();
var tools_menu;
// get the Tool menu item; if it doesn't exist, create it
var id = menu_bar.findMenu("Tools");
if (id < 0)
{
tools_menu = new Menu("Tools");
menu_bar.insert(tools_menu, menu_bar.getMenuCount()-1);
}
else
{
tools_menu = menu_bar.getMenu(id);
}
return tools_menu;
}
function insertToolsMenuItem(name)
{
// summary: inserts a menu item with the given name in
// an appropriate location in the host application's Tool
// menu item
// get the Tool menu item
var tools_menu = getToolsMenu();
// if the menu item already exists, first remove the
// old menu item before we add the new menu item
var item = tools_menu.findMenuItem(name);
if (item)
tools_menu.remove(item);
// note: the 'click' event for this item must be connected
// after this function is called
item = new MenuItem(name);
// the index of the separator right after the 'Projects...'
// menu item
var projects_pos = tools_menu.findMenuItem("Projects...") + 1;
// the index of the separator right before the 'Options...'
// menu item
var options_pos = tools_menu.findMenuItem("Options...") - 1;
// if we couldn't find one of the menu items, return
if (projects_pos < 0 || options_pos < 0)
return;
// if these two menu items have the same index, we need
// to insert another separator to make the 'Extensions Group'
if (projects_pos == options_pos)
{
// this is the first extension menu item that is being
// inserted in the 'Extensions Group'
tools_menu.insertSeparator(projects_pos++);
tools_menu.insert(item, projects_pos);
}
else
{
// we've already created the 'Extensions Group', all
// we have to do is insert the menu item at the end
// of the area
tools_menu.insert(item, options_pos);
}
return item;
}
Once we've created the main script, "main.js", we need to create a small information file that tells Strata about the script. This file is called "info.xml", and it's packaged up together with "main.js" into the extension file.
To create the "info.xml" file:
- Go to the File menu and select New->Script, which will open a new text editor without any script.
- Go to the File menu and select "Save As External".
- In the "Save As" dialog, save the script as "info.xml" to your desktop.
Then, in this file, enter the following and save it:
<?xml version="1.0">
<extension_info>
<guid>{9642c44c-f790-4f16-9d46-fb54fc97d1a7}</guid>
<name>Hello World Extension</name>
<author>Hello World Industries, Inc.</author>
<bitmap>icon.png</bitmap>
<startup>main.js</startup>
<copyright>(c) 2008 Hello World Industries, Inc.</copyright>
<description>A simple "Hello World" extension.</description>
<major_version>1</major_version>
<minor_version>0</minor_version>
<subminor_version>0</subminor_version>
</extension_info>
The fields in this "info.xml" file are as follows:
- <guid> Unique ID for the extension (generate using the extension wizard)
- <name> Name shown in the Extensions panel in Kirix Strata.
- <author> Author of the extension.
- <bitmap> Bitmap shown in the Extensions panel in Kirix Strata.
- <startup> Initial script file to be called when the extension is run.
- <copyright> Copyright information for the extension.
- <description> Description shown in the Extensions panel in Kirix Strata.
- <major_version> Major version shown in the Extensions panel in Kirix Strata.
- <minor_version> Minor version shown in the Extensions panel in Kirix Strata.
- <subminor_version> Subminor version shown in the Extensions panel in Kirix Strata.
Once you've created this information file, it's time to package up the main.js file and the info.xml file into an extension, and install it. To do this:
- Zip up the newly create main.js and info.xml into a new zip file called hello_world.zip.
- Rename hello_world.zip to hello_world.kxt. The "kxt" extension tells Strata that the file in question is an extension.
- In Strata, go to the Tools menu and select Tools->Extensions.
- In the Extensions panel, click on the "Add Extensions…" button to add the hello_world.kxt extension.
- Then, when the "Hello World" extension appears in the list of extensions, press the "Start Now" button in the newly inserted extension.
- Close the Extensions panel and open the Tools menu again.
- Click on the newly inserted "Hello World…" item to show the "Hello World" message.