Upgrading templates to the Modern UI

Managed by | Updated .


This article discusses the steps that need to be carried out when upgrading Funnelback Classic UI templates (.form files) to the Modern UI.

Upgrade script

Funnelback ships with an script that converts Classic UI .form files into Modern UI .ftl  files.  This is run automatically if you upgrade Funnelback.

This script can also be run manually.

$SEARCH_HOME/bin/convert-form-file.pl  </path/to/file.form> </path/to/newfile.ftl> [-v or -vv]

After running the conversion the converted .ftl file will probably require further rectification work.

Fixing the converted .ftl file

General technique is to search for "<s:" in the .ftl file.  This will uncover things that have not been converted.


These can usually be converted directly to an <#if> tag

You will need to ensure that the <#if> tag doesn't have variables like <#if ${s.result.liveUrl} == "www.funnelback.com"> (this should be <#if s.result.liveUrl == "www.funnelback.com">

Classic UIModern UI
<s:Compare var == "val"><#if var == "val">
<s:Compare var != "val"><#if var != "val">
<s:Compare var =~ regexp"><#if var?matches("regexp")>
<s:Compare var !~ regexp"><#if ! var?matches("regexp")>


Classic UIModern UI
<s:IncludeFile>/path</s:IncludeFile><#Include "path">

Note: path is relative to $SEARCH_HOME/conf/$COLLECTION_NAME/$PROFILE


This will need to be replaced with Freemarker code that operates directly on the data model (probably).

The following Freemarker functions may well do what your EvalPerl codeblock does so it's worth checking them out:


Classic UIModern UIFunnelback version
<s:IncludeUrl args/><@fb.IncludeUrl args/>v12+
<s:IncludeUrl args/><@IncludeUrl args/>v11


<@IncludeUrl url="http://www.example.com/template.html" expiry=86400 start="<div id=\"global-header\">" end="</div> <!-- /#global-header -->" convertRelative=true />
<#--v12: IncludeUrl is now part of the fb namespace-->
<@fb.IncludeUrl url="http://www.example.com/template.html" expiry=86400 start="<div id=\"global-header\">" end="</div> <!-- /#global-header -->" convertRelative=true />

The IncludeUrl tag was undocumented in v11 but is since v12: http://docs.funnelback.com/help-ftl/funnelback.ftl.html#IncludeUrl


  • (?ms) is set on the backend so you don't need to include these flags in the start and end parameters
  • for the expiry value and convertRelative you need to omit any quotes or you get a FreeMarker error because it expects a number and not a string: ie. expiry=86400 and not expiry="86400"
  • start/end parameter Regex encoding: 
    • You need to encode any double quotes ie. start="<div class=\"somthing\">"
    • Valid escape sequences don't need to be escaped: \t, \n, \r ...
    • Backslashes need to be escaped: \\ will result in a single slash \
    • Brackets should be escaped, otherwise they'll be considered matching groups: start="\\(test\\)"
    • You don't need to encode a forward slash.
  • Keep in mind that the regex patterns use java regex so you sometimes need lots of additional backslashes. See: http://www.regular-expressions.info/java.html for further info.
  • In v11 you can't have more than one include from the same source URL, eg. a header and footer from the same source page - if you attempt to do this you will get the same code chunk repeated for each include call regardless of the start and end values.  To workaround this add a parameter to the URL so that each URL is unique.  Eg. if you are importing http://site/home.html call it with a parameter url="http://site/home.html?include=1", url="http://site/home.html?include=2" etc.

Result transforms

Result Transforms are not supported in the Modern UI but the functionality can be implemented using a post-process hook script.

Classic UI (collection.cfg)Modern UI (hook_post_process.groovy)

result_transform=$$result{'title'} =~ s/ - Example Site Suffix//g;

if ( transaction.response != null
&& transaction.response.resultPacket != null) {
transaction.response.resultPacket.results.each() {
// Transform each result's title
it.title= (it.title =~ / - Example Site Suffix/).replaceAll("")

CGI transforms

While CGI transforms work in the Modern UI the best practise is to remove any CGI transforms and re-implement these using a hook script. See: https://docs.funnelback.com/15.8/develop/programming-options/hook-scripts.html#transforming-cgi-parameters

Morph query parameters

Morph query parameters are not supported by modern UI in v11 but the functionality can be implemented using a hook script.  See: Morph query parameters functionality for the modern UI

<s:Plugin name='FeedbackLink'>

The FeedbackLink plugin isn't implemented in the modern UI.  However, it can be easily called from the Modern UI.  See: FeedbackLink plugin support for the Modern UI

Was this artcle helpful?

Type: Keywords:
Features: Frontend > Templating Frontend > Classic UI Frontend > Modern UI Frontend > Freemarker Frontend > Hook scripts