24.10.2013 Views

FotoWeb 6.0 User Guide - Customization - FotoWare

FotoWeb 6.0 User Guide - Customization - FotoWare

FotoWeb 6.0 User Guide - Customization - FotoWare

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Customizing<br />

<strong>FotoWeb</strong> <strong>6.0</strong><br />

Copyright (C) <strong>FotoWare</strong> a.s 1997-2007. All rights reserved.<br />

This document gives an overview of the techniques available for customizing <strong>FotoWeb</strong>.


Customizing <strong>FotoWeb</strong> 3.0<br />

Table of Contents<br />

1 Introduction............................................................................................................................................. 3<br />

1.1 Recommended knowledge.................................................................................................................... 3<br />

2 <strong>Customization</strong> of <strong>FotoWeb</strong> ....................................................................................................................... 4<br />

2.1 Scripting.............................................................................................................................................. 4<br />

2.2 Scripting in <strong>FotoWeb</strong>........................................................................................................................... 5<br />

2.3 Tags.................................................................................................................................................... 6<br />

2.4 Command requests ............................................................................................................................ 14<br />

2.5 Include files ....................................................................................................................................... 15<br />

2.6 Script rules ........................................................................................................................................ 16<br />

2.7 Template validation ........................................................................................................................... 18<br />

3 Creating a <strong>FotoWeb</strong> template ................................................................................................................. 24<br />

3.1 The first step – a Html page ............................................................................................................... 24<br />

3.2 Adding the first tag ............................................................................................................................ 25<br />

3.3 Adding ‘ImageList’ tag....................................................................................................................... 29<br />

3.4 Displaying images .............................................................................................................................. 33<br />

3.5 Creating page navigation .................................................................................................................... 36<br />

4 Tips and tricks ....................................................................................................................................... 40<br />

4.1 Evaluating multiple conditions............................................................................................................ 40<br />

4.2 Special archive................................................................................................................................... 40<br />

4.3 Image marking................................................................................................................................... 41<br />

4.4 Creating loops ................................................................................................................................... 42<br />

4.5 Displaying navigation information ...................................................................................................... 43<br />

5 Auto search scripts ................................................................................................................................. 44<br />

6 Indexes .................................................................................................................................................. 46<br />

6.1 Figures .............................................................................................................................................. 46<br />

6.2 Tables ............................................................................................................................................... 46<br />

6.3 Screenshots ....................................................................................................................................... 46<br />

6.4 Examples........................................................................................................................................... 46<br />

2 / 47 <strong>FotoWare</strong>


1 Introduction<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

<strong>FotoWeb</strong> offers many powerful features that allow web designers to customize the look and feel of the application,<br />

and also to some degre150<br />

e change the functionality of a web site based on <strong>FotoWeb</strong>. The goal of this document is to give the reader the<br />

necessary knowledge to create custom sites based on <strong>FotoWeb</strong>.<br />

1.1 Recommended knowledge<br />

Persons with knowledge of HTML programming (“manual coding”) can do customization of <strong>FotoWeb</strong>. Experience<br />

with scripting using dynamic server platforms (such as ASP, ASP.NET, JSP or PHP) will give you a head start.<br />

<strong>FotoWare</strong> 3 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

2 <strong>Customization</strong> of <strong>FotoWeb</strong><br />

All <strong>FotoWeb</strong> pages (FWX) are produced based on <strong>FotoWeb</strong> script templates. The templates are a mix of Htmlcode<br />

and <strong>FotoWeb</strong> ’tags’, a kind of pseudo-html. By changing the templates you can completely customize the look<br />

and feel and functionality of <strong>FotoWeb</strong>.<br />

Following the same idea as the scripting technologies, the <strong>FotoWeb</strong> tags serve as the interface to inner functionality<br />

of <strong>FotoWeb</strong>. With these tags, we can tell <strong>FotoWeb</strong> to perform a specific operation and from the same tags we can<br />

retrieve desired information processed by <strong>FotoWeb</strong>. Before going any further, lets look at some basic scripting<br />

concepts.<br />

2.1 Scripting<br />

The following figures illustrate some basic processing and transmission concepts among Html, Asp and Fwx pages.<br />

<br />

. . .<br />

<br />

5 – 2 = 3.<br />

<br />

<br />

Figure 1: A mathematical expression displayed by an Html page.<br />

<br />

. . .<br />

<br />

<br />

<br />

<br />

Figure 2: A mathematical expression evaluated and displayed by an Asp page.<br />

<br />

. . .<br />

<br />

5 – 2 = .<br />

<br />

<br />

Figure 3: A mathematical expression evaluated and displayed by an Fwx page.<br />

All three pages in the above figures will finally display the string ‘5 – 2 = 3.’ in the client’s browser while the actual<br />

pages are designed and processed differently. The Html page must store the final results of the expression in the<br />

page itself. Upon request, this page is transmitted to the client AS IS. The Asp and Fwx pages are utilizing scripting<br />

to allow the final result to be evaluated and added to the page dynamically upon a request. Contents of the raw<br />

page enclosed within the script identifiers (‘’ and ‘’) are replaced with proper Html code before<br />

transmission to the client.<br />

The Asp and Fwx pages are also Html pages with or without special identifiers such as ‘’ (Asp) and<br />

‘’ (Fwx). It is, however, the extension of these pages that inform IIS which module is responsible of<br />

processing and transmitting the page. IIS redirects requests made to Asp pages to the Asp processing module in IIS.<br />

Similarly, <strong>FotoWeb</strong> handles requests made to Fwx pages. Both modules will then scan their requested pages<br />

looking for the identifiers and process the requests made within them. The identifiers are then removed or replaced<br />

with proper Html code and, finally, the pages are transmitted to the client.<br />

4 / 47 <strong>FotoWare</strong>


2.2 Scripting in <strong>FotoWeb</strong><br />

Customizing <strong>FotoWeb</strong> 3.0<br />

As in ASP programming, <strong>FotoWeb</strong> uses special prefix and postfix identifiers to create its tags to be able to recognize<br />

them among Html code in a page. These identifiers are “”, without quotes. In Asp programming,<br />

the prefix and postfix identifiers create a context that is processed by the Asp processing module. For example:<br />

<br />

Figure 4: Multiple actions performed in a context created by Asp identifiers.<br />

In <strong>FotoWeb</strong>, each action is enclosed by identifiers so that the prefix and postfix identifiers always appear on the<br />

same line. It is possible to create a multi line context in <strong>FotoWeb</strong> as well, but with slightly different rules that will<br />

be discussed later. In <strong>FotoWeb</strong>, the same actions would be repeated as follows:<br />

5 – 1 = .<br />

5 – 2 = .<br />

5 – 3 = .<br />

5 – 4 = .<br />

5 – 5 = .<br />

Figure 5: Multiple actions performed in multiple contexts created by <strong>FotoWeb</strong> identifiers.<br />

<strong>FotoWeb</strong> provides a large collection of actions that can be called to perform different operations. These actions can<br />

be divided into two categories:<br />

1. Tags. Also called Commands.<br />

2. Command Requests<br />

A tag is what is enclosed and immediately called within identifiers “”. See ‘MathEval’ tag in figure 4. The<br />

command requests are types of ‘hidden’ Fwx pages that do not exist physically. The difference between these types<br />

of actions lies in the way they are used and will be discussed later.<br />

As in all scripting languages, <strong>FotoWeb</strong> also requires a harmonious uniformity in the templates and a steadfast<br />

adherence to some basic guidelines. To achieve this goal, <strong>FotoWeb</strong> provides a set of rules to obey when writing or<br />

updating templates. These rules are explained in ’<strong>FotoWeb</strong> script rules’ later in this document. However, to<br />

understand the rules, you first need to know the basic elements of <strong>FotoWeb</strong> templates – tags, attributes, variables,<br />

conditions and command requests.<br />

<strong>FotoWare</strong> 5 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

2.3 Tags<br />

A tag is an action or functionality identifier that triggers desired functions in <strong>FotoWeb</strong>. The operations performed<br />

by the tags can be divided into four different sections:<br />

1. Something changes in memory/disk for later use.<br />

2. A single result is processed.<br />

3. A collection of results is processed.<br />

4. No result is processed. An evaluation is performed.<br />

The tags that change something in memory or on disk are simply removed from the final Html after processing. For<br />

example:<br />

Example 1: ‘SetVariable’ tag creates a variable in memory.<br />

In this example, the tag ‘SetVariable’ create a variable named ‘someVariable’ with a value of ‘some value’ and stores<br />

it in the memory. The entire string is removed from the final processed Html.<br />

The example:<br />

Example 2: ’InsertVariable’ displays its results immediately.<br />

In this example, the tag ‘InsertVariable’ inserts the value of a variable named ‘someVariable’ in its place. The final<br />

processed Html now contains the value of ‘someVariable’ instead of the above string.<br />

The tags that process a collection of results are a hybrid of the two examples above. Lets look at the following<br />

command:<br />

Example 3: ‘ImageList’ tag processes a collection of results.<br />

In this example, the tag ‘ImageList’ is called. This tag creates a collection of results that can be accessed through<br />

variables such as ‘imageList.currentArchive.id’ etc. In the final Html, the tag strings such as ‘’<br />

are simply removed, while the tag variables are replaced with their corresponding values.<br />

Finally, there are tags that process no result, but rather perform an evaluation. For example:<br />

Example 4: ‘CompareNumbers’ tag creates an evaluation context.<br />

In this example, the tag ‘CompareNumbers’ performs an evaluation where the current archive id is compared with<br />

the number 5001. If they match then the code in the tag’s context is executed and/or included in the final Html.<br />

As you may have noticed in the above examples, some tags are single line commands that end with<br />

/%><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

while others are multi line tags where the last line is same as the tags name in the form<br />

<br />

This difference is due to how information is retrieved from the tag and is identified as empty and non-empty tags.<br />

6 / 47 <strong>FotoWare</strong>


2.3.1 Empty tags<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

Tags that change something in memory and/or return a single result are defined on a single line and have no<br />

context. In the final Html, these tags are either removed or replaced with the result and are, therefore, called empty<br />

tags. For example:<br />

<br />

Example 5: 'MathEval' is an empty tag.<br />

In this example, the tag ‘MathEval’ processes the expression and the result is available immediately.<br />

2.3.2 Non-empty tags<br />

Tags that processes a collection of results or perform an evaluation are defined on multiple lines. Their definition<br />

consists of a starting tag with the tag name and an ending tag with the same tag name. Everything between these<br />

starting and ending tags becomes the context of the command. This context can consist of regular Html code,<br />

command’s variables and conditions and other commands. For example:<br />

<br />

Bla bla bla…<br />

You have<br />

<br />

images in your shopping cart.<br />

Bla bla bla…<br />

<br />

Example 6: 'ShoppingCartList' is a non-empty tag.<br />

In this example, the tag ‘ShoppingCartList’ is called that instructs <strong>FotoWeb</strong> to collect all the information about<br />

logged on user’s shopping cart and stores the results in a collection in memory. These results can then be accessed<br />

through the tag’s access points (variables and conditions) within the tag’s context. In the final Html, the main tags<br />

will be removed and the access points will be replaced with the result values.<br />

2.3.3 Evaluation tags<br />

<strong>FotoWeb</strong> provides two evaluation tags:<br />

• If – else – endif<br />

• Ifnot – else – endif<br />

These evaluation tags allow evaluation of existing conditions. For example:<br />

Example 7: 'If' tag creating context with 'endif'.<br />

’/’ marks end of tag.<br />

Start tag.<br />

In this example, the condition ‘current<strong>User</strong>.isLockedOut’ is being evaluated. If the condition is true, the code in the<br />

tag’s context (until ‘endif’) will be executed. This tag can be extended to evaluate both outcomes of the conditions.<br />

For example:<br />

Example 8. 'If' tag creating double context with 'else' and 'endif'.<br />

’ShoppingCartList<br />

’ tag’s context.<br />

End tag with ’/’<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

The ‘else’ clause allows creation of a second context that can be executed if the condition is not true. Similarly, the<br />

entire evaluation can be reversed with the ‘ifnot’ tag. For example:<br />

<strong>FotoWare</strong> 7 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

<br />

<br />

<br />

Example 9: 'Ifnot' tag creating context with 'endif'.<br />

In this example, the tag context is executed if current user is not locked out. To evaluate both sides of the<br />

condition, you can add the ‘else’ clause as follows:<br />

<br />

<br />

<br />

<br />

<br />

Example 10: 'Ifnot' tag creating double context with 'else' and 'endif'.<br />

Conditions are discussed later in this document.<br />

2.3.4 Attributes<br />

Some tags allow regulation of information processing by passing parameters to <strong>FotoWeb</strong>. These parameters are<br />

called ‘attributes’ of the tags. These attributes instruct <strong>FotoWeb</strong> in detail on how to process and/or deliver the<br />

information. For example:<br />

<br />

. . .<br />

<br />

Example 11: Optional attributes of 'ImageList' tag.<br />

In this example ‘rows’, ‘columns’, and ‘archiveId’ are attributes of ‘ImageList’ tag that instruct <strong>FotoWeb</strong> to<br />

produce an image list of archive 5005 with 3 rows and 8 columns. If the rows and columns attributes were not<br />

specified, then <strong>FotoWeb</strong> would use default values of 2 and 6 respectively. These are called optional attributes. Not<br />

all attributes are optional. For example:<br />

<br />

Example 12: Mandatory attributes of 'MathEval' tag.<br />

In this example, the attribute ‘expression’ is not optional and must be specified for the ‘MathEval’ tag to produce<br />

any sensible information.<br />

2.3.5 Variables<br />

Variables are the information access points for the tags and externally set variables. The variables provide textual<br />

information that can be added to the final Html transmission to the client.<br />

2.3.5.1 Types of variables<br />

The variables can be divided into four categories:<br />

1. Request variables.<br />

• These are variables that are passed with the http request. These variables can be accessed<br />

anywhere in the page, given they exist.<br />

2. Global variables.<br />

• Variables that belong to ‘Global’, ‘Current<strong>User</strong>’ and ‘BrowserDetection’ tags are called global<br />

variables. These variables can be accessed anywhere in the page without calling the tag or<br />

creating a tag context.<br />

3. Tag variables.<br />

• Variables set by a tag. These variables must be used within the tag’s context.<br />

4. External variables.<br />

• Variables that are set manually by the programmer. These variables can be used anywhere in the<br />

page after they are set. They behave similar to global variables.<br />

2.3.5.2 Accessing variables<br />

8 / 47 <strong>FotoWare</strong>


Customizing <strong>FotoWeb</strong> 3.0<br />

Since the variables return textual values, it is important to know, or at least have an idea of, what type of data you<br />

expect from the variables and where it will be used in the Html structure. <strong>FotoWeb</strong> provides several different<br />

options to display and use variable data. These options include:<br />

• Html encoding<br />

o Encodes the text in Html format for safe display in browsers.<br />

• URL encoding<br />

o Encodes the text in URL format to construct URLs and query strings.<br />

• JavaScript encoding<br />

o Encodes the text in JavaScript format to be passed to JavaScript functions.<br />

• Plain text encoding<br />

o Displays the text as is without any encoding.<br />

• Text length capping<br />

o Allows capping of the text if it exceeds a specified size.<br />

• Text abbreviation<br />

o Adds an abbreviation string at the end of the text if it is capped.<br />

All these formats can be derived from the ‘InsertVariable’ tag by specifying different attributes. For example:<br />

<br />

Example 13: Displaying variable with formatting.<br />

In this example client’s platform name is being displayed with Html encoding. A maximum of 10 characters will be<br />

displayed. If the actual platform name consists of more than 10 characters, then it will be capped down to 10 and<br />

the abbreviator string ‘…’ will be appended to it.<br />

If no encoding, capping or abbreviation is desired, as may be the case for numerical values, then you can simply<br />

retrieve the variable value by directly using the variable name as follows:<br />

<br />

Example 14: Displaying variables without formatting.<br />

<strong>FotoWare</strong> 9 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

2.3.5.3 Existence of variables<br />

It is important to know that a variable must exist before you can access its value. If an attempt is made to access a<br />

variable that does not exist, then the entire processing is stopped and an error is generated.<br />

It is not always clear in the context when a certain variable may exist or not. To cope with such situations, <strong>FotoWeb</strong><br />

provides following set of tags to check for existence of variables on different levels:<br />

• IfVariableExists<br />

• IfNotVariableExists<br />

• IfHttpRequestValueExists<br />

• IfNotHttpRequestValueExists<br />

All these tags use a ‘name’ attribute to specify the name of the variable to be checked. In addition, these are nonempty<br />

tags that perform an evaluation and allow execution of their context accordingly. For example:<br />

<br />

Client platform:<br />

<br />

<br />

Example 15: Checking if a variable exists.<br />

In this example, we check if a variable named ‘browser.paltformName’ exists. If it does, then the context of the<br />

‘IfVariableExists’ is executed and the client’s platform name is displayed, otherwise the entire context is skipped.<br />

Similarly, a code section can be created for execution in absence of a variable. For example:<br />

<br />

Client platform is not available.<br />

<br />

Example 16: Checking if a variable does not exist.<br />

In this example the context of ‘IfNotVariableExists’ is executed only if ‘browser.platformName’ does not exist.<br />

2.3.5.4 Creating own variables<br />

<strong>FotoWeb</strong> also allows creating your own variables for easy data access throughout the Fwx pages. The tags used to<br />

achieve this are:<br />

• SetVariable<br />

• SetSessionVariable<br />

For example:<br />

<br />

Example 17: Creating custom variables in the page scope.<br />

In this example a variable named ‘productName’ is declared with a specified value. This variable can now be<br />

accessed anywhere in the Fwx page in any context. However, once another page is processed, this variable is no<br />

longer valid.<br />

To declare variables that are valid and accessible through all pages, you can use the ‘SetSessionVariable’ tag. This<br />

tag sets a session variable that only needs to be declared once and is available during the entire user session. A<br />

session variable is recognized with a special prefix ‘UDSV_’, which stands for <strong>User</strong> Defined Session Variable. For<br />

example:<br />

<br />

Example 18: Creating custom variables in the session scope.<br />

In this example a session variable ‘UDSV_productName’ is declared that will be available throughout the user<br />

session in any context.<br />

The externally set variables can be removed from the memory when they are no longer needed with the<br />

‘RemoveVariable’ and ‘RemoveSessionVariable’ tags. For example:<br />

10 / 47 <strong>FotoWare</strong>


Example 19: Removing custom variables.<br />

In this example the externally set variable ‘productName’ is removed from the memory.<br />

2.3.6 Conditions<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

Conditions are the true/false evaluations points for the tags and externally set conditions. The conditions allow<br />

creating contexts of codes that can be chosen for execution in different situations.<br />

2.3.6.1 Types of conditions<br />

The conditions can be divided into three categories:<br />

1. Global conditions<br />

• Conditions that belong to ‘Global’, ‘Current<strong>User</strong>’ and ‘BrowserDetection’ tags are called global<br />

conditions. These conditions can be accessed anywhere in the page without calling the tags or creating<br />

a tag context.<br />

2. Tag conditions<br />

• Conditions set by a tag. These conditions must be used within the tag’s context.<br />

3. External conditions<br />

• Conditions that are set manually by the programmer. These conditions can be used anywhere in the<br />

page after they are set. They behave similar to global conditions.<br />

<strong>FotoWare</strong> 11 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

2.3.6.2 Evaluating conditions<br />

Since the conditions are simple true/false evaluations, their usage is very straightforward. The evaluations are<br />

performed using ‘if’ or ‘ifnot’ tags. For example:<br />

<br />

<br />

<br />

<br />

<br />

Example 20: Evaluating conditions.<br />

In this example the account status of the logged on user is being evaluated. If the account is locked out, then the<br />

first section of the if-clause is executed, otherwise the second section is executed.<br />

The ‘’ clause allows evaluation of the negation at the same time. However, if only negation needs to be<br />

evaluated, then an ‘ifnot’ can be performed on the condition. For example:<br />

<br />

<br />

<br />

Example 21: Inverted condition evaluation.<br />

In this example a context is created for execution only if the condition being tested is false.<br />

The ‘if’ and ‘ifnot’ tags can be nested and they can contain any other tags in their contexts. For example:<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Example 22: Nested condition evaluation.<br />

12 / 47 <strong>FotoWare</strong>


2.3.6.3 Existence of conditions<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

It is important to know that a condition must exist before you can evaluate it. If an attempt is made to evaluate a<br />

condition that does not exist, then the entire processing is stopped and an error is generated.<br />

It is not always clear in the context when a certain condition may exist or not. To cope with such situations,<br />

<strong>FotoWeb</strong> provides following tags to check for existence of conditions:<br />

• IfConditionExists<br />

• IfNotConditionExists<br />

These tags use a ‘name’ attribute to specify the name of the condition to be checked. In addition, these are nonempty<br />

tags with the exception that they do not store any results in the memory. It is rather the context of the tag is<br />

responsible of delivering the results. For example:<br />

<br />

<br />

You are using an Opera browser.<br />

<br />

<br />

Example 23: Checking if a conditions exists.<br />

In this example, we check if a condition named ‘browser.isOpera’ exists. If it does, then the context of the<br />

‘IfConditionExists’ is executed and the condition is evaluated, otherwise the entire context is skipped.<br />

Similarly, a code section can be created for execution in absence of a condition. For example:<br />

<br />

<br />

<br />

Example 24: Checking if a condition does not exist.<br />

In this example the context of ‘IfNotConditionExists’ is executed only if ‘browser.isOpera’ does not exist.<br />

2.3.6.4 Creating own conditions<br />

<strong>FotoWeb</strong> also allows creating your own conditions for easy flag setting throughout the Fwx pages. The tags used to<br />

achieve this are:<br />

• SetCondition<br />

• SetSessionCondition<br />

For example:<br />

<br />

Example 25. Creating custom conditions in the page scope.<br />

In this example a condition named ‘openShoppingCartInNewWindow’ is created with a value set to true. This<br />

condition can now be accessed anywhere in the Fwx page in any context. However, once another page is processed,<br />

this condition is no longer valid.<br />

To declare conditions that are valid and accessible in all pages, you can use the ‘SetSessionCondition’ tag. This tag<br />

sets a session condition that only needs to be declared once and is available during the entire user session. A session<br />

condition is recognized with a special prefix ‘UDSC_’, which stands for <strong>User</strong> Defined Session Condition. For<br />

example:<br />

<br />

Example 26: Creating custom conditions in the session scope.<br />

In this example a session condition ‘UDSC_fromLoginPage’ is declared that will be available throughout the user<br />

session in any context.<br />

The externally set conditions can be removed from the memory when they are no longer needed with the<br />

‘RemoveCondition’ and ‘RemoveSessionCondition’ tags.<br />

<strong>FotoWare</strong> 13 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

2.4 Command requests<br />

Commands requests seem like hidden Fwx pages that are nowhere to be found on disk. They are in fact just<br />

<strong>FotoWeb</strong> tags designed to behave differently.<br />

The regular tags are always executed from their context in an Fwx page. The command requests on the other hand<br />

are only executed upon user interaction and can be called from any type of page (Fwx, Asp, Php, Html etc) or a<br />

third-party application. For example the ‘ImageList’ tag displays images from the archive, while it is up to the user<br />

to decide whether to add an image to an album or not. When the user clicks on the ‘add to album’ icon, the<br />

command request ‘AddToAlbum.fwx’ is executed and the selected image is added to the user’s album.<br />

Since the command requests are set up as ‘hidden’ Fwx pages, they must be accessed as if they were regular Fwx<br />

pages with the exception of their virtual path that must follow the string ‘cmdrequest’.<br />

http:///fotoweb/cmdrequest/AddToAlbum.fwx?f=&SuccessURL=/fotoweb/ViewA<br />

lbum.fwx&ErrorURL=/fotoweb/ViewAlbum.fwx<br />

Example 27: Calling command requests.<br />

When accessed, the user is actually redirected to these pages to execute the command. Once the command is<br />

executed, the user is redirected back to the previous page where the request was made from. The user usually does<br />

not notice the redirection and only experiences a simple page refresh.<br />

In most of the commands, these redirections are controlled by parameters such as ‘SuccessURL’ and ‘ErrorURL’.<br />

‘SuccessURL’ defines the URL to be redirected to when the command is executed successfully while the user is<br />

redirected to the ‘ErrorURL’ if any error would occur during processing of the command.<br />

Most of the command requests also require information that is processed by other commands, e.g. a file access<br />

token (foxtoken) of a file to work with. For example:<br />

<br />

<br />

<br />

<br />

<br />

<br />

Example 28: Incorporating tags with command requests.<br />

In this example the command request ‘AddToAlbum.fwx’ is used in the context of ‘Image’ command that is again<br />

used in the context of ‘ImageList’ command. The ‘AddToAlbum.fwx’ command request is being referenced as if it<br />

was a regular Fwx page with query string parameters ‘fileId’, ‘SuccessURL’ and ‘ErrorURL’. These parameters are<br />

‘attributes’ of the command requests that provide necessary information to the command request to work with.<br />

The ‘fileId’ is the foxtoken of the image that is being added to the album. The ‘SuccessURL’ defines the URL to be<br />

redirected to when the command is executed successfully while the ‘ErrorURL’ defines the URL to be redirected to<br />

in case of any error. Notice the virtual path of the command request that starts with ‘cmdrequest’. This string<br />

identifies that the following Fwx page is a command request.<br />

14 / 47 <strong>FotoWare</strong>


2.5 Include files<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

As in other script languages, <strong>FotoWeb</strong> allows you to insert the content of one script file into another script file<br />

before the server executes it. It is done with a special ‘include’ tag that is enclosed by special identifiers ‘’. For example:<br />

<br />

Example 29: Including files with virtual path definition.<br />

In this example, a file ‘SystemSetup.inc’ is being included where the path of the file is virtual. To include files files<br />

absolute path use following ‘absolute’ keyword. For example:<br />

<br />

Example 30: Including files with absolute path definition.<br />

This tag can be used to create functions, headers, footers, or elements that will be reused on multiple pages.<br />

<strong>FotoWare</strong> 15 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

2.6 Script rules<br />

Now that you have been introduces to basic elements of <strong>FotoWeb</strong> scripting, its time to get to know the rules. The<br />

rules are few and simple and, more or less, already explained during the introduction of the elements.<br />

Failure to follow these rules can cause incorrect information display, compromise security and processing stops.<br />

<strong>FotoWeb</strong> has implemented several mechanisms to prevent these occurrences, but the best mechanism lies in the<br />

hands of the template programmer – adoption of <strong>FotoWeb</strong> script rules.<br />

2.6.1 Close/End the tags<br />

Whether it is an empty or non-empty tag, it must be closed with a forward slash ‘/’. For example:<br />

<br />

Example 31: Closing empty tags.<br />

Empty tags are closed by themselves by adding the closing mark ‘/’ right before the closing identifier ‘%>’, with no<br />

space in between them.<br />

<br />

. . .<br />

<br />

Example 32: Closing non-empty tags.<br />

The non-empty tags that create a context, must be closed with a separate closing tag. The closing tag is the same as<br />

starting tag, but with a closing mark ‘/’ right before the tag name, with no space in between them.<br />

Failure to close a tag will invalidate the hierarchal structure of the template and case a parsing error during template<br />

validation.<br />

2.6.2 Close/End contexts<br />

This rule is based on the same principal as the previous, but extends a little further. As explained in the previous<br />

rule, tags creating a context (non-empty tags) must be closed with a closing tag. Similarly, the evaluation tags (‘if’<br />

and ‘ifnot’) must also close their contexts with ‘endif’.<br />

<br />

. . .<br />

<br />

. . .<br />

<br />

<br />

. . .<br />

<br />

. . .<br />

<br />

Example 33: Closing 'if' and 'ifnot' tags.<br />

Starting tag.<br />

Closing tag with closing mark ’/’.<br />

’/’ closes the tag.<br />

Starting evaluation tag.<br />

Closing evaluation tag.<br />

Starting evaluation tag.<br />

Closing evaluation tag.<br />

Optional else.<br />

Optional else.<br />

Failure to close a tags’ context will invalidate the hierarchal structure of the template and cause a parsing error<br />

during the template validation..<br />

16 / 47 <strong>FotoWare</strong>


2.6.3 Avoid illegal peers<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

Some tags such as ‘ImageList’, ‘ShoppingCartList’ etc cannot be repeated in the same template. They are called<br />

illegal peers. Any attempt to repeat these tags in the same template will invalidate all the illegal peers after the first<br />

occurrence. See ‘<strong>FotoWeb</strong> <strong>6.0</strong> Tag Reference’ document for details on illegal peers of tags.<br />

2.6.4 Avoid illegal nesting<br />

<strong>FotoWeb</strong> allows usage of tags in the context of other tags. It is, however, not possible to repeat certain tags in their<br />

own context. As a general rule of thumb: the empty tags cannot be nested, because they cannot create a context.<br />

For non-empty tags, check documentation of the tag for individual reference.<br />

2.6.5 Use correct elements and names<br />

‘Of course!’ you say. So do we, but we wouldn’t have to make it an emphasized rule if it was only for the typos.<br />

Misspelling of a name or two can occur and be discovered and corrected with a little debugging. The real challenge<br />

is to adhere to the new standardized elements and names. A old template can be prone to following errors:<br />

• It contains elements that are being used with their old names.<br />

• It contains elements that are no longer in use.<br />

• It contains elements that are accepted by <strong>FotoWeb</strong>, but their functionality is not implemented.<br />

It can be almost an impossible task to manually update the templates if you are upgrading from older <strong>FotoWeb</strong><br />

versions. It can also be difficult to debug and verify large templates you have written yourself. <strong>FotoWeb</strong> provides a<br />

tool to automatically perform the upgrade and verification for you following the latest rules set. The tool is called<br />

‘Template Validator’ and is discussed in next section.<br />

Tip: Even if you have customized <strong>FotoWeb</strong> templates earlier, always refer to the ‘<strong>FotoWeb</strong> <strong>6.0</strong> Tag Reference’<br />

document to make sure that you use valid elements with correct syntax.<br />

<strong>FotoWare</strong> 17 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

2.7 Template validation<br />

Use the template validator on all templates every time they have been updated, modified or customized to verify<br />

their consistence and integrity. This tool analyses the templates and reports detailed error descriptions of errors<br />

found with their location and suggestions on how to correct them. It is very important to have all the templates<br />

validated before they are put into production. Incorrect templates can not only cause erroneous information to be<br />

displayed to the user, but also stop <strong>FotoWeb</strong> processing and further create undesirable and unexpected errors and<br />

situations.<br />

Tip! Use extensive template validation on development / test systems.<br />

Screenshot 1: Verify templates menu.<br />

This tool is located in each site’s context menu. Selecting the ‘Verify Templates’ menu will launch the validation<br />

wizard.<br />

2.7.1 Script analysis and conversion wizard<br />

Screenshot 2: Verify templates wizard - Start page.<br />

Click on ’Next’ button to start the wizard.<br />

18 / 47 <strong>FotoWare</strong>


2.7.1.1 Script (template) selection<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

You can either select a single template or a folder with templates. The script or folder selected may be outside the<br />

Site’s ‘documents’ folder. If that is so, then you need to specify the location of Site’s ‘documents’ folder in the<br />

script base field.<br />

Screenshot 3: Verify templates wizard - Template selection.<br />

2.7.1.2 Selecting rule set<br />

The templates are validated through a set of rules. <strong>FotoWeb</strong> is shipped with a built-in rule set that is always valid<br />

for templates up to the current version of <strong>FotoWeb</strong>. An external rules file can be used, only if one is recommended<br />

and supplied from <strong>FotoWare</strong>.<br />

Screenshot 4: Verify templates wizard - Rule set selection.<br />

<strong>FotoWare</strong> 19 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

2.7.1.3 Creating backup<br />

Since template validator can modify the templates on command, it is always a good idea to create a backup of the<br />

templates before starting to work on them. This option will automatically create backup of selected templates at the<br />

specified location before doing the actual analysis.<br />

Screenshot 5: Verify templates wizard - Create backup.<br />

2.7.1.4 Start the validation<br />

Finally, click in ’Finish’ to start the actual validation.<br />

Screenshot 6: Verify templates wizard - Start validation.<br />

A progress bar will appear displaying the status of validation.<br />

20 / 47 <strong>FotoWare</strong>


2.7.2 Validating the templates<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

Once the validation wizard has finished, it will launch the template validation window that displays the validation<br />

results, options to correct the errors and to re-validate the templates.<br />

Screenshot 7: Template validation window.<br />

The analysis summary on the top of the window displays general statistics of the analysis.<br />

Files analyzed<br />

Displays number of files analyzed.<br />

Total errors<br />

Displays total number of errors found in the files.<br />

Fixable<br />

Displays number of errors that can be fixed with the most simple ‘Auto update’ option.<br />

Unfixable<br />

Displays number of errors that require manual edition. However, these errors can also be removed with<br />

the ‘Auto update option by adding additional update flags that remove (not fix) the errors from the files.<br />

Total rules used<br />

Displays the number of <strong>FotoWeb</strong> script rules used to validate the files.<br />

The ‘Analysis Details’ window displays all the files that are analyzed along with the error status of each file. The list<br />

also displays a color icon next to the file name to indicate the error status. The list can be sorted with respect to<br />

available columns for better information display. Once a single file is selected from the list, the ‘Quick Error View’<br />

list box on the bottom lists the error occurrences in the file if any. The operation buttons ‘Auto Update’, ‘Edit’ and<br />

‘Delete’ buttons are also enabled.<br />

The types of errors reported by the ‘Quick Error View’ are:<br />

Change case<br />

The name of the tag/variable etc needs to update the case according to <strong>FotoWeb</strong> standard. This is a fixable<br />

error that can automatically be fixed with Auto Update.<br />

Need update<br />

The name of the tag/variable etc has become obsolete and needs to be updated. This is a fixable error that<br />

can automatically be fixed with Auto Update.<br />

Incorrect folder reference<br />

The “bin” folder reference has become obsolete and needs to be updated. This is a fixable error that can<br />

automatically be fixed with Auto Update.<br />

<strong>FotoWare</strong> 21 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

Out of scope<br />

The tag/variable etc is used out of scope. This is an unfixable error and must be fixed manually. The Auto<br />

Update can be used to remove this tag/variable from the template.<br />

Invalid<br />

The tag/variable etc is invalid. This is an unfixable error and must be fixed manually. The Auto Update<br />

can be used to remove this tag/variable from the template.<br />

Not implemented<br />

The tag/variable etc is valid. But not implemented in this version of <strong>FotoWeb</strong>. This is an unfixable error<br />

and must be fixed manually. The Auto Update can be used to remove this tag/variable from the template.<br />

No longer in use<br />

The tag/variable etc has become obsolete and will not be supported by <strong>FotoWeb</strong> any more. This is an<br />

unfixable error and must be fixed manually. The Auto Update can be used to remove this tag/variable<br />

from the template.<br />

Illegal nesting<br />

The tag is nested under illegal context. This is an unfixable error and must be fixed manually. The Auto<br />

Update can be used to remove this tag/variable from the template.<br />

Illegal peer<br />

The tag appears with another illegal peer in the same template. This is an unfixable error and must be<br />

fixed manually. The Auto Update can be used to remove this tag/variable from the template.<br />

A template may not pass the parser at all if its <strong>FotoWeb</strong> tag structure is corrupt (e.g. unclosed contexts). In such<br />

case, <strong>FotoWeb</strong> will only attempt to report where in the template the tag structure is breaking. Once the tag<br />

structure is re-established, the template must be re-validated.<br />

2.7.2.1 Auto update<br />

This ‘Auto Update’ button launches the a dialog box where more selections can be made for the auto update<br />

process. The basic function of this operation is to update the obsolete <strong>FotoWeb</strong> elements with their updated values<br />

and correct the case of element names that are not written according to the standard. It also corrects the folder<br />

references from ‘bin’ to ‘fwbin’ for the <strong>FotoWeb</strong> ISAPI modules.<br />

In addition to this, ‘Auto Update’ provides four additional options that are directed toward ‘unfixable’ errors.<br />

These options will delete the sections of templates that contain unfixable errors along with their contexts. A single<br />

variable is simply removed from the file, leaving the surrounding structure intact. A condition is removed along with<br />

the entire if/else/endif structure it occurs in. A tag is removed along with the data, variables, conditions and/or other<br />

commands that appear under the context of the tag. It is, therefore, strongly recommended to use these additional<br />

options with extreme caution and certainly after carefully analyzing all the errors in the selected templates.<br />

To perform auto update on multiple files, simply select multiple files in the list box before starting the operation.<br />

Screenshot 8: Auto update templates dialog.<br />

22 / 47 <strong>FotoWare</strong>


2.7.2.2 Manually edit templates<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

The ‘Edit’ option launches a simple text editor with the selected template with a triple color-coding of the errors.<br />

The simple case errors are marked with green color. The errors that need an update are marked with blue and all<br />

other errors are marked with red color. The red color is a basic indication that the error should be fixed manually.<br />

The drop down box on the top of the editor can be used to quickly navigate to the errors. By use of the drop down<br />

box, a brief description of the error is also displayed on the top of the editor.<br />

If you have edited and saved a template in ‘Edit’ window, then it will automatically be re-validated when you close<br />

the editor. You can edit only one template at a time. Use the ‘Edit’ option to manually edit the templates or just to<br />

simply view the errors and the context they have occurred in.<br />

Screenshot 9: Manual edit template window.<br />

2.7.2.3 Delete templates<br />

You can delete the templates using the ‘Delete’ option. Multiple templates can be deleted simultaneously. This<br />

operation moves the selected files to Window’s recycle bin where they can be restored.<br />

2.7.2.4 Re-validate templates<br />

Use ‘Refresh’ option to re-validate the templates. This option can be handy if you are using a third-party editor<br />

while validating the templates.<br />

2.7.3 Special case with include files<br />

Some special cases can occur with respect to the include files where the logical structure of the including and<br />

included files is correct, but errors may be reported by the script validator. The following example illustrates such a<br />

case.<br />

The assumed ‘main.fwx’ has two references of include files in the script, ‘include1.inc’ and ‘include2.inc’. The<br />

‘include1.inc’ sets some variables and conditions that are referred in ‘include2.inc’. ‘Include2.inc’ does not have<br />

any direct reference for the variables used in the file that indicate their setting by ‘include1.inc’. Thus, when<br />

‘include2.inc’ is validated, ‘out of scope’ errors will occur every time the variables/conditions from ‘include1.inc’ are<br />

used.<br />

To resolve this problem, a special include instruction is introduced that is as follows:<br />

<br />

<br />

Figure 6: Include statement for template validation.<br />

In ‘include2.inc’, add one of the above strings on the first line with the reference to ‘include1.inc’. This way, the<br />

validator will know that the file is using variables/conditions that are set by ‘include1.inc’ and no errors will be<br />

generated. Since the string is contained in HTML comments, this will not affect the normal processing of the page.<br />

However, it is important to maintain the exact structure of the string with respect to spaces etc in order to make it<br />

work.<br />

<strong>FotoWare</strong> 23 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

3 Creating a <strong>FotoWeb</strong> template<br />

Creating a <strong>FotoWeb</strong> template is basically no harder than creating a regular Html page with some JavaScript or Asp<br />

code. In this section, we will create a basic <strong>FotoWeb</strong> template to display images from an archive. We will create the<br />

template in small steps by adding an element or two in each step to illustrate the ease of design and how different<br />

<strong>FotoWeb</strong> elements ‘hang’ together.<br />

3.1 The first step – a Html page<br />

As mentioned earlier, <strong>FotoWeb</strong> templates are basically Html pages with <strong>FotoWeb</strong> tags and Fwx extension. So we<br />

start by creating a basic Html page.<br />

<br />

<br />

My First <strong>FotoWeb</strong> Template<br />

<br />

<br />

Hello World: This is my first <strong>FotoWeb</strong> template.<br />

<br />

<br />

Example 34: Primary Fwx page.<br />

Save the page in the site’s document folder with an ‘fwx’ extension, e.g. ‘MyGrid.fwx’. Access the page using your<br />

browser.<br />

Screenshot 10: A FWX page containing only HTML code.<br />

24 / 47 <strong>FotoWare</strong>


3.2 Adding the first tag<br />

Now that we have a basic Html page set up, we can add our first <strong>FotoWeb</strong> tag to it. The tag we will add is<br />

‘ListArchives’ that generates list of archives on the site.<br />

Note! All new code entries in the examples will me marked blue for easy recognition.<br />

<br />

<br />

My First <strong>FotoWeb</strong> Template<br />

<br />

<br />

Archives on site<br />

<br />

- <br />

<br />

<br />

<br />

Example 35: Adding 'ListArchives' tag.<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

‘ListArchives’ is a non-empty tag that starts from the first archive on the site and repeats itself until all the archives<br />

are enumerated. Every time it is repeated, it holds the information about the archive being enumerated that can be<br />

accessed from the tag’s variables and conditions in its context. In the example above, we access the ‘archive.name’<br />

variable of the ‘ListArchives’ tag to get the name of the archive.<br />

Screenshot 11: Adding 'ListArchives' tag.<br />

<strong>FotoWare</strong> 25 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

Next, we will access some more variables of ‘ListArchives’ tag to create a better information display. At the same<br />

time, we will display the results in a table.<br />

<br />

<br />

My First <strong>FotoWeb</strong> Template<br />

<br />

<br />

Archives on site<br />

<br />

<br />

Id<br />

Name<br />

Description<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Example 36: Accessing variables of 'ListArchives' tag.<br />

This time, we are retrieving archive id, name and description all at the same time.<br />

Screenshot 12: Accessing variables of 'ListArchives' tag.<br />

26 / 47 <strong>FotoWare</strong>


Next, we will evaluate a condition of the ‘ListArchives’ tag.<br />

<br />

<br />

My First <strong>FotoWeb</strong> Template<br />

<br />

<br />

Archives on site<br />

<br />

<br />

Id<br />

Name<br />

Description<br />

Current user has access<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Yes<br />

<br />

No<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Example 37: Accessing conditions of 'ListArchives' tag.<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

We are evaluating the ‘archive.current<strong>User</strong>HasAccess’ condition that informs us whether the currently logged on<br />

user has access to the archive or not. This condition can be used to decide whether to show this archive to the users<br />

or not.<br />

Screenshot 13: Accessing conditions of 'ListArchives' tag.<br />

<strong>FotoWare</strong> 27 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

Finally, we will use the same information to create an archive list that can be displayed on top of the page. The<br />

archive names will be presented as links to the same page ‘MyGrid.fwx’ where the archive id is passed to the page<br />

through query string. The description of the archive will be presented as tool tip of the links. The condition<br />

‘archive.current<strong>User</strong>HasAccess’ will be used to exclude the archives from the list where the currently logged on<br />

used does not have access.<br />

<br />

<br />

My First <strong>FotoWeb</strong> Template<br />

<br />

<br />

Available archives:<br />

<br />

<br />

<br />

<br />

&nbsp;|&nbsp;<br />

<br />

<br />

<br />

<br />

Example 38: Creating archive list with links and tool tips.<br />

Notice the use of ‘InsertVariable’ tag that performs an Html encoding on the archive name and description before<br />

outputting the results.<br />

Screenshot 14: Creating archive list with links and tool tips.<br />

28 / 47 <strong>FotoWare</strong>


3.3 Adding ‘ImageList’ tag<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

Now we go over to the most important tag in <strong>FotoWeb</strong>’s tag arsenal, ‘ImageList’ tag. This tag creates image list of<br />

the specified archive. The usage of this tag as simple as the ‘ListArchives’, but this tag offers a much larger<br />

collection of variables and conditions and it must be combined with some other tags to get full advantage of it.<br />

We will explore this tag by expanding the previously started example.<br />

<br />

<br />

My First <strong>FotoWeb</strong> Template<br />

<br />

<br />

Available archives:<br />

<br />

<br />

<br />

<br />

&nbsp;|&nbsp;<br />

<br />

<br />

<br />

<br />

You are browsing archive <br />

.<br />

<br />

<br />

<br />

Example 39: Adding 'ImageList' tag.<br />

We define ‘ImageList’ tag with 2 rows and 4 columns through its attributes. We also use ‘endforeDefault’ attribute<br />

to enforce the values of ‘rows’ and ‘columns’ attributes as they are specified in the tag definition. This option will<br />

ignore these attributes if they are specified through query string or posted data. We did not define the ‘archiveId’<br />

attribute, therefore, the tag will automatically locate the first archive where the logged on user has access. In our<br />

example, it is ‘Sample Images’ archive. The ‘imageList.currentArchive.name’ variable gives us the name of<br />

the archive that is being processed by the ‘ImageList’ tag.<br />

Screenshot 15: Adding 'ImageList' tag.<br />

<strong>FotoWare</strong> 29 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

Now comes the interesting part. As you recall, we created the archive list with links to the same page where archive<br />

id is passed in as query string parameter. This means that clicking on an archive link on top of the page will<br />

navigate back to this page with an addition of ‘?archiveId=XXXX’ in the page URL. When that is done, the<br />

‘ImageList’ tag will recognize the query string parameter ‘archiveId’ and work with the archive specified by this<br />

parameter rather than using the first archive where the currently logged on user has access. So, if we click on ‘Raw<br />

Library’ in the archive list, the ‘ImageList’ tag will process this archive and display its name.<br />

Screenshot 16: Adding 'ImageList' tag and using with archive list.<br />

Notice the query string parameter in the URL and the archive name reported by the ‘ImageList’ tag.<br />

30 / 47 <strong>FotoWare</strong>


Customizing <strong>FotoWeb</strong> 3.0<br />

Next we will perform a change and an addition in our template. We will change it by expanding the context of<br />

‘ImageList’ tag to the whole template. Then we will use some conditions and variables of ‘ImageList’ tag to display<br />

a little more information about the archive.<br />

<br />

<br />

<br />

My First <strong>FotoWeb</strong> Template<br />

’ImageList’ start tag.<br />

<br />

<br />

Available archives:<br />

<br />

<br />

<br />

<br />

&nbsp;|&nbsp;<br />

<br />

<br />

<br />

You are browsing archive .<br />

This archive has images.<br />

This archive is not searchable.<br />

<br />

<br />

<br />

’ImageList’ end tag.<br />

Example 40: Expanding context of 'ImageList' tag.<br />

Screenshot 17: Expanding context of 'ImageList' tag.<br />

<strong>FotoWare</strong> 31 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

Since the ‘ImageList’ is the main tag in this page, we should be able to access its variables anywhere in the page.<br />

This flexibility is achieved by expanding the tag’s context to the entire template. Now we can even display the<br />

archive name in the Html title of the page. In addition, the ‘ListArchives’ tag can now (internally) get information<br />

from the ‘ImageList’ tag about which archive is currently being processed and set its ‘listArchives.isCurrent’<br />

condition. We can use this condition to mark the archive in the archive list.<br />

<br />

<br />

<br />

Viewing archive ‘’<br />

<br />

<br />

Available archives:<br />

<br />

<br />

<br />

<br />

<br />

&nbsp;|&nbsp;<br />

<br />

<br />

<br />

You are browsing archive .<br />

This archive has images.<br />

This archive is not searchable.<br />

<br />

<br />

<br />

Example 41: Using variables and conditions of 'ImageList' tag with other tags.<br />

Screenshot 18: Using variables and conditions of 'ImageList' tag with other tags.<br />

32 / 47 <strong>FotoWare</strong>


3.4 Displaying images<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

The images are displayed with ‘Image’ tag. This tag, however, can only exist in the context of ‘ImageList’,<br />

‘ShoppingCartList’ and some other tags. These are called ‘parent’ tags of the ‘Image’ tag. See ‘<strong>FotoWeb</strong> <strong>6.0</strong> Tag<br />

Reference’ document for complete lists of parents for ‘Image’ and other tags.<br />

When ‘ImageList’ is called with ‘rows’ and ‘columns’ attributes, it immediately prepares rows X columns images to<br />

be displayed. To actually display these prepares images, the ‘ImageRow’ and ‘Image’ tags are used. The<br />

‘ImageRow’ tag creates the rows for us, just like the ‘’ tag in Html, while the ‘Image’ tag works similar to the<br />

‘’ tag in Html.<br />

Note! For the remainder of this example, we will mostly only display the relevant code snippet of the template.<br />

Thus, it should be assumed that these snippets are to be inserted in the main template in correct context.<br />

<br />

. . .<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

. . .<br />

<br />

Example 42: Displaying images with 'ImageRow' and 'Image' tags.<br />

Screenshot 19: Displaying images with 'ImageRow' and 'Image' tags.<br />

<strong>FotoWare</strong> 33 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

Next, we will utilize the ‘preview.dll’ in “\bin” folder to display a preview of the image using the<br />

‘foxtoken’ created by the ‘Image’ tag.<br />

<br />

. . .<br />

<br />

<br />

<br />

<br />

<br />

<br />

Example 43: Using 'preview .dll' to show thumbnails.<br />

<br />

<br />

<br />

<br />

<br />

<br />

. . .<br />

<br />

Screenshot 20: Using 'preview .dll' to show thumbnails.<br />

34 / 47 <strong>FotoWare</strong>


Customizing <strong>FotoWeb</strong> 3.0<br />

Next, we want to add an add-to-album link to the images. To create this link, we need to evaluate the<br />

‘current<strong>User</strong>.canModifyAlbums’ condition. The link will be created using the default <strong>FotoWeb</strong> icon. An image is a<br />

added to the album using the ‘AddToAlbum’ command request.<br />

<br />

. . .<br />

<br />

<br />

<br />

<br />

<br />

<br />

Example 44: Adding conditional actions to images.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

. . .<br />

<br />

<strong>FotoWare</strong> 35 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

Screenshot 21: Adding conditional actions to images.<br />

3.5 Creating page navigation<br />

We have now set up a basic template that displays<br />

• List of available archives.<br />

• Basic information about the selected archive.<br />

• An image list with thumbnails, file names and option to add an image to the album.<br />

So far so good, but it would be nice to be able to see more than first 8 images of the archives. To do so, we need to<br />

utilize the ‘PageNavigation’ tag. This tag provides navigational data that can be used to create ‘go to page’ links and<br />

‘previous’ and ‘next’ links to navigate through the archives.<br />

. . .<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

&nbsp;|&nbsp;&nbsp;<br />

<br />

<br />

<br />

Example 45: Adding 'PageNavigation' tag.<br />

36 / 47 <strong>FotoWare</strong>


Customizing <strong>FotoWeb</strong> 3.0<br />

Note that we are passing two additional attributes of ‘ImageList’ tag to ‘MyGrid.fwx’. These attributes are ‘sorting’<br />

and ‘search’. Even that we are not using these attributes at this time, we start adding them here for future<br />

convenience. These attributes inform ‘ImageList’ tag about the search criteria to use when retrieving images from<br />

Index Manager and the sorting scheme to apply to the final image list.<br />

Screenshot 22: Adding 'PageNavigation' tag.<br />

<strong>FotoWare</strong> 37 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

The page navigation can be even more improved if incorporated with ‘ImageList’ conditions such as<br />

‘imageList.isFirstPage’ and ‘imageList.islastPage’.<br />

. . .<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

&nbsp;|&nbsp;&nbsp;<br />

<br />

<br />

<br />

<br />

First&nbsp;|&nbsp;Previous<br />

<br />

First<br />

&nbsp;|&nbsp;<br />

Previous<br />

<br />

&nbsp;|&nbsp;<br />

<br />

next&nbsp;|&nbsp;Last<br />

<br />

Next<br />

&nbsp;|&nbsp;<br />

Last<br />

<br />

<br />

<br />

<br />

Example 46: Improving page navigation.<br />

38 / 47 <strong>FotoWare</strong>


Screenshot 23: Improving page navigation.<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

<strong>FotoWare</strong> 39 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

4 Tips and tricks<br />

4.1 Evaluating multiple conditions<br />

Combining and evaluating multiple conditions using standard approach requires nesting of condition evaluations.<br />

Depending on the number of conditions to combine and the number of times the evaluations are to be repeated,<br />

the templates can end up being rather complex and messy that further can be hard to maintain and debug. It can,<br />

therefore, be a good idea to create some own conditions that represent a combination of standard conditions. For<br />

example, if you want to categorize a user’s access level to the archive and later use this information in a couple of<br />

places, then you can do as follows:<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Example 47: Evaluating multiple conditions.<br />

In this example we have created two conditions ‘accessLevel1’ and ‘accessLevel2’ and set their initial values to false.<br />

Then we perform the real evaluation and reset these conditions’ values accordingly. Once done, we do not need to<br />

repeat the deeply nested evaluation any more and can use the values of ‘accessLevel1’ and ‘accessLevel2’ for further<br />

evaluations.<br />

4.2 Special archive<br />

You can allow different archives to be displayed differently. A trivial approach to this would be to look for an<br />

archive identifier and split the grid using if-else evaluations to display archive contents differently. This approach<br />

requires designing a complex grid page that evaluates archive identifier in multiple places and repeats major parts of<br />

the code with different parameters. Maintenance of such pages is also difficult and full of risks.<br />

A better approach to achieve the same results more elegantly would be to design two or more different grid pages.<br />

This way each grid page will be rather small in size and contain clearer standard <strong>FotoWeb</strong> and Html code. Simple<br />

pages are also easy to maintain and debug. In case of unknown or hard-to-find errors it is then no harder to just<br />

rename a page to one that is working until further than being stuck with a large messy page that won’t display<br />

anything correct.<br />

The trick here is to create a dynamic system, as rest of <strong>FotoWeb</strong>, so that the archive lists generated on top of the<br />

grid pages ‘know’ which grid page to use for different archives. Hard coding these archive lists will require manual<br />

updating every time an archive on the system is added, deleted or updated. A dynamic solution can be achieved by<br />

using a newly introduced ‘CompareNumbers’ tag in <strong>FotoWeb</strong>. With this tag, we can continue generating the<br />

archive list dynamically while watching for the archive ids and create grid links for different archives. For example:<br />

<br />

40 / 47<br />

<br />


Example 48: Special archive with special grid page.<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

In this example, we compare the archive ids reported by the ‘ListArchives’ tag with the id of the archive that is<br />

‘5001’. If the id of the archive being enumerated is 5001, then we create a link with ‘SpecialGrid.fwx’ while all<br />

other archives are linked with ‘Grid.fwx’.<br />

4.3 Image marking<br />

In some environments it is important for the clients to know if an image has already been used earlier or, even<br />

better, when it was lat used. Since <strong>FotoWeb</strong> has re-implemented the IPTC history event writing, it has become an<br />

easy task to perform.<br />

The destinations can be set to write IPTC history events on source images when they are processed through<br />

workflow. These events can later be read back in the grid page to mark images. This way the client can get visual<br />

information on images that have been used and even how long ago were they last used.<br />

There are no limitations on how such a solution can be implemented. One way is to utilize JavaScript along with<br />

<strong>FotoWeb</strong> commands. For example:<br />

<strong>FotoWare</strong> 41 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

<br />

// Enumerate history events and pick the last <strong>FotoWeb</strong> Workflow event<br />

var lastFwEvent = "";<br />

<br />

var currEvent = "";<br />

// "FWW" represents a Workflow event<br />

if(currEvent.indexOf("E=FWW") > -1)<br />

{<br />

lastFwEvent = currEvent;<br />

}<br />

<br />

// Check if an event was retrieved<br />

if (lastFwEvent != "" )<br />

{<br />

// Extract date from the event<br />

var dateIndex = lastFwEvent.indexOf("D=");<br />

// Cannot be -1 ! But we check any way<br />

if (dateIndex != -1)<br />

{<br />

// Create date object for event date. Parameters are Year, Month, day where<br />

month is 0-indexed.<br />

var eventDate = new Date(eval(lastFwEvent.substr(dateIndex + 2, 4)),<br />

eval(lastFwEvent.substr(dateIndex + 7, 2)) - 1, eval(lastFwEvent.substr(dateIndex + 10,<br />

2)));<br />

// Get difference with today's date. The difference is in milliseconds.<br />

var difference = Math.abs(new Date() - eventDate);<br />

// Convert to number of days<br />

var days = Math.round(difference / (1000 * 60 * 60 * 24));<br />

document.write('');<br />

if (days == 0)<br />

{<br />

document.write('Recently used');<br />

}<br />

else if (days == 1)<br />

{<br />

document.write('Last used ' + days + ' day ago');<br />

}<br />

else<br />

{<br />

document.write('Last used ' + days + ' days ago');<br />

}<br />

}<br />

}<br />

<br />

Example 49: Marking used images.<br />

Using this example, we can display a string along with the images on when they were last used in a workflow<br />

process. Other events that are written by <strong>FotoWeb</strong> are download events (FWD) and soft crop events (SCRP).<br />

4.4 Creating loops<br />

Repeating a section of code for a certain number of times is also possible in <strong>FotoWeb</strong>. This is done by using the<br />

‘Repeat’ tag as follows:<br />

<br />

Current loop value: <br />

<br />

In this example we are creating a loop with a start value of 1. The loop will count up to a value of 10 and display its<br />

current count during each iteration.<br />

42 / 47 <strong>FotoWare</strong>


4.5 Displaying navigation information<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

<strong>FotoWeb</strong> does not provide a direct tag or variable that can inform how many pages can be browsed in an archive.<br />

This number depends on the number of images in the archive, number of hits in a search and number of rows and<br />

columns. However, <strong>FotoWeb</strong> provides all the information that is required to calculate this page count.<br />

We know the number of rows and columns in the grid and we know number of images that can be browsed in the<br />

archive. That’s all we need to find out how many ‘pages’ there are in the archive. For example:<br />

<br />

Example 50: Calculating total 'complete' pages in archive.<br />

In this example the ‘MathEval’ tag is used to calculate number of ‘complete’ pages. With ‘complete’ pages we mean<br />

pages where the number of images are equal to rows X columns. There can be an unreported last page where the<br />

number of images is less than rows X columns. The reason of this exclusion is simple – integer conversion.<br />

We are evaluating the expression with no precision (‘precision’ attribute is not specified). Therefore, the result is<br />

converted to an integer before it is displayed. During the conversion to an integer, the real decimal value is rounded<br />

either up or down. Decimals less than 0.5 are rounded down while decimals greater than or equal to 0.5 are<br />

rounded up (e.g. 4.1 ≈ 4 and 4.5 ≈ 5). Therefore, depending on the number of images in the last page, that page<br />

may or may not be counted by the above expression.<br />

To calculate ‘absolute’ total pages, we need to add an offset to total images to compensate for the integer<br />

conversion. This is done fairly simple as follows:<br />

<br />

Example 51: Calculating total 'absolute' pages in archive.<br />

We add ‘rows + columns – 1’ images to the total images before dividing by rows X columns. This addition will<br />

create an offset that after integer conversion will return the ‘absolute’ page count.<br />

<strong>FotoWare</strong> 43 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

5 Auto search scripts<br />

It is a common practice to have one large image database and create different archives from it based on different<br />

auto search filters. <strong>FotoWeb</strong> also allows defining auto searches all the way down to groups’ and users’ level. This<br />

way each group or user can be served different set of images in the same archive. Using this option requires that you<br />

enter an auto search for selected groups/users in archive properties | Access List | Autosearch filter in the <strong>FotoWeb</strong><br />

Administration Console.<br />

<strong>FotoWeb</strong> comes with a feature that opens for new frontiers within auto search settings. You can write FWX scripts<br />

in the auto search field. It is written in the same way as FWX templates, but without any Html code. Due to its<br />

unique nature, the use of scripts in this context is bound by certain rules.<br />

5.1.1 Rules<br />

Only the following of the <strong>FotoWeb</strong> tags can be used in the auto search scripts. Any reference to other tags will<br />

cause a processing error.<br />

• BrowserDetection<br />

• IfHttpRequestValueExists<br />

• IfNotHttpRequestValueExists<br />

• IfVariableExits<br />

• IfNotVariableExists<br />

• Current<strong>User</strong><br />

• AccessInfo<br />

• InsertVariable<br />

• StringSearch<br />

• StringLength<br />

• CompareNumbers<br />

• CompareStrings<br />

• SetVariable<br />

• RemoveVariable<br />

• SetCondition<br />

• RemoveCondition<br />

• MathEval<br />

• Repeat<br />

• Skip<br />

5.1.2 Variables and conditions<br />

Variables<br />

Name Description<br />

autoSearch.today.date Today’s date in “YYYYMMDD” format.<br />

autoSearch.today.dateTime Today’s date in “YYYYMMDD HHMMSS” format.<br />

Table 1: 'AutoSearch' variables.<br />

Conditions<br />

Name Description<br />

autoSearch.access.none True if use has no access to the archive.<br />

autoSearch.access.view True if user has view access to the archive.<br />

autoSearch.access.preview True if user has preview access to the archive.<br />

autoSearch.access.workflow True if user has workflow access to the archive.<br />

autoSearch.access.download True if user has download access to the archive.<br />

autoSearch.access.order True if user has order access to the archive.<br />

autoSearch.access.editText True if user has edit text access to the archive.<br />

autoSearch.access.crop True if user has crop access to the archive.<br />

autoSearch.access.comping True if user has comping access to the archive.<br />

autoSearch.access.delete True if user has delete access to the archive.<br />

autoSearch.access.thirdParty1 True if user has 1st third party access to the archive.<br />

autoSearch.access.thirdParty2 True if user has 2nd third party access to the archive.<br />

autoSearch.access.thirdParty3 True if user has 3rd third party access to the archive.<br />

autoSearch.access.thirdParty4 True if user has 4th third party access to the archive.<br />

Table 2: 'AutoSearch' conditions.<br />

44 / 47 <strong>FotoWare</strong>


5.1.3 Examples<br />

We start by looking at a simple example.<br />

<br />

Europe<br />

<br />

Middle East<br />

<br />

Example 52: Simple 'AutoSearch' example.<br />

Customizing <strong>FotoWeb</strong> 3.0<br />

In this examples the guest users will be served images related to ‘Europe’ while all other users will see images<br />

related to ‘Middle East’.<br />

Now we construct a more complicated filter where the main search criterion is ‘sports’ and permission regulation is<br />

based on ‘ThirdParty’ permissions. Our filter will serve old images to guests and registered users that do not have<br />

‘ThirdParty’ permissions. <strong>User</strong>s with ‘ThirdParty’ permissions are again divided with respect to the combinations if<br />

‘ThirdParty1’ and ‘ThirdParty2’ permissions. So the final division will be as follows:<br />

• If a user has ‘ThirdParty1’ permissions, then images more than 2 days old are served.<br />

• If a user has ‘ThirdParty2’ permissions, then images not more than 2 days old are served.<br />

• If a user has both ‘ThirdParty1’ and ‘ThirdParty2’ permissions, then there is no limitation on date.<br />

• All other users will be served images that are more than a week old.<br />

For example:<br />

(sports)<br />

<br />

<br />

<br />

<br />

AND (FQYFD contains (0~~))<br />

<br />

<br />

<br />

<br />

AND (FQYFD contains (~~99999999))<br />

<br />

<br />

<br />

<br />

<br />

AND (FQYFD contains (0~~))<br />

<br />

<br />

Example 53: Advanced 'AutoSearch' example.<br />

In this example, we start by defining the main search criterion ‘sports’. Then a condition is set to apply the ‘week’<br />

limit. If the user is not a guest and has ‘ThirdParty1’ and/or ‘ThirdParty2’ permissions, then the ‘week’ condition is<br />

set to false and the proper filter is added. At the end, we check if we are to apply the ‘week’ limit and do it<br />

accordingly.<br />

<strong>FotoWare</strong> 45 / 47


Customizing <strong>FotoWeb</strong> 3.0<br />

6 Indexes<br />

6.1 Figures<br />

Figure 1: A mathematical expression displayed by an Html page.......................................................................... 4<br />

Figure 2: A mathematical expression evaluated and displayed by an Asp page....................................................... 4<br />

Figure 3: A mathematical expression evaluated and displayed by an Fwx page......................................................4<br />

Figure 4: Multiple actions performed in a context created by Asp identifiers......................................................... 5<br />

Figure 5: Multiple actions performed in multiple contexts created by <strong>FotoWeb</strong> identifiers. ................................... 5<br />

Figure 6: Include statement for template validation. .......................................................................................... 23<br />

6.2 Tables<br />

Table 1: 'AutoSearch' variables......................................................................................................................... 44<br />

Table 2: 'AutoSearch' conditions. ..................................................................................................................... 44<br />

6.3 Screenshots<br />

Screenshot 1: Verify templates menu. ............................................................................................................... 18<br />

Screenshot 2: Verify templates wizard - Start page............................................................................................. 18<br />

Screenshot 3: Verify templates wizard - Template selection. .............................................................................. 19<br />

Screenshot 4: Verify templates wizard - Rule set selection.................................................................................. 19<br />

Screenshot 5: Verify templates wizard - Create backup. ..................................................................................... 20<br />

Screenshot 6: Verify templates wizard - Start validation. .................................................................................... 20<br />

Screenshot 7: Template validation window. ...................................................................................................... 21<br />

Screenshot 8: Auto update templates dialog. ..................................................................................................... 22<br />

Screenshot 9: Manual edit template window. .................................................................................................... 23<br />

Screenshot 10: A FWX page containing only HTML code. ............................................................................... 24<br />

Screenshot 11: Adding 'ListArchives' tag........................................................................................................... 25<br />

Screenshot 12: Accessing variables of 'ListArchives' tag. .................................................................................... 26<br />

Screenshot 13: Accessing conditions of 'ListArchives' tag................................................................................... 27<br />

Screenshot 14: Creating archive list with links and tool tips. .............................................................................. 28<br />

Screenshot 15: Adding 'ImageList' tag. ............................................................................................................. 29<br />

Screenshot 16: Adding 'ImageList' tag and using with archive list....................................................................... 30<br />

Screenshot 17: Expanding context of 'ImageList' tag. ........................................................................................ 31<br />

Screenshot 18: Using variables and conditions of 'ImageList' tag with other tags. ................................................ 32<br />

Screenshot 19: Displaying images with 'ImageRow' and 'Image' tags................................................................... 33<br />

Screenshot 20: Using 'preview .dll' to show thumbnails...................................................................................... 34<br />

Screenshot 21: Adding conditional actions to images......................................................................................... 36<br />

Screenshot 22: Adding 'PageNavigation' tag...................................................................................................... 37<br />

Screenshot 23: Improving page navigation. ....................................................................................................... 39<br />

6.4 Examples<br />

Example 1: ‘SetVariable’ tag creates a variable in memory. .................................................................................. 6<br />

Example 2: ’InsertVariable’ displays its results immediately. ................................................................................ 6<br />

Example 3: ‘ImageList’ tag processes a collection of results.................................................................................. 6<br />

Example 4: ‘CompareNumbers’ tag creates an evaluation context........................................................................ 6<br />

Example 5: 'MathEval' is an empty tag................................................................................................................ 7<br />

Example 6: 'ShoppingCartList' is a non-empty tag............................................................................................... 7<br />

Example 7: 'If' tag creating context with 'endif'. ................................................................................................... 7<br />

Example 8. 'If' tag creating double context with 'else' and 'endif'........................................................................... 7<br />

Example 9: 'Ifnot' tag creating context with 'endif'. .............................................................................................. 8<br />

Example 10: 'Ifnot' tag creating double context with 'else' and 'endif'. ................................................................... 8<br />

Example 11: Optional attributes of 'ImageList' tag............................................................................................... 8<br />

Example 12: Mandatory attributes of 'MathEval' tag. .......................................................................................... 8<br />

Example 13: Displaying variable with formatting................................................................................................. 9<br />

Example 14: Displaying variables without formatting. ......................................................................................... 9<br />

Example 15: Checking if a variable exists.......................................................................................................... 10<br />

Example 16: Checking if a variable does not exist.............................................................................................. 10<br />

Example 17: Creating custom variables in the page scope. ................................................................................. 10<br />

Example 18: Creating custom variables in the session scope............................................................................... 10<br />

Example 19: Removing custom variables. ......................................................................................................... 11<br />

46 / 47 <strong>FotoWare</strong>


Customizing <strong>FotoWeb</strong> 3.0<br />

Example 20: Evaluating conditions................................................................................................................... 12<br />

Example 21: Inverted condition evaluation. ...................................................................................................... 12<br />

Example 22: Nested condition evaluation. ........................................................................................................ 12<br />

Example 23: Checking if a conditions exists. ..................................................................................................... 13<br />

Example 24: Checking if a condition does not exist. .......................................................................................... 13<br />

Example 25. Creating custom conditions in the page scope. .............................................................................. 13<br />

Example 26: Creating custom conditions in the session scope............................................................................ 13<br />

Example 27: Calling command requests. .......................................................................................................... 14<br />

Example 28: Incorporating tags with command requests.................................................................................... 14<br />

Example 29: Including files with virtual path definition. .................................................................................... 15<br />

Example 30: Including files with absolute path definition. ................................................................................. 15<br />

Example 31: Closing empty tags....................................................................................................................... 16<br />

Example 32: Closing non-empty tags................................................................................................................ 16<br />

Example 33: Closing 'if' and 'ifnot' tags. ............................................................................................................ 16<br />

Example 34: Primary Fwx page. ....................................................................................................................... 24<br />

Example 35: Adding 'ListArchives' tag. ............................................................................................................. 25<br />

Example 36: Accessing variables of 'ListArchives' tag......................................................................................... 26<br />

Example 37: Accessing conditions of 'ListArchives' tag. ..................................................................................... 27<br />

Example 38: Creating archive list with links and tool tips................................................................................... 28<br />

Example 39: Adding 'ImageList' tag.................................................................................................................. 29<br />

Example 40: Expanding context of 'ImageList' tag............................................................................................. 31<br />

Example 41: Using variables and conditions of 'ImageList' tag with other tags. ................................................... 32<br />

Example 42: Displaying images with 'ImageRow' and 'Image' tags. ..................................................................... 33<br />

Example 43: Using 'preview .dll' to show thumbnails......................................................................................... 34<br />

Example 44: Adding conditional actions to images. ........................................................................................... 35<br />

Example 45: Adding 'PageNavigation' tag. ........................................................................................................ 36<br />

Example 46: Improving page navigation. .......................................................................................................... 38<br />

Example 47: Evaluating multiple conditions. .................................................................................................... 40<br />

Example 48: Special archive with special grid page. ........................................................................................... 41<br />

Example 49: Marking used images. .................................................................................................................. 42<br />

Example 50: Calculating total 'complete' pages in archive. ................................................................................. 43<br />

Example 51: Calculating total 'absolute' pages in archive. .................................................................................. 43<br />

Example 52: Simple 'AutoSearch' example........................................................................................................ 45<br />

Example 53: Advanced 'AutoSearch' example. .................................................................................................. 45<br />

<strong>FotoWare</strong> 47 / 47

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!