# Printer-friendly Output

# Reference

This is a growing collection of Helma documentation categorized by functionality.

## Application Object

`app` represents the Application object in Hop. By adding variables to this object it is possible to store temporary global variables, which are independent from request evaluator threads, i.e. they are shared by all threads. But be aware that they are not persistent and lost as soon as you restart the application.

### errorCount

Syntax
`app.errorCount`

Description
Returns the number of Errors which occured due to User Requests since the application has been started.
Note: "File Not Found" Errors are not counted.

Example
`res.write(app.errorCount);
8`

### getActiveThreads()

Syntax
`app.getActiveThreads()`

Description
This function returns the number of currently working Request Evaluator Threads.
If this number reaches the maximum allowed Treads Hop returns a "maximum thread count reached" error page.

Example
`res.write(app.getMaxThreads());
12`

### getFreeThreads()

Syntax
`app.getFreeThreads()`

Description
This function returns the number of additional of Request Evaluator Threads, which could be created at the current moment.
This is equivalent to the number of current Threads deducted from the number of maximum THreads.

Example
`res.write(app.getActiveThreads());
2
res.write(app.getMaxThreads());
12
res.write(app.getFreeThreads());
10`

### getMaxActiveThreads()

Syntax
`app.getMaxActiveThreads()`

Description
This function returns the historic maximum number of Request Evaluator Threads, which occured at some point since the application has been started.

Example
`res.write(app.getMaxActiveThreads());
6`

### getMaxThreads()

Syntax
`app.getMaxActiveThreads()`

Description
This function returns the historic maximum number of Request Evaluator Threads, which occured at some point since the application has been started.

Example
`res.write(app.getMaxActiveThreads());
6`

### requestCount

Syntax
`app.requestCount`

Description
Returns the number of HTTP-Requests since the application has been started.

Example
`res.write(app.requestCount);
231`

### setMaxThreads()

Syntax
`app.setMaxThreads(Number)`

Description
This function enables the programmer to adjust the number of maximum allowed Request Evaluator Threads without having to restart the application.

Example
`app.setMaxThreads(10);
res.write(app.getMaxThreads());
10`

### skinfiles

Array containing the skins of an application.

Syntax
`app.skinfiles`

Description
To access the actual content of a skin file in the inner loop you'd say `app.skinfiles[a][b]`. To access a skin file by name, you'd say something like `app.skinfiles.root.test`.

Example
`for (var a in app.skinfiles) {
res.write(a + "<br>");
for (var b in app.skinfiles[a]) {
res.write("&nbsp;&nbsp;&nbsp;&nbsp;" + b + "<br>");
}
}`

### upSince

Syntax
`app.upSince`

Description
Returns the createtime of the Application object, i.e. the time when the application was started.

Example
`res.write(app.upSince.format("dd.MMM yyyy HH:mm"));
06.Sep 2001 13:09`

### xmlrpcCount

Syntax
`app.xmlrpcCount`

Description
Returns the number of XML-RPC-Requests since the application has been started.

Example
`res.write(app.xmlrpcCount);
12`

## Date Object

### format()

Formatting a date string for custom output.

Syntax
`Date.format(String)`

Description
Formats the date string of a date object for custom output. The function's string parameter is used as a pattern to describe the desired format. Most common are the following pattern letters:

    Symbol Meaning              Presentation   Example
    ------ -------              ------------   -------
    y      year                 (Number)       1996
    M      month in year        (Text, Number) July, 07
    d      day in month         (Number)       10
    h      hour in am/pm (1~12) (Number)       12
    H      hour in day (0~23)   (Number)       0
    m      minute in hour       (Number)       30
    s      second in minute     (Number)       55
    E      day in week          (Text)         Tuesday
    a      am/pm marker         (Text)         PM

Please note that the output is depending on the locale settings of the Helma server. For further reference refer to the examples below or directly to the documentation of the Java SimpleDateFormat class.

Example
`var d = new Date();
res.write(d.format("EEE d.M.y, HH:mm'h'"));
Thu 9.8.01, 15:15h
res.write(d.format("dd. MMM. yyyy, hh:mm:ss aa"));
09. Aug. 2001, 03:15:44 PM
res.write(d.format("hh:mm:ss,SS"));
03:15:44,609
res.write(d.format("EEEEE d MMMMM yyyy"));
Thursday 9 August 2001
res.write(d.format("EEE, d MMM yyyy HH:mm:ss z"));
Thu, 9 Aug 2001 15:15:44 CET`

## Direct Database Interface

The Direct Db interface allows the developer to directly access relational databases defined in the `db.properties` file without going through the Helma objectmodel layer.
`var con = getDBConnection("db_source_name");`
This returns a Connection object from the Helma connection pool that can be used as specified by the Fesi DbAccess protocol, except that it is not necessary to call the `connect()` and `disconnect()` functions.
`var rows = con.executeRetrieval("select title from dummy");
while (rows.next())
res.write(rows.getColumnItem("title")+"<br>");
`

## FESI Extensions

FESI (pronounced like fuzzy) is a full implementation of the ECMAScript language as defined in the ECMA technical standard specification ECMA-262 (June 97 edition).
ECMAScript is largely equivalent to the JavaScript language version 1.1 or to the core part of JScript, but without the extensions specific to Netscape Navigator. Instead, FESI comes with its own extensions as listed below.
These parts of the documentation are adapted from the FESI Homepage courtesy by Jean-Marc Lugrin.

### throwError()

Syntax
`throwError(stringOrException)`

Description
This function throws an exception, ie. the script interpreter aborts, the `stringOrException` parameter is converted to a string and immediately written to the response object for output.

Example
`throwError("Aborting without any reason");
Runtime error Aborting without any reason
detected at line 1 of function 'main_action' in string starting with: 'function main_action (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) {'...`

### tryEval()

Syntax
`tryEval(functionString, defaultValue)`

Description
`tryEval()` evaluates the `functionString` parameter just like the standard ECMAScript function `eval()` does, but returns an object with two properties, `value` and `error`.
If the evaluation is successful, the `value` property contains the result of the evaluation and the `error` property equals to `null` (which tests as `false`).
If the evaluation results in an error, the `value` property has either the value of the optional `defaultValue` parameter (if specified) or `undefined`, and the `error` property contains an object describing the error, which is guaranteed to test as `true`.
The `error` object string representation is some description of the error. In the future more detailed error information may be available.

Example
`var trial = tryEval("undefinedFunction()", -1)
if (trial.error)
res.writeln(trial.error);
res.writeln(trial.value);
FESI.Exceptions.EcmaScriptException: Runtime error no global function named 'undefinedFunction' detected at line 1 in string: 'undefinedFunction()'
-1`

## FTP Client

This object represents an Ftp client object for sending and receiving files from an Ftp server. The constructor is called FtpServer and invoked as follows:
`var ftp = new FtpClient("ftp.mydomain.com");`
The Ftp client needs Daniel Savarese's NetComponents library in the classpath in order to work.
Functions and Properties

### ascii()

Syntax
`FtpObject.ascii();`

Description
Set transfermodus to Ascii for transmitting text.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.ascii();`

### binary()

Syntax
`FtpObject.binary();`

Description
Set transfer mode to binary for transmitting images and other non-text files.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.binary();`

### cd()

Syntax
`FtpObject.cd(Path);`

Description
Change the current path on the FTP server.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
// use absolute pathname
ftp.cd("/home/users/fred/www");
// change to parent directory
ftp.cd("..");
// use relative pathname
ftp.cd("images");`

### getFile()

Syntax
`FtpObject.getFile(RemoteFile, LocalFile);`

Description
Transfer a file from the server to the local file system.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.getFile(".htaccess", "htaccess.txt");`

### getString()

Syntax
`FtpObject.getString(RemoteFile);`

Description
Retrieves a file from the remote server and returns it as string.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
var str = ftp.getString("messages.txt");`

### lcd()

Syntax
`FtpObject.lcd(LocalPath);`

Description
Change the local path of the FTP client.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
// use absolute pathname
ftp.lcd("/home/users/fred/www");
// change to parent directory
ftp.lcd("..");
// use relative pathname
ftp.lcd("images");`

### login()

Syntax
`FtpObject.login(UserName, Password);`

Description
Log in to the FTP server. The function returns `true` if successful, `false` otherwise.

Example
`var ftp = new FtpClient("ftp.host.dom");
if (ftp.login("user", "pass"))
res.write("User logged in.");
else
res.write("Unable to log in.");
User logged in.`

### logout()

Syntax
`FtpObject.logout();`

Description
Terminate the current FTP session.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.putFile("htaccess.txt", ".htaccess");
ftp.logout();`

### mkdir()

Syntax
`FtpObject.mkdir(String);`

Description
Creates a new directory on the server. The name of the directory is determined as the function's string parameter. Returns `false` when an error occured (e.g. due to access restrictions, directory already exists etc.), otherwise `true`.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
if (ftp.mkdir("testdir"))
ftp.cd("testdir")
else
ftp.logout();`

### putFile()

Syntax
`FtpObject.putFile(LocalFile, RemoteFile);`

Description
Transfers a file from the local file system to the remote server. Returns `true` if the transmission was successful, otherwise `false`.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
if (ftp.putFile("testfile"))
res.write("File transfered successfully.");
else
res.write("Transfer error.");
File transfered successfully.`

### putString()

Syntax
`FtpObject.putString(String, RemoteFile);`

Description
Transfer text from a string to a file on the remote server.

Example
`var ftp = new FtpClient("ftp.host.dom");
ftp.login("user", "pass");
ftp.putString("Hello, World!", "message.txt");`

## Global Functions

These are the global functions that are added to the Hop interpreter in addition to the standard global functions found in a JavaScript interpreter.

### authenticate()

Syntax
`authenticate(UserNameString, PasswordString)`

Description
This function authenticates against a standard Unix password file, which is both secure (encrypted using CRYPT) and can be managed using the `htpasswd` utility which is included in the Apache web server distribution.
The function just returns `true` or `false`, so you have to make sure yourself you remember the result in the user object by setting some cache flag.
The function compares the two arguments with the data in the file called "passwd", stored in the Helma installation directory. This can be overridden by a file with the same name in the application directory.
Please note that this function is currently not working under Windows because the Windows version of Apache's `htpasswd` can use a special type of MD5 encryption only.

Example
`var login = authenticate("user", "pass");
if (login)
res.write("Welcome back!");
else
res.write("Oops, please try again...");
Welcome back!`

### countActiveUsers()

Syntax
`countActiveUsers()`

Description
Returns the number of currently active users.

Example
`var nr = countActiveUsers();
res.write(nr);
18`

### createSkin()

Syntax
`createSkin(String)`

Description
Turns a string into a Skin object ready for rendering with `renderSkin()` and `renderSkinAsString()`.

Example
`var str = "Hello, <% response.body %>!";
var skin = createSkin(str);
res.body = "World";
renderSkin(skin);
Hello, World!`

### encode()

Preparing a string for smooth html output.

Syntax
`encode(string)`

Description
Encodes a string by replacing linebreaks with `<br>` tags and diacritical characters as well as html tags with their equivalent html entities.

Example
`var str = encode("<b>Bananer växer\n minsann inte på träd.<b>");
res.write(str);
&lt;b&gt;Bananer v&auml;xer
<br> minsann inte p&aring; tr&auml;d.&lt;/b&gt;`

### encodeForm()

Syntax
`encodeForm(String)`

Description
Similar to `encode()` this functions substitutes html entities but leaves newlines untouched. This is what you usually want to do for encoding form content (esp. with textarea values).

Example
`var str = encodeForm("<b>Bananer växer\n minsann inte på träd.<b>");
res.write(str);
&lt;b&gt;Bananer v&auml;xer
minsann inte p&aring; tr&auml;d.&lt;/b&gt;`

### encodeXml()

Preparing a string for smooth xml output.

Syntax
`encodeXml(string)`

Description
Encodes a string by replacing `<` and `>` with `&lt;` and `&gt;` as well as `&` with its html entity `&amp;`.

Example
`var str = encodeXml("<title>Smørebrød</title>");
res.write(str);
&lt;title&gt;Sm&amp;oslash;rebr&amp;oslash;d&lt;/title&gt;`

### format()

Preparing a string for smooth html output.

Syntax
`format(string)`

Description
Encodes a string similar to `encode()` but keeping the markup tags and trying to avoid `<br>` tags where possible (e.g. in table structures).

Example
`var str = encode("<b>Bananer växer\n minsann inte på träd.<b>");
res.write(str);
<b>Bananer v&auml;xer
<br> minsann inte p&aring; tr&auml;d.</b>`

### getActiveUsers()

Retrieving active Users.

Syntax
`getActiveUsers()`

Description
Returns an array that contains all User Objects of users who are currently browsing the Hop application. This includes users who are logged in as well as anonymous users.

Example
`var myUsers = getActiveUsers();
res.write(myUsers);
UserNode 6df1869674117400@e4042e487b, UserNode Snoopy, UserNode Woodstock`

### getAllUsers()

Retrieving the names of all registered users.

Syntax
`getAllUsers()`

Description
Returns an array that contains the names of all registered users. Use the getUser() function to retrieve the actual user object. This is to be used with caution with large amounts of users.

Example
`var myUsers = getAllUsers();
res.write(myUsers);
Snoopy, Lucy, Linux, Woodstock
res.write(getUser(myUsers[1]));
UserObject Lucy`

### getProperty()

Retrieving a global Property.

Syntax
`getProperty(string)`

Description
Returns a Property named `string` stored in one of the files app.properties or server.properties. If the Property exists in both of the files, app.properties overwrites server.properties. This way server.properties defines Properties for all applications which app.properties can refine for a particular application. app.properties is located in the top directory of a Hop application. server.properties is located in the Hop installation directory.
There is a complete list of Hop's System Properties

Example
`var smtp = getProperty("smtp");
res.write(smtp);
mail.helma.org`

### getURL()

Retrieving the content behind a URL.

Syntax
`getURL(url)`

Description
Allocates and retrieves a remote file from a url.

Example
`var url = getURL("http://helma.org/");
res.write(url);`
...see helma.org :->
`var url = getURL("ftp://user:pass@ftp.server.dom/welcome.txt");
res.write(url);
Welcome on the FTP server of server.dom!`
`var url = getURL("file:///home/snoopy/www/title.txt");
res.write(url);
The Nudist on the Late Shift`

### getUser()

Retrieving a User Object.

Syntax
`getUser(string)`

Description
Returns a Hop Object describing the user referred to with `string`.

Example
`var myUser = getUser("Snoopy");
res.write(myUser.email);
atomicdog@helma.org`

### getUserBySession()

Retrieving a User Object.

Syntax
`getUserBySession(sessionId)`

Description
Returns a user object with a certain session id (= Helma session cookie).

Example
`
var id = user.sessionID;
var user = getUserBySession(id);
res.write(user.name);
Snoopy`
(quite recursive, isn't it?)

### isActive()

Determining whether a user is logged in.

Syntax
`isActive(userObject)`

Description
Returns `true` if the user referred to by the user object is logged in.

Example
`var user = getUser("Snoopy");
res.write(isActive(user));
false`

### renderSkin()

Syntax
`renderSkin(String, ParameterObject)`

Description
Renders a global skin (ie. a skin file inside the `global` directory). The name of the skin is defined by the string parameter.
A skin is a file that only contains markup (e.g. Html or Xml) and macros. Macros are references to Helma functions wrapped in special tags (`<%` and `%>`). For more information about skin and macro techniques please refer to the section about Helma Skins.
Optionally, a JavaScript object can be assigned to the function call as second argument. This object's properties later can be accessed from the skin via pseudo-macro calls of the kind `<% param.PropertyName %>`
If a `param` property is not set but referred to in the skin file, it will be replaced with an empty string. Please note that this behaviour is different from generic macro calls.

Example
Contents of the file `global/example.skin`:`
<html>
<head>
<title>Hello, <% param.title %>!</title>
</head>
<body bgcolor="<% param.bgcolor %>">
I greet you <% param.amount %> times.
</body>
</html>`
Rendering the skin:`
var param = new Object();
param.bgcolor = "#ffcc00";
param.title = "World";
param.amount = "12345";
renderSkin("example", param);
<html>
<head>
<title>Hello, World!</title>
</head>
<body bgcolor="#ffcc00">
I greet you 12345 times.
</body>`

### renderSkinAsString()

Syntax
`renderSkinAsString(String, ParameterObject)`

Description
Renders a global skin just the same way as `renderSkin()` does. The only difference is though, that this function returns the result as string instead of immediately writing it to the response object.

Example
`var str = renderSkinAsString("example", param);
res.write(str);`
which is equivalent to
`renderSkin("example", param);`

### stripTags()

Removing markup tags from a string.

Syntax
`stripTags(string)`

Description
Removes any `<` and `>` as well as everyhing between both of these two characters. In other words: extracts the essence of the text from a string without anything that looks like markup.

Example
`var str = "<html><b>The Nudist on the Late Shift</b></html>";
res.write(str);
The Nudist on the Late Shift`

### write()

Syntax
`write(String)`

Description
This function echoes the string parameter on the console display. Very useful for debugging purposes.

Example
`write("Hello, Console!");
Hello, Console!`

### writeln()

Syntax
`writeln(String)`

Description
This function echoes the string parameter on the console display and additionally a newline character. Very useful for debugging purposes.

Example
`writeln("Hello,");
writeln("Console!");
Hello,
Console!`

## Hop Object

The HopObject is the basic building block of a Hop applications. The website root object, the user object, as well as any custom type defined by the application are HopObjects and inherit all functionality described below.
In addition to defining and scripting special types of HopObjects it is possible to extend all HopObjects at once by defining a prototype called `hopobject`.
Functions and Properties

### add()

Adding a Subnode to a Hop Object.

Syntax
`hopObject.add(hopObject)`

Description
Adds a Hop Object as new Subnode to another Hop Object. The new Subnode is added after the last Subnode already contained in the Hop Object.

Example
`res.write(root.size());
0
var myStory= new story();
root.add(myStory);
res.write(root.size());
1`
It is also possible to add a bunch of Subnodes with only one function call:
`var myAuthor= new author();
var myTitle= "The Nudist On The Late Shift";
var myStory= new story();
root.add(myAuthor, myTitle, myStory);
res.write(root.size());
3`

### addAt()

Adding a Subnode to a Hop Object.

Syntax
`hopObject.addAt(number, hopObject)`

Description
Adds a Subnode to a Hop Object. Unlike `add()` the position of the Subnode is determined by a number as first parameter in the function call.
Using addAt() instead of add() usually only has an effect with the embedded database, since the order of objects stored in a relational database depends on the value of some column. Thus when adding objects stored in a relational database, one may as well use add().

Example
`res.write(root.get(23));
null
var myStory= new story();
root.addAt(23, myStory);
res.write(root.get(23));
hopObject story`

### cache

Syntax
`HopObject.cache`

Description
Each HopObject contains a `cache` object to store temporary properties (e.g. strings, numbers or other objects) in. These properties can be accessed in any thread until the application is restarted or the HopObject is invalidated, either manually using the invalidate() function or whenever Helma is fetching the HopObject's data from a remote database.
There is no way to make the `cache` object persistent.

Example
`user.cache.message = "This is a temporary message."`

### contains()

Determining if a Hop Object contains a certain Subnode.

Syntax
`hopObject.contains(hopObject)`

Description
Returns the index position of a Subnode contained by a Hop Object (as usual for JavaScript starting with `0` referring to the first position). The index position is a relative value inside a Hop Object (not to be confused with a Hop ID which is unique for each Hop Object). If there is no appropriate Subnode inside the Hop Object the returned value equals `-1`

Example
`var obj = root.get("myObject");
res.write(root.contains(obj));
23
obj = root.get("blobject");
res.write(root.contains(obj));
-1`

### count()

Counting Subnodes.

Syntax
`hopObject.count()`

Description
Returns the amount of Subnodes contained in a Hop Object.

Example
`res.write(root.count());
5`

### editor()

Syntax
`hopObject.editor(string, width, height)`

Description
Returns an input element for the object's property defined by the string parameter. The result can be used inside an Html form. The property's value is set to the form elements value. If the optional height parameter is set, a text area is used instead of a one-line text field.

Example
`var editor = this.editor("title", 20);
res.write("<form>" + editor + "</form>");
<form><input type="text" name="title" size="20" value="Hello, World"></form>
var editor = this.editor("bodytext", 20, 5);
res.write("<form>" + editor + "</form>");
<form><textarea name="bodytext" cols="20" rows="5" wrap="virtual">When the going gets tough, the tough goes shopping.</textarea></form>`

### get()

Retrieving Properties and Subnodes.

Syntax
`hopObject.get(stringOrNumber)`

Description
Retrieves a Property or a Subnode of a known Hop Object. The type of the result depends on the type of the submitted parameter: a number will retrieve the Subnode of the Hop Object at the corresponding index position, a string the corresponding Property of the Hop Object. Finally, a number as string retrieves the subnode with the corresponding Hop ID.

Example
`root.get(0);
HopObject author
root.get(1);
HopObject story
root.get("date");
Wed Oct 18 02:01:41 GMT+01:00 1971
root.get("title");
The Nudist On The Late Shift
root.get("1");
HopObject author`

### href()

Getting a Hop Object's url-compatible reference.

Syntax
`hopObject.href()
hopObject.href(string)`

Description
Returns the absoulte url path of a Hop Object relative to the application's root. Any string parameter is simply appended to the return value. Useful to refer to a Hop Object in a markup tag (e.g. with a `href` parameter in an html `<a>` tag).

Example
`var obj = root.get(0);
res.write("<a href=\"" + obj.href() + "\">");
<a href="/main/">
res.write("<a href=\"" + obj.href("edit") + "\">");
<a href="/main/edit">
`

### invalidate()

Delete a Hop Object from the cache.

Syntax
`hopObject.invalidate()`

Description
Marks a HopObject as invalid so that it is fetched again from the database the next time it's accessed. In other words, use this function to kick an object out of Helma's database cache.

Example
`var obj = this.get(0);
obj.invalidate();`

### list()

Listing Hop Objects.

Syntax
`hopObject.list()`

Description
Returns an array including all Subnodes of a Hop Object. Useful if array data is required, however general use should be avoided in favor of the method described below.

Example
`var objectList = root.list();
for (var i=0; i<objectList.length; i++){
var myObject = objectList[i];
res.write(myObject.created + "<br>");
}
Wed Oct 18 02:01:41 GMT+01:00 1971
Fri Nov 03 13:25:15 GMT+01:00 2000
Mon May 29 07:43:09 GMT+01:00 1999`
With increasing amounts of Subnodes tied to a Hop Object the use of `list()` becomes seriously inefficient – as long as not all Subnodes really need to be read out. This is due to the creation of a JavaScript Array containing the whole bunch of Subnodes each time the `list()` function is called. Instead, it is recommended to determine the amount of Subnodes using the `count()` function and looping through them using `get()`:
`var amount = root.size();
for (var i=0; i<amount; i++){
var myObject = root.get(i);
res.write(myObject.created + "<br>");
}
Wed Oct 18 02:01:41 GMT+01:00 1971
Fri Nov 03 13:25:15 GMT+01:00 2000
Mon May 29 07:43:09 GMT+01:00 1999`

### remove()

Removing a Subnode.

Syntax
`hopObject.remove()`

Description
Removes a known Subnode from a Hop Object. The subnode can be determined e.g. via the `get()` function.

Example
`res.write(root.size());
24
var myObject = root.get(5);
root.remove(myObject);
res.write(root.size());
23`

### renderSkin()

Syntax
`HopObject.renderSkin(String, ParameterObject)`

Description
Renders a skin of this object. The name of the skin is defined by the string parameter.
A skin is a file that only contains markup (e.g. Html or Xml) and macros. Macros are references to Helma functions wrapped in special tags (`<%` and `%>`). For more information about skin and macro techniques please refer to the section about Helma Skins.
Optionally, a JavaScript object can be assigned to the function call as second argument. This object's properties later can be accessed from the skin via pseudo-macro calls of the kind `<% param.PropertyName %>`
If a `param` property is not set but referred to in the skin file, it will be replaced with an empty string. Please note that this behaviour is different from generic macro calls.

Example
Contents of the file `root/example.skin`:`
<html>
<head>
<title>Hello, <% param.title %>!</title>
</head>
<body bgcolor="<% param.bgcolor %>">
I greet you <% param.amount %> times.
</body>
</html>`
Rendering the skin:`
var param = new Object();
param.bgcolor = "#ffcc00";
param.title = "World";
param.amount = "12345";
root.renderSkin("example", param);
<html>
<head>
<title>Hello, World!</title>
</head>
<body bgcolor="#ffcc00">
I greet you 12345 times.
</body>`

### renderSkinAsString()

Syntax
`HopObject.renderSkinAsString(String, ParameterObject)`

Description
Renders a skin of this object just the same way as `renderSkin()` does. The only difference is though, that this function returns the result as string instead of immediately writing it to the response object.

Example
`var str = root.renderSkinAsString("example", param);
res.write(str);`
which is equivalent to
`root.renderSkin("example", param);`

### set()

Changing Properties and Subnodes.

Syntax
`hopObject.set(stringOrNumber, value)`

Description
Replaces the value of a Property or Subnode with a new value.

Example
`res.write(root.get(23));
null
var myAuthor = new author();
root.set(23, myAuthor);
res.write(root.get(23));
hopObject author
res.write(root.title);
null
var myTitle = "The Nudist On The Late Shift";
root.set("title", myTitle);
res.write(root.title);
The Nudist On The Late Shift`

### setParent()

Defining a Hop Object as parent for a Subnode.

Syntax
`hopObject.setParent(hopObject)`

Description
Sometimes it is necessary to set a Subnode's parent to a certain Hop Object. This is caused by the way Hop caches Subnodes. Especially if you are retrieving a Subnode from a relational database through different ways (e.g. by using `subnoderelation`) and you want to remove this Subnode or apply the `href()` function on it.

Example
`var trash = user.stories.get(23);
trash.setParent(root);
root.remove(trash);`

### size()

Counting Subnodes.

Please refer to `count()`.

### _id

Syntax
`hopObject._id`

Description
Returns the internal id of the object. This property is assigned by Helma and cannot be set.

Example
`var obj = root.get(0);
res.write(obj._id);
43`

### _parent

Syntax
`hopObject._parent`

Description
Returns the parent object of this object.

Example
`var obj = root.get(0);
res.write(obj._parent);
HopObject root`

## Image Processing

The image object allows you to read, manipulate, and save images. An image object is created using the `Image()` constructor.
`var img = new Image(imageUrl);
var img = new Image(imageUrl, imageFilter);`
For this to work, you must have Sun's Jimi library in your classpath.
Example:
`var img = new Image("http://helma.org/image.gif");
var img = new Image("file:///home/images/image.jpg");
var filter = new Packages.com.sun.jimi.core.filters.Rotate(90);
var img = new Image("http://helma.org/image.gif", filter);`.
Please refer to the `getSource()` function for details and examples of the `imageFilter` parameter.

### crop()

Cutting out a rectangular area of an image.

Syntax
`imageObject.crop(x, y, width, height)`

Description
Cuts out (crops) a rectanglular area of an image. The dimensions of the area are calculated from the x- and y-offset from the top left corner of the image as upper left reference point to x + width and y + height as lower right reference point.

Example
`var img = new Image("http://helma.org/images/original.gif");
res.write("<img src=\"/images/original.gif\">");
img.crop(58,9,48,21);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");
`

### drawLine()

Adding a drawn line to an image.

Syntax
`imageObject.drawLine(x1, x2, y1, y2)`

Description
Draws a line onto an image. The line starts at the reference point defined by the offsets x1 and y1 from the top left corner of the image and ends at the reference point defined by the offsets x2 and y2.

Example
`var img = new Image("http://helma.org/images/originalgif");
res.write("<img src=\"/images/original.gif\">");
img.setColor(204,0,0);
img.drawLine(58,26,100,26);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");
`

### drawRect()

Adding a drawn rectangle to an image.

Syntax
`imageObject.drawRect(x, y, width, height)`

Description
Draws a rectangle onto an image. The rectangle's dimensions are calculated from the x- and y-offset from the top left corner of the image as upper left reference point to x + width and y + height as lower right reference point.

Example
`var img = new Image("http://helma.org/images/originalgif");
res.write("<img src=\"/images/original.gif\">");
img.setColor(204,0,0);
img.drawRect(57,8,46,20);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");
`

### drawString()

Adding text to an image.

Syntax
`imageObject.drawString(string, x, y)`

Description
Draws a string onto an image. The string will be drawn starting at the x- and y-offset from the top left corner of the imaget.

Example
`var img = new Image("http://helma.org/images/original.gif");
res.write("<img src=\"/images/original.gif\">");
img.setColor(204,0,0);
img.drawString("rocks!",82,35);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");
`

### fillRect()

Adding a filled rectangle to an image.

Syntax
`imageObject.fillRect(x, y, width, height)`

Description
Draws a filled rectangle onto an image. The rectangle's dimensions are calculated from the x- and y-offset from the top left corner of the image as upper left reference point to (x + width) and (y + height) as lower right reference point.

Example
`var img = new Image("http://helma.org/images/original.gif");
res.write("<img src=\"/images/original.gif\">");
img.setColor(204,0,0);
img.fillRect(58,27,43,29);
img.saveAs("/www/images/processed.gif");
res.write("<img src=\"/images/processed.gif\">");
`

### getHeight()

Determining the height of an image.

Syntax
`imageObject.getHeight()`

Description
Returns the height of an image measured in pixels.

Example
`var img = new Image("http://helma.org/images/hop.gif");
res.write("<img src=\"/images/hop.gif\">");
var height = img.getHeight();
res.write(height);
35`

### getSource()

Syntax
`Image.getSource()`

Description
To use the image filters provided by the Jimi java image processing package `Packages.com.sun.jimi.core.filters`, a specific class of image objects is needed. Helma wraps the `sun.awt.image` objects into a custom class. To use Helma image objects with Jimi's filters these have to be "unwrapped" using the `getSource()` function.
The following filter functions have been successfully applied the way as described in the examples above:

- `Rotate(degreeNumber)`
- `Gray()`
- `Flip(typeNumber)`
- `Oil(intensityNumber)`
- `Invert()`
- `Smooth(intensityNumber)`
- `Shear(degreeNumber)`
- `Edges()`
- `Shrink(multiplyNumber)`
- `Enlarge(divisionNumber)`

Please take into account that the quality might suffer depending on the type and amount of filters applied to the image.

Example
`var img = new Image("http://helma.org/static/original.jpg");
var rotator = new Packages.com.sun.jimi.core.filters.Rotate(45);
var processed = new Image(img, rotator);
processed.saveAs("/path/to/static/processed.jpg");
res.write("&lt;img src=\"/static/processed.jpg\&gt;");
var img = new Image("http://helma.org/static/original.jpg");
var filter = Packages.com.sun.jimi.core.filters;
var oil = new filter.Oil(img.getSource(), 3);
var processed = new Image(img, oil);
processed.saveAs("/path/to/static/processed.jpg");
res.write("&lt;img src=\"/static/processed.jpg\&gt;");
`

### getWidth()

Determining the width of an image.

Syntax
`imageObject.getWidth()`

Description
Returns the width of an image measured in pixels.

Example
`var img = new Image("http://helma.org/images/hop.gif");
res.write("<img src=\"/images/hop.gif\">");
var width = img.getWidth();
res.write(width);
174`

### reduceColors()

Setting the color depth of an image.

Syntax
`imageObject.reduceColors(number)`

Description
Reduces the number of colors used in an image to the amount specified with number. Use with caution, generally. Gif images need a color depth of max. 256 colors maximum.

Example
`var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");
img.reduceColors(8);
img.saveAs("/www/images/processed.jpg");
res.write("<img src=\"/images/processed.jpg\">");
`

### resize()

Setting the dimensions of an image.

Syntax
`imageObject.resize(width, heigth)`

Description
Sets the height and width of an image to new values. The new width and height have to be integers, so be careful to round the new values eventually. In case of a gif image be sure to reduce the image to 256 colors after resizing by using the `reduceColors()` function.

Example
`var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");
var factor = 0.66;
var wd = Math.round(img.getWidth() * factor);
var ht = Math.round(img.getHeight() * factor);
img.resize(wd, ht);
img.saveAs("/www/images/processed.jpg");
res.write("<img src=\"/images/processed.jpg\">");
`

### saveAs()

Storing an image on the hard disk.

Syntax
`imageObject.saveAs(path)`

Description
Stores the binary data of an image on the hard disk. Before the image is converted into the appropriate image format determined by the file extension (please refer to the JIMI documentation for a detailed overview of the available formats).

Example
`var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");
img.saveAs("/www/images/processed.png");
res.write("<img src=\"/images/processed.png\">");
`

### setColor()

Selecting a drawing color.

Syntax
`imageObject.setColor(colorOrRgbValues)`

Description
Determines the color of the following drawing actions either by a 24-bit integer (0–16777215) or by an rgb-tuple (each element ranging from 0 to 255).

Example
`var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");
img.setColor(16777215);
img.fillRect(80, 50, 30, 30);
img.setColor(255, 255, 0);
img.fillRect(65, 15, 30, 30);
img.saveAs("/www/images/processed.png");
res.write("<img src=\"/images/processed.png\">");
`

### setFont()

Selecting a typeface for font setting.

Syntax
`imageObject.setFont(name, style, size)`

Description
Determines the font face, style and size of a font to be used in following `drawString()` actions. name specifies the font face as string (e.g. "sansserif", "dialog").
The integer style sets the font to normal (0), bold (1), italic (2) or bold and italic (3). size, also an integer, refers to the font size in pixels.
Please take a look at this description about adding fonts to the Java Runtime for a detailed look onto Java's font mechanics.

Example
`var img = new Image("http://helma.org/images/original.jpg");
res.write("<img src=\"/images/original.jpg\">");
img.setColor(255, 255, 255);
img.setFont("serif", 0, 12);
img.drawString("I shot the serif.", 50, 15);
img.setFont("sansserif", 1, 14);
img.drawString("But I didn't shoot", 10, 100);
img.setFont("monospaced", 2, 16);
img.drawString("the monotype.", 15, 115);
img.saveAs("/www/images/processed.png");
res.write("<img src=\"/images/processed.png\">");
`

## Java Object Access

See the Fesi documentation for Java object access.
For starters, objects from the core Java Api (in the java.* packages) can be instantiated directly, while other Java classes need the Packages prefix.
`var buffer = new java.lang.StringBuffer();
var foo = new Packages.com.bar.util.Foo();`
Use Sun's Api Specification to find out more about Java objects.
Example`
/**
* This function returns a date string
* from a Date object formatted
* according to a custom locale.
*/
function getLocaleDate(date) {
// Here the locale is set (english / Ireland):
var locale = new java.util.Locale("en", "IE");
// Creating the date formatter:
var dateFormat = new java.text.SimpleDateFormat("EEEE d MMMM yyyy, HH:mm", locale);
// Formatting the Date object as date string:
var dateString = dateFormat.format(date);
return(dateString);
}`

## Mail Client

Mail objects are used to send email via Smtp and are created by using the Mail() constructor:
`var mail = new Mail();`
The mail object can than be manipulated and sent using the functions listed below.
You'll need the JavaMail library installed for this to work. Also, don't forget to set your mail server via the smtp property.
Note: Make sure that the Smtp server itself is well-configured, so that it accepts Mails coming from your server and does not deny relaying.
Best and fastest configuration is of course if you run your own Smtp server (e.g. sendmail), but which might be a bit tricky to set up.

### addBCC()

Syntax
`mailObject.addBCC(EmailString, NameString)`

Description
Adds a recipient to the list of addresses to get a "blind carbon copy" of the message. The first argument specifies the receipient's e-mail address. The second argument is optional and specifies the name of the recipient.

Example
`var mail = new Mail();
mail.addBCC("hop@helma.at");
mail.addBCC("tobi@helma.at", "Tobi Schaefer");`

### addCC()

Syntax
`mailObject.addCC(EmailString, NameString)`

Description
Adds an address to the list of carbon copy recipients. The first argument specifies the receipient's e-mail address. The second argument is optional and specifies the name of the recipient.

Example
`var mail = new Mail();
mail.addCC("hop@helma.at");
mail.addCC("tobi@helma.at", "Tobi Schaefer");`

### addPart()

Syntax
`mailObject.addPart(Object)`

Description
Adds a mime-part to the message. The mime-part (e.g. a gif image or an rtf document) has to be wrapped into a `java.io.File` object.

Example
`var file = new java.io.File("/home/snoopy/woodstock.jpg");
var mail = new Mail();
mail.setFrom("snoopy@doghouse.com");
mail.setTo("woodstock@birdcage.com");
mail.setSubject("Look at this!");
mail.addPart("I took a photograph from you. Neat, isn't it? -Snoop");
mail.addPart(file);
mail.send();`

### addText()

Syntax
`mailObject.addText(String)`

Description
Appends a string to the body text of the message. Note that this method will overwrite any multi-mime-parts already added to the message.

Example
`var mail = new Mail();
mail.addText("Hello, World!");`

### addTo()

Syntax
`mailObject.addTo(EmailString, NameString)`

Description
Adds a receipient to the address list of the message. The first argument specifies the receipient's e-mail address. The second argument is optional and specifies the name of the recipient.

Example
`var mail = new Mail();
mail.addTo("hop@helma.at");
mail.addTo("tobi@helma.at", "Tobi Schaefer");`

### send()

Syntax
`mailObject.send()`

Description
This function actually sends the message created with the mail object using the smtp server as specified in an appropriate property file.

Example
`var mail = new Mail();
mail.addTo("watching@michi.tv", "michi");
mail.addCC("franzi@home.at", "franzi");
mail.addBCC("monie@home.at");
mail.setFrom("chef@frischfleisch.at", "Hannes");
mail.setSubject("Registration Conformation");
mail.addText("Thanks for your Registration...");
mail.send();`

### setFrom()

Syntax
`mailObject.setFrom(EmailString, NameString)`

Description
Sets the sender of the message. The first argument specifies the sender's e-mail address. The second argument is optional and specifies the name of the sender.

Example
`var mail = new Mail();
mail.setFrom("tobi@helma.at", "Tobi Schaefer");`

### setSubject()

Syntax
`mailObject.setSubject(String)`

Description
Sets the subject of the message.

Example
`var mail = new Mail();
mail.setSubject("Hello, World!");`

### status

Syntax
`mailObject.status`

Description
Returns the current status of the message. If an error has occured the status is greater than zero. Here are the error codes:

    nr   error description
    --   -----------------
     0   no error
    10   error with setSubject()
    11   error with addText()
    12   error with addPart()
    20   error with addTo()
    21   error with addCC()
    22   error with addBCC()
    30   error while trying to send the Message

Example
`var mail = new Mail();
mail.addTo("idont@know@myemail.com");
res.write(mail.status);
20`

## Number Object

### format()

Syntax
`Number.format(PatternString)`

Description
Formats a number as string for custom output. The function's string parameter is used as a pattern to describe the desired format. In the pattern string you can use the following pattern letters:

    Symbol   Meaning
    ------   -------
      0      a digit
      #      a digit, zero shows as absent
      .      placeholder for decimal separator
      ,      placeholder for grouping separator.
      E      separates mantissa and exponent for
             exponential formats.
      ;      separates formats.
      -      default negative prefix.
      %      multiply by 100 and show as percentage
      ?      multiply by 1000 and show as per mille
      ¤      currency sign; replaced by currency symbol;
             if doubled, replaced by international currency
             symbol. If present in a pattern, the monetary
             decimal separator is used instead of the decimal
             separator.
      X      any other characters can be used in the prefix
             or suffix.
      '      used to quote special characters in a prefix
             or suffix.

Please note that the output is depending on the locale settings of the Helma server. For further reference refer to the examples below or directly to the documentation of the Java DecimalFormat class

Example
`var nr = 12345.67890;
res.write(nr.format("#.00 ¤"));
12345,68 öS
res.write(nr.format("###,####.00 ¤¤"));
1.2345,68 ATS
var nr = 0.0987654321;
res.write(nr.format("0.###%"));
9,877%
var nr = 7.9E-5
res.write(nr.format("0.######"));
0,000079`

## Object-Relational Mapping

The Hop comes with the ability to store Hop objects natively in its embedded object database. However, for many purposes it is advisable to use an external relational database product for object storage for reasons including features, accessability and reliability.
A prototype can specify how its data properties are stored in relational database tables by providing a types.properties file. This file is located in the prototype's directory along with the prototype code. It is basically a Java properties file that maps JavaScript properties to database columns. Unfortunately, the mapping rules have gone from clean and simple to rather obscure as features were added to the Hop.
A basic type.properties file might look like this:

>     _datasource = my_data_source
>     _tablename = my_table

>     _subnodes = <child.db_parent_id
>     _id = id

>     title = db_title
>     createdate = db_createdate
>     owner = db_owner_id>user.id

The first thing we notice is that some properties begin with an underscore ("_") while others don't. This is a simple convention to separate those properties which are needed by Hop internally from those that specify script-accessible properties of this prototype.
In the following, we describe the different kinds of entries that can be used in type.properties files.

- Storage Location: _datasource, _tablename
- Object Hierarchy: _subnodes, _properties
- Object Identity: _id, _name, _idgen
- Primitive Type Property Mappings (string, number, date etc)
- Object Property mappings
- Virtual Subnodes
- Advanced Settings (cachemode, loadmode, etc)

## Path Object

Description
The objects in the uri path of a request are not only accessible as array members of the global `path` object, but also as named properties of `path` via the name of their prototype. For instance, if an object in the uri path has a prototype called "story", it will be accessible as `path.story`.
Example
Assumed the request path of an application is
`/h_files/myDocument/storyTitle/23
for (var i=0; i<path.length; i++)
res.writeln(path[i]);
HopObject file
HopObject document
HopObject story
HopObject note
var obj = path.story;
res.write(obj);
HopObject story`

## Property Files

Helma's property files are simple text files containing information e.g. about which applications to start, about the database connection, server configuration etc.
There is no general syntax of the various properties, however most of the time each line represents a property's assignment the way
`propertyName = propertyValue(s)`
A line starting with a hash character # will be handled as comment:
`# This is a comment.
This is no comment. # This is no comment, either.`

### app.properties

Description
This file is located in an application's directory (e.g. `apps/myApp/`). A wide variety of properties can be defined here. Generally, any imaginable name can be used as a property and assigned a string value the way
`propertyName = propertyValue`
Properties defined in such a way can be evaluated from inside Helma's scripting environment by using the `getProperty()` function.
However, there is a bunch of pre-defined properties that are used internally by Helma. Be careful not to accidentally bend these special properties for your custom purposes or your application eventually could behave unexpectedly.
Many of those pre-defined properties also can be defined server-wide in `server.properties`. However, any property that is set there will be overwritten by an appropriate setting in `app.properties`.
Example
`# Setting some properties:
backgroundColor = #3333ff
title = "Hello, World!"`
Accessing the properties e.g. from `root/main.hac`:
`var bgColor = getProperty("backgroundColor");
res.write(bgColor);
#3333ff
var title = getProperty("title");
res.write(title);
Hello, World!`

### apps.properties

Description
This file is located in Helma's installation directory. It contains a list of applications that helma will handle (ie. start up, execute, update). The name of an application refers to a directory with the same name in helma's `apps` directory.
Example
`hopblog`
`antville`
`gong`
`kolin`
Special case: `appname = self`
Using this syntax enables the application `appname` to script Helma herself. Currently, there can be only one application set-up this way:
Example
`hopblog
antville
base = self
gong`

### db.properties

Description
This file is located in Helma's installation directory. It contains a list of data sources and data source properties setting up the basic connection between Helma and relational databases.
To define data sources, the property `sources` is assigned a comma-separated list of names (certainly, the list can contain only one element):
`sources = dataSourceName`
In consequence the following properties of the data source(s) must be set:
`dataSourceName.url
dataSourceName.driver
dataSourceName.user
dataSourceName.password`
Example
`sources = mySqlDB, oracleDB, hsqlDB
mySqlDB.url = jdbc:mysql://db.domain.com/mysql
mySqlDB.driver = org.gjt.mm.mysql.Driver
mySqlDB.user = username
mySqlDB.password = secretPassword
oracleDB.url = jdbc:oracle://db.domain.com/oracle
oracleDB.driver = oracle.jdbc.driver.OracleDriver
oracleDB.user = username2
oracleDB.password = secretPassword2
hsqlDB.url = jdbc:hsqldb:dbData
hsqlDB.driver=org.hsqldb.jdbcDriver
hsqlDB.user=sa
hsqlDB.password=`

### server.properties

Description
This file is located in Helma's installation directory. It contains pre-defined properties that are used internally by Helma for configuring the server.
Many of these properties also can be defined in an `app.properties` file. Any property that is set there will overwrite the appropriate setting in `server.properties`.
Example
`# Setting a custom locale:
country = AT
language = de
# Defining a mail server:
smtp = mail.domain.dom`

### type.properties

This file is located in a prototype's directory (e.g. `apps/myApp/myProto`). It contains definitions that specify the way Helma maps the relational database tables to hierarchical objects.

#### Basic Mappings

The `_db` entry describes the database to use for storing objects of this type. `dbname` is the name of a database as defined in the `db.properties` file.
`_db = dbname`
The `_table` entry tells Helma which table to use for objects of this type within the database.
`_table = TABLENAME`
The `_id` entry defines the column to use as primary key. Helma requires a single primary key with no other functionality.
`_id = ID_COLUMN`
The optional `_name` entry tells Helma which database column to use as object name. This is important for the user prototype, since it defines which column constitutes the user name.
`_name = NAME_COLUMN`
The `_parent` entry contains a list of properties of objects of this type to be used as parent. Objects must know their parent in order to generate correct URLs in their `href()` function.
`_parent = property1, property2`

#### Simple Property Mappings

The mappings for simple (non-object) properties simple map a property name of the specified object type to a column of the relational database table. The type of the property or column need not be specified. Helma does all necessary conversion when reading or writing a property value.
`prop1 = DB_COLUMN_1
prop2 = DB_COLUMN_2`
To prevent a property from being overwritten by the application it can be made readonly.
`prop1.readonly = true`

#### Mountpoint Mappings

Mountpoints provide a simple way to directly attach a prototype to the URL path. If the path contains the name of a mountpoint the prototype's objects are accessible simply by adding their id (or a property defined by `._accessname`) to the URL string.
`myMountpoint = mountpoint(myProto)`
In the example above, the path `/myMountpoint/23/test` refers to the action `test.hac` of the object with id 23, which is derived from the `myProto` prototype.

#### Object Property Mappings

Properties that contain other objects are defined by the object keyword and the prototype name of the referenced object in brackets. The object reference is resolved via two entries:
`prop3 = object (protoype)
prop3.local = LOCAL_DB_COLUMN
prop3.foreign = FOREIGN_DB_COLUMN`
`prop3.local` specifies the part of the reference in the local database-table, `prop3.foreign` the column in the table where objects of the referenced prototype are stored. By executing the assignment `obj.prop3 = someObject`, the database-column specified by `prop3.local` will be set to the value of `FOREIGN_DB_COLUMN`, or `null` if `someObject == null`.

#### Collection Mappings

The following section describes the entries used to define collections of objects. There are two kinds of collections: First, every object can itself act as a collection, and second, it can define additional properties to be used as collections. Direct descendents are defined with entries starting with `_children`, while additional collections are defined using their property name. Otherwise the syntax for the two is the same.
The following are examples for simple collection mappings for both the direct descendants and those contained in a collection-property called `prop4`. The `.foreign` entry is used in both cases to specify a column in the foreign table used to collect the objects. Exactly those objects will be collected whose `FOREIGN_DB_COLUMN` value equals the `LOCAL_DB_COLUMN` value of the object holding the collection. Leaving away `.local` and `.foreign` creates a collection of all available objects of the specified prototype.
`_children = collection (protoype)
_children.local = LOCAL_DB_COLUMN
_children.foreign = FOREIGN_DB_COLUMN
prop4 = collection (protoype)
prop4.local = LOCAL_DB_COLUMN
prop4.foreign = FOREIGN_DB_COLUMN`
By executing `obj.add(otherObj)` resp. `obj.prop4.add(otherObj)`, the `FOREIGN_DB_COLUMN` will be set to the value of `LOCAL_DB_COLUMN`.
By default, child objects can be accessed from the containing parent object through their index-position or `ID` value. Additionally the entry `.accessname` can be used to specify a database column in the child table. The value of this column will be used as name of the objects contained in this collection.
`prop4.accessname = DB_COLUMN`
With the above mapping, an object contained in the `prop4` collection with a `DB_COLUMN` value of "xyz" would be reachable as `this.prop4.xyz` from the containing object.
`filter` can be used to add an additional condition for the selection of objects which is not dependent on the object holding the collection. `order` contains the sorting to be applied to the child objects. `group` tells Helma to group the objects in the collection according to the value in `DB_GROUPCOLUMN`.
`prop4.filter = DB_FILTERCOLUMN is not null
prop4.order = DB_ORDERCOLUMN desc
prop4.group = DB_GROUPCOLUMN
prop4.group.order = DB_GROUPORDERCOLUMN`
Notice the two appearences of `order` above. The first one, `prop4.order` sorts the objects, the second, `prop4.group.order` sorts the grouped objects, that Helma will create as a result of the `group` entry. With this it's also possible to sort the grouped objects ascending, but the contents of the grouped objects descending.

#### Additional Join Conditions

For both object and collection mappings, it is possible to provide any number of additional restraints used to join the local with the other table to further limit the selected objects.
`prop4.local.1 = FIRST_LOCAL_COLUMN
prop4.foreign.1 = FIRST_FOREIGN_COLUMN
prop4.local.2 = SECOND_LOCAL_COLUMN
prop4.foreign.2 = SECOND_FOREIGN_COLUMN`
Whenever one specifies more than one restraint, the use of `.[Number]` is mandatory.

### List of All Properties

This is a list of all pre-defined properties that can be set in one of the files `server.properties`, `db.properties` and `app.properties` (`type.properties` coming soon). Which property is available in which file is displayed in the "Range" column.

Property | Range | Description
--- | --- | ---
`actionExtension` | server, app | Sets the extension for Helma action files. Default setting is `actionExtension = .hac`. Changing this setting is not recommended. Use with caution and at your own risk.
`allowWeb` | server | Specifies ip adresses (or networks) that are allowed to connect to the Helma rmi servlet server (port 5055). For more than one ip adress put a comma between the entries, subnets should be written as i.e. `192.168.0.*`.
`allowXmlRpc` | server, app | Same as `allowWeb`, but for the xml-rpc server (port 5056).
`appHome` | server | Defines the path to the location of Helma applications. If not specified, `[hopHome]/apps` will be used.
`appsPropFile` | server | Sets the location of the `apps.properties` file (i.e. for security reasons). The default is the `root` directory of your Helma installation.
`baseURI` | server, app | Specifies the prefix to add to urls generated by a Helma application. For example, if your application is "mounted" at `/myapp` in the server's document tree, you'd set `baseURI = /myapp`.
`cachesize` | server | Defines the size of the node cache in bytes.
`charset``` | server | Defines the character encoding. The default is ISO-8859-1 (Western) encoding. You can use any of the encodings supported by Java.
`country` | server | Like language, this is used to set the country for proper localisation. For details you can refer to this list of country codes.
`dbHome` | server | Defines the path to the location of the embedded database files. If not specified, `[hopHome]/db` will be used
`debug` | server, app | Switches between "normal" logging output (`debug = false`) and the extensive "debug" output (`debug = true`) which may be useful when developing. Default setting is `false`.
`exposeTemplates` | server, app | To directly call a `.hsp` (instead of a `.hac`) file via the http interface it is necessary to set `exposeTemplates = true`. Default setting is `false`.
`hopHome` | server | This property defines the Helma working directory, e.g. `hopHome = /hop/apps`. If not specified, the current directory is used.
`hrefSkin` | app | The name of the skin that is assigned to this property is used to extend the `href()` function. E.g. setting `hrefSkin = customLink` will cause Helma to set `param.path` to the result of `href()` and to render the skinfile `customLink.skin` as if the function `renderSkin("customLink", param)` was invoked. Take a look at the `hrefSkin` example for the whole picture.
`idBaseValue` | server, app | Used to set the current value of the internal ID generator. This is useful when starting a new internal db (where the id value would normally start at 1), but relational dbs are used that already contain data. Only applied if the current counter value is smaller than `idBaseValue`.
`language` | server | Used to set the language on systems where the Java runtime doesn't recognize it by itself (e.g. Linux), which may be important for date formatting and the like. Refer to this list of language codes for details.
`linkMethod` | server, app | `linkMethod = query | path` Deprecated.
`logDir` | server, app |
`logSQL` | server, app | With this option set to "true", Helma writes out all sql `select` statements to the logging device (and just those, so you won't find any `insert`, `update` or `delete` statements in there).
`maxThreads` | server | Sets the maximum number of Helma's Java threads, e.g. `maxThreads = 12`. This is one of the parameters you should adjust for each server depending on the applications you run. If you see an error like "maximum thread count reached" you should increase the value of this property.
`paranoid` | server | If set to `true`, switches Helma to "paranoid" mode, which means that it won't accept connections from servers with unknown ip adresses >you can specify allowed ip adresses with the `allowWeb` and `allowXmlRpc` properties. Default setting is `paranoid = false`.
`requestTimeout` | server | Defines the time in seconds after which a request receives a timeout. Normally there is no need to change this value, but if you have tasks in your Helma application that take a longer time, you should increase this value.
`scriptExtension` | server, app | Used to change the extension of script files. Default setting is `scriptingExtension = .js`. Changing this setting is not recommended. Use with caution and at your own risk.
`sessionTimeout` | server, app | This determines the time (in minutes) after which an inactive session becomes invalid.
`skinPath` | app |
`smtp` | server, app | Specifies an smtp server, e.g. `smtp = mail.server.dom`. If you want Helma to send e-mail you should define this property.
`sources` | db | Defines the name of one or more data sources to be used in an application, e.g. `sources = mySqlDB, oracleDB`. Each data source has then to be specified in detail by assigning values to its properties `url`, `driver`, `user` and `password`. Refer to the description of `db.properties` for further information.
`templateExtension` | server, app | Used to change the extension of Helma template files. Changing this setting is not recommended. Use with caution and at your own risk.
`timezone` | server | It might be necessary to explicitly set the timezone for Helma. If `new Date()` puts out the wrong date, check if this option was set correctly. For details, refer to this list of timezones
`xmlparser` | server, app | Can be used to specify a different Xml parser, e.g. `xmlparser = minml`. The default value is `openxml`.
`XmlRpcAccess` | server, app | Functions which should be callable via Xml-Rpc need to be listed in this property on a per-application basis. The list contains entries of the kind `prototype.function` for each exposed function separated by commata, e.g. `XmlRpcAccess = weblog.getStory, weblog.showStatus`.
`xmlRpcHandlerName` | app | Setting this property makes it possible to change the name under which an application is registered with the XML-RPC server. This means that the functions exposed via XML-RPC will have a "blogger" prefix. For instance a function called "newPost" will be XML-RPC callable as `blogger.newPost` instead of `antville.newPost`.

### Example Files

server.properties
`# Setting the extension for Helma action files:
actionExtension = .hac
# Allowing some ip addreses for web access:
allowWeb = 192.168.0.*, 194.152.169.160
# Allowing some ip addreses for xml-rpc access:
allowXmlRpc = 192.168.0.*
# Setting the directory where Helma applications reside:
appHome = /helma-1.2/apps
# Setting the location of apps.properties:
appsPropFile = /helma-1.2/propFiles
# Setting the application's base uri:
baseURI = /apps/testApp
# Setting the size of Helma's cache memory:
cachesize = 1000
# Setting the character encoding:
charset = UTF8
# Setting the country code:
country = AT
# Setting the location of database files:
dbHome = /etc/db/helma
# Enabling debugging:
debug = true
# Enabling web access to .hsp templates:
exposeTemplates = true
# Setting the Helma working directory
hopHome = /helma-1.2
# Setting the base value to create id numbers from:
idBaseValue = 5000
# Setting the language code:
language = de
# Enabling database logging
logSQL = true
# Setting the maximum number of server threads:
maxThreads = 12
# Enabling restricted web access to the Helma server:
paranoid = true
# Setting the duration after a request times out:
requestTimeout = 60
# Setting the extension of JavaScript files:
scriptExtension = .js
# Setting the duration after an inactive session times out:
sessionTimeout = 10
# Setting a smtp server:
smtp = mail.server.dom
# Setting a relational data source:
sources = mySqlDB
# Setting the extension of Helma templates:
templateExtension = .hsp
# Setting the server's timezone:
timezone = GMT
# Enabling the MinML xml parser:
xmlparser = minml
# Defining which application functions should be accessible via xml-rpc:
XmlRpcAccess = weblog.getStory, weblog.showStatus
`

## Request Object

The request object represents the request coming from the client. It is accessible as a global variable called `req`.

### data

Syntax
`req.data.String;`

Description
Retrieves the corresponding value from the http request. The value can either come from a cookie, or from a "post" or "get" http request. Hop does not make any difference here.
The following variables are automatically set by Helma if they are available:

- `HopSession`
  The id of the current hop session cookie
- `http_browser`
  Name and version of the client Browser
- `http_host`
  Name of the local server
- `http_remotehost`
  Internet address of the user
- `http_referer`
  URL of the page which linked the user to the current page

`req.get()` provides exactly the same functionality in a what we think not as comfortable way (gotta type brackets and quotes). But it's just a matter of taste which one to use.

Example
Here we see all three methods of setting a name, value pair:
`res.write("<form action=" + root.href("showValues") + " method="post"><input name="city"><input type="submit"></form>");
res.write("<form action=" + root.href("showValues") + " method="get"><input name="district"><input type="submit"></form>");
res.setCookie("street", "Lindengasse");`
root/showValues.hac:
`res.write(req.data.city);
res.write(req.data.district);
res.write(req.data.street);`
Note: If you have got a cookie and a form element with the same name sent by "get" or "post", the cookie value will be overridden by the form value.
If you are very curious and want to see all the values sent by the http request, you can use the `getReqData()` function.

### get()

Syntax
`req.get(String)`

Description
Retrieves the corresponding value from the http request. The value can either come from a cookie, or from a "post" or "get" http request. Hop does not make any difference here.
This is an alternative way of accessing request data to the `req.data` object. Please see the req.data documentation for more information.

Example
`res.write(req.get("http_remotehost"));
127.0.0.1`

### path

Syntax
`req.path`

Description
returns the path of the current request

Example
`res.write(req.path);
docs/reference/req/path`

### session

Syntax
`req.session`

Description
returns the Session ID of the current user

Example
`res.write(req.session);
717163f187abf800@e4b40a0e88`

## Response Object

The response object represents the response to be sent back to the client. It is accessible as a global variable called `res`.

### body

Deprectated property.

This property is deprecated and will not be supported in future releases of Helma.
Use `res.data` instead, by attaching the appropriate property to it.

### cache

Syntax
`res.cache = Boolean`

Description
Specifies on a per-response base whether to allow client-side caching of the response or not. The default value is set to `true`, but can be changed globally by passing `caching=false` to the initial Helma java call. Please refer to the section about servlet properties for more details.

Example
`res.cache = true;`

### charset

Setting character encoding.

Syntax
`res.charset = CharsetString`

Description
Sets Helma's character encoding according to the list of supported encodings. By default, Helma uses ISO-8859-1 (western) encoding. It is also possible to set the encoding server or application wide using the charset property in the appropriate file.

Example
`res.charset = "UTF8";
res.write("ÄÖÜäöüß");
// this is displayed if the brower's encoding is set to "Western"
Ã„Ã–ÃœÃ¤Ã¶Ã¼ÃŸ`

### contentType

Syntax
`res.contentType = ContentTypeString`

Description
The contentType of the http response can be set manually by changing the value of this Property. The default value is "text/html".

Example
`res.contentType="text/plain";`
`res.contentType="text/xml";`

### data

`res.data` can be used to attach any property `propertyName` onto it to make it available in a skin via `<% response.propertyName %>`.
Example
== root/main.hac
`res.data.title = "Test";
res.data.body = "Hello, World!";
root.renderSkin("main");`
== root/main.skin
`<html>
<head>
<title><% response.title %></title>
</head>
<body>
<% response.body %>
</body>
</html>`

### encode()

Syntax
`res.encode(String)`

Description
Works similar to the global function `encode()` but writes the result directly to the response string buffer. Encodes a string by replacing linebreaks with `<br>` tags and diacritical characters as well as html tags with their equivalent html entities.

Example
`res.encode("<b>Bananer växer\n minsann inte på träd.<b>");
&lt;b&gt;Bananer v&auml;xer
<br> minsann inte p&aring; tr&auml;d.&lt;/b&gt;`

### encodeXml()

Syntax
`res.encodeXml(String)`

Description
Works the same way as the global Function encodeXml(), but writes the result directly to the response string buffer.

Example
`res.encodeXml("<title>Smørebrød</title>");
&lt;title&gt;Sm&amp;oslash;rebr&amp;oslash;d&lt;/title&gt;`

### error

Contains an internal Helma error message.

Syntax
`res.error`

Description
Contains a string describing an error if one should occur. If no error was detected, `res.error` contains an empty string. A good place for this function is a custom error page to display errors in a pretty layout.

Example
`res.write(res.error);
Runtime error Syntax error detected near line 1, column 24, after in string starting with: 'function main_action (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) {'...`

### format()

Syntax
`res.format(String);`

Description
Encodes a string similar to `encode()` but keeping the markup tags and trying to avoid `<br>` tags where possible (e.g. in table structures).

Example
`res.encode("<b>Bananer växer\n minsann inte på träd.<b>");
<b>Bananer v&auml;xer
<br> minsann inte p&aring; tr&auml;d.</b>`

### head

Deprectated property.

This property is deprecated and will not be supported in future releases of Helma.
Use `res.data` instead, by attaching the appropriate property to it.

### message

Buffer a string for output.

When this property is set, its value can be retrieved either by `res.message` from within an action or a JavaScript file or by `<% response.message %>` from within a skin file.
Additionally, it will survive an HTTP redirect which can be necessary to display warnings or error messages to the user. The property's value will be cleared at latest after a redirected response was output.

### redirect()

Syntax
`res.redirect(UrlString);`

Description
Redirects the user to the specified url immediately. The JavaScript code following this command will not be processed anymore.

Example
Here is a simple check using a hypothetic `isAdmin()` function to grant access to authorized people only:
`if (!user.isAdmin())
res.redirect("/main");`

### reset()

Syntax
`res.reset();`

Description
Resets the current Response StringBuffer.

Example
`res.write("Writing something to the response");
// changing my mind (e.g. an error occured somewhere)
res.reset();
res.write("Actually this is what I wanted to tell you: ...");
Actually this is what I wanted to tell you: ...`

### setCookie()

Syntax
`res.setCookie(KeyString, ValueString, NumberOfDays);`

Description
Sets a Cookie on the client machine. The third number argument is optional and specifies the number of days until the cookie expires.

Example
The following can be used to "remember" users, and automatically log them in, when they return to your site.
`res.setCookie("username", "michi", 10);
res.setCookie("password", "strenggeheim", 10);`

### title

Deprectated property.

This property is deprecated and will not be supported in future releases of Helma.
Use `res.data` instead, by attaching the appropriate property to it.

### write()

Writes to the Response StringBuffer

Syntax
`res.write(String);`

Description
Transforms the passed argument to a string (only if necessary) and appends the result to the response string buffer. Throws an error if no argument or an undefined argument is passed.

Example
`var now = new Date();
res.write("current time: " + now);
current time: Thu Feb 15 23:34:29 GMT+01:00 2001`

### writeBinary()

Syntax
`res.writeBinary(javaByteArray);`

Description
This function takes one argument, which must be a Java byte array. Useful when handling binary data retrieved via http file upload.

Example
`var upload = req.data.fileUpload;
res.writeBinary(upload);`

### writeln()

Syntax
`res.writeln(string)`

Description
Transforms the passed argument to a string (only if necessary), appends an Html break `<br>` and appends the result to the response string buffer. Throws an error if no argument or an undefined argument is passed. Useful for debugging tasks.

Example
`res.writeln("Hello,");
res.write("World!");
Hello,<br>
World!`

## Skin Object

### allowMacro()

Syntax
`allowMacro(String)`

Description
This function is necessary to limit the range of allowed macros to be rendered to an explicit set. This is useful when text entered by non-trusted users is interpreted as skins to provide macro functions on a user-level.

Example
Two macro functions defined in a JavaScript file:
`function isAllowed_macro() {
return("Hello");
}
function isForbidden_macro() {
return("World");
}`
The action that enables one of the macros:
`var str = "<% root.isAllowed %>, <% root.isForbidden %>!";
var skin = createSkin(str);
// as soon as we call allowMacro() on a skin, only those
// macros explicitely set are allowed to be evaluated.
// all others will result in an error msg.
skin.allowMacro("root.isAllowed");
renderSkin(skin);
Hello, [Macro root.isForbidden not allowed in sandbox]!`

### containsMacro()

Syntax
`containsMacro(String)`

Description
This function checks whether a skin does contain the macro specified by the string parameter. This is thus useful to make sure a user-edited skin does not contain any macro with which the application would break.

Example
`var skin1 = createSkin("myMacro");
var skin2 = createSkin("<% myMacro %>");
res.writeln(skin1.containsMacro("myMacro"));
false
res.writeln(skin2.containsMacro("myMacro"));
true`

## User Object

### lastActive()

Determine the last time of a certain user being logged in.

Syntax
`user.lastActive()`

Description
Returns a Date Object of the timestamp the current user was logged in the last time. Please note that you can use this function with the `user` prototype only, not with any user HopObject.

Example
`res.write(user.lastActive())
Thu Nov 02 16:12:13 GMT+01:00 2000`

### login()

Syntax
`UserObject.login(UserNameString, PasswordString)`

Description
Returns `true` if the user name / password pair match the stored values in the database. Otherwise it returns `false`.

Example
`var login = user.login("user", "pass");
if (login)
res.write("Welcome back!");
else
res.write("Oops, please try again...");
Welcome back!`

### onSince()

Syntax
`userObject.onSince()`

Description
Returns the date string of the time the user's session was started.

Example
`var usr = getUser("Tobi");
res.write(usr.onSince());
Fri Aug 10 16:36:36 GMT+02:00 2001`

### register()

Syntax
`userObject.register(usernameString, passwordString)`

Description
Stores this user in the database using two arguments as user name and password phrase. Returns a valid user HopObject if the transaction was successful, `false` otherwise (e.g. if a user HopObject with the same name already exists). Additional properties can be attached to the user HopObject the usual way, then.

Example
`var newUser = user.register("snoopy", "woodstock");
res.write(newUser);
HopObject snoopy
newUser.email = "snoopy@peanuts.com";
newUser.fullname = "Snoop Doggy Dogg";`

### touch()

Syntax
`UserObject.touch()`

Description
Refreshes the user's session, moving its expiration date to now plus session timeout unless it is "touched" again either by the user requesting a page or calling `touch()`.

Example
`var usr = getUser("tobi");
usr.touch();`

### uid

Syntax
`UserObject.uid`

Description
Returns the database-internal id of the current user. If the user is logged into the application `uid` is set, otherwise it is null.

Example
`res.writeln(user);
res.writeln(user.uid);
TransientNode [session cache]
null
res.writeln(user);
res.writeln(user.uid);
HopObject tobi
tobi`

## XML and HTML Parsing

Syntax
`getXmlDocument(XmlString)
getXmlDocument(UrlString)
getXmlDocument(java.io.InputStream)
getXmlDocument(java.io.Reader)
getHtmlDocument(HtmlString)
getHtmlDocument(UrlString)
getHtmlDocument(java.io.InputStream)
getHtmlDocument(java.io.Reader)
jdomize(DomDocument)`

Description
The Xml and Html parsing functions take one parameter and try to parse it into a Dom document object. If the document could not be retrieved or contains invalid markup, the functions return null.
The Dom object can be processed according to the Java language binding for Dom Level 1.
Be sure to update your Helma 1.x installation with the patched openxml.jar file for this to work.
As an alternative to the W3C Dom Api, Dom documents may be transformed into JDOM documents using the global `jdomize()` function. JDom documents are far easier to handle than Dom documents. Be sure to have the `jdom.jar` file in your classpath for this to work.

Example
This `.hac` file fetches an Xml document containing news headlines and generates some simple Html output.
`var xmltext = getXmlDocument("http://www.salon.at/news/lxml");
if (xmltext == null)
res.write("Error retrieving Xml document!");
else {
var newslist = xmltext.firstChild.childNodes;
for (var i=0; i<newslist.length; i++) {
var newsitem = newslist.item(i);
// make sure we only look at <headline> elements,
// ignoring whitespace CDATA
if (newsitem.nodeName == "headline") {
// get the <title> element
var titleElem = newsitem.getElementsByTagName("title").item(0);
// get the character data contained in it
var title = titleElem.firstChild.nodeValue;
// get the <url> element
var urlElem = newsitem.getElementsByTagName("url").item(0);
// get the actual url character data
var url = urlElem.firstChild.nodeValue
res.write ("<a href='"+url+"'>"+encode(title)+"</a><br>");
}
}
}`

## XML-RPC

Remote procedure calls via Xml-Rpc are very straightforward with the Hop for both client and server side.

### XML-RPC Client

Description
Xml-Rpc calls are performed using a `Remote` object. `Remote` objects are created with the Url of the Xml-Rpc service. Functions of the remote Xml-Rpc service can then be called just like local functions.
To compensate for the missing exception handling, `Remote` objects return result wrappers which contain either the result of the remote function, or a description of the error if one occurred.
Example
`var xr = new Remote("http://helma.domain.tld:5056/");
var msg1 = xr.helmaorg.getXmlRpcMessage();
if (msg1.error)
res.write(msg1.error);
else
res.write(msg1.result);
Hello, Xml-Rpc World!
var msg2 = xr.hotelGuide.hotels.grandimperial.getXmlRpcMessage();
if (!msg2.error)
res.write(msg2.result);
Welcome to the Grand Imperial Hotel, Vienna!
var msg3 = xr.kolin.document.comments["23"].getXmlRpcMessage();
if (!msg3.error)
res.write(msg3.result);
Here you can write your comments.
var xr = new Remote("http://betty.userland.com/RPC2");
var state = xr.examples.getStateName(23);
if (!state.error)
res.write(state.result);
Minnesota`

### XML-RPC Server

Description
The Helma Xml-Rpc server is running on port 5056 by default, or port+1 if the `-p` command line parameter is specified.
You can make any Helma function callable via Xml-Rpc. To do so, the function needs to be added to the XmlRpcAccess property in the `app.properties` file.
For example, if you have two functions, `listThings()` and `addThing()`, in the `root` prototype you want to call via Xml-Rpc, add the following line to the `app.properties` file of your application:
`XmlRpcAccess = root.listThings, myprototype.addThing`
Xml-Rpc function names have the application name as first element followed by an optional object path within the application and the actual function name. Thus, a function called `sayHello()` in the `root` directory of an application called `myapp` would result in an Xml-Rpc function name of `myapp.sayHello`.
There are a few things to consider when working with server side Xml-Rpc:

- There is no Helma user object associated with an Xml-Rpc request.

- There is no request object associated with an Xml-Rpc request.

- You can pass any primitive Javascript types as parameters as well as objects and arrays, but should not pass a persistent HopObject directly as parameter or return value. Xml-Rpc can't handle objects with circular references, i.e. if `obj1` has a reference to `obj2`, `obj2` must not have a reference to `obj1`.