SiteStudio Online Documentation

For more information contact us

Adding Templates To SiteStudio Pages


By template we mean HTML and FreeMarker code processed by SiteStudio to generate SiteStudio layouts.
SiteStudio templates have no relation to vendor website templates.
In order to create a SiteStudio template based on a vendor template, you will need additional work to integrate it to SiteStudio.
At the moment, ready-made SiteStudio templates are not sold anywhere, but distributed with SiteStudio.

SiteStudio uses a combination of page tamplates and layout templates to produce a professionally looking web site. The fact that the layout and content are separated greatly helps to acheive flexible yet great-looking pages. The creation of layout templates, or templates that define the look of SiteStudio's pages is covered in Adding new designs to SiteStudio. Here, we will focus on creating content templates.

These are files that define what kind of information a user can place on a page, as well as how this information will be displayed.

First we must fully understand the structure of the websites' hierarchy tree. At the root of this tree is the "super-website" entity. This is the "parent" of all the other website entities, and traditionally has the name "simple". You will not need to change this unless you are rebuilding the whole website tree from scratch. The children of the super-website are regular websites, which can be selected by the user at the time they (re)start building their site. These usually define the type of site that a user wants to build (i.e. personal, corporate, etc.)

Each website contains a number of pages that can be added to that website. For example, a personal website can contain a genealogy tree page which would not be approriate for a business website. Each page entity can in turn be a root for it's own hierarch of sub-pages, or it may simply be a plain page with no further children. If sub-pages DO exist, they can have sub-pages of their own, ad infinitum.

Pages and subpages can be both visible and invisible. A visible page can be edited, viewed and published, and is represented in the finished site by a physical HTML file. An invisible page can be edited, and stores some data, but is not physically represented, and therefore cannot be viewed or published. Rather the information it contains is inserted into another page, usually its partent which IS visible. For example, a generic page contains an infinite number of invisible sub-pages each of which represent a paragraph. Each of these paragraphs can be edited separately, but their contents is displayed on the parent page in a list. Equally these pages have no individual HTML files once the site is published, but rather, are included in the HTML of the generic page.

While most top-level pages would have to be visible pages, often their sub-pages will be invisible, as in the example of the generic page.

Each page on the website must have a corresponding java object that stores its information. There are a few predefined classes that can be used for this purpose, and if a completely new functionality is needed, any of these can be extended. The following are Factory Supplied Page classes that you can use for your pages with no Java programming:

                          This is a "vanilla" page. It is visible and contains no children.
                          use it for such things as a simple "About" page.
                          This is an extension of psoft.masonry.Page that allows the
                          addition of child sub-pages.
                          This class should be used for invisible (or "transparent") pages.
                          Since it is an extention of psoft.masonry.HierarchicalPage, it can
                          include children sub-pages as well.

The type of java class that you want to associate with a given page depends on what that page's function, and can be specified in the page declaration file. This is a large XML file that contains the definitions of all pages that are used in the sites available under the super-website. (The super-website itself must be declared in the XML file as well. It should be the root node of this file)

The root path for all the template files will be referred to as "template_path/". This is the directory in which all the generic template files will be stored. In this same directory, the directory for the super-website will be kept. If the name of the super-website is "simple", then the path of it's files will be "template_path/simple/", and the XML desctription file will be stored as "template_path/simple/simple.xml". The tag for the super-website entity is "<website>" and should encompass all other tags in the file.

The entry for each individual site type is marked by a "<page>" tag, which can contain children page declarations and definitions.

The main focus of this tutorial is adding new pages to existing website types. If you wish to create a new website type entirely, you should use the existing code in the XML file and work from that.

To add a page to a particular website (for example personal) you will need to declare it and define it. The declaration is done using the <child> tag, and the definition is done using the <page> tag.

Let us start from the definition. The basic <page> tag contains two parameters:

                "name" is a name under which the page is to be identified. It should be unique in its
                      own scope. (The scope means that no other children of its parent shold have the same name.)
                "class" is a string containing the full java class name of the class to be used to
                     represent this page. (i.e. "psoft.masonry.Page". See above for factory-packaged classes)

So a simple <page> tag is opened like this:

             <page name="about" class="psoft.masonry.Page">

What this means is that the page will use the vanilla Page object to represent itself, and will be referred to in the scope of this level of website's hierarchy by the name "about".

A <page> can contain any combination of the following three tags:

                              this tag has a name and a value parameter, and assigns a property of a page
                              (usually this is a default property that will later bechangable. for example
                              <param name="title" value="About"/>  assigns the page a default title "About".
                              this tag allows you to declare pages that are only available within the scope
                              of the parent page. These page tags can have the same parameters and the same
                              child tags as the original <page> tag.
                              (The <page> tags can be nested to a depth limited only by the system resources.)
                              the child tag is used for page declaration, and will be defined in detail next.

Defining a page is not in itself sufficient to allow you to add it to the parent. You must also declare it as the parent's <child>. The structure of SiteStudio is such that one defined <page> can serve as a base for two different children. A <child> tag must have two parameters:

"name", the name under which this child will be known to its parent. The name must be unique among the parent's children. "page", the name of the page on which this child is based.

The simplest use of the <child> tag would be <child name="about" page="about"/> which states that the parent page can have a child based on the "about" page that will be known to it as "about".

A <child> tag can also have <param> tags inside of it that would supply properties in addition to those defined in the <page> tag of the page that the child is based on. If you wished to have two about pages, one of which would be titled "About You" by default and the other -- "About me", you could use your one definition of the "about" page to achieve both:

                              <page name="about" class="psoft.masonry.Page"/>
                              <child name="about_me" page="about">
                                      <param name="title" value="About Me"/>
                              <child name="about_you" page="about">
                                      <param name="title" value="About You"/>

This way, it would later be possible to add functionality and properties to the core "about" <page> and have these changes automatically translate into both of the children.

You will want to insert both the definition (<page>) and the declaration (<child>) tags into the <page> tag of the entity under which you wish the given page to be located. If you want that page to be a direct child of a website (for example the personal type), you will need to insert these tags into the <page name="personal" ...> tag.

Now that the page is completely defined, you will need to create physical files that define its look and its content. Let us assume that the templates for SiteStudio are located in some directory at template_path, and that the super-website entity is known as "simple".

Then the files for defining an entity of the website should be located in the directory template_path/simple/hierarchy_path where hierarchy_path is the path obtained from putting together a page's name with the names of all its "ansestors" (that is the <page> names, not the <child> names).

So for a page with the name "about" that is a child of a "personal" site, hierarchy_path becomes personal/about/ and the complete path would then be template_path/simple/personal/about/

Similarly, if the about page had a child page named "about_address" (such a page could contain the address information for the site's owner) then the path for that page would be template_path/simple/personal/about/about_address/

For most types of pages, it will be enough to only provide two files in order to fully describe the new page: the layout file and the edit file.

The layout file should be called "html" and contain freemarker-enchanced html code for displaying the content portion of the page. As this file will be <include>d into a file containing the styling code, it should not have an <html> tah or a <body> tag, but simply begin displaying the page's contents right from the start. An example of the simple version of the layout "html" file for the aforementioned "about" page would be: template_path/simple/personal/about/html :


The above code simply shows the page's title and then its text. In addition to the layout file we also need to have an edit file. Its name should be "edit.body", and it should be contained in the same directory as the "html" file.

The format for the file is as follows:

<include global.path+"generic/other"> Include generic freemarker functions.
<call startPage("Some title")> Call the function to statr an edit page and set its title (opens main form).
(property definitions) Define the page's properties.
<call pluginSelector()> Call the plugin selector function.
</form> Close the main form.
<call saveButton()> Put a "Save" button on the page.
<call endPage()> Call end of page function.

The property definition section is the one that you will need to customize to fit your needs. Simply put, this section is a list of named input fields, each of which contains a value. An input field in this file will correspond to a property in the page with the same name, and clicking the "save" button will assign that property the input field's current value.

The following code, for example, allows the user to edit the page's title:

      Title: <input name="title" value="${title}"> <br>

This means that the edit page will contain an input field named title, that will initially have the value of the page's "title" property. If that value is edited on the page, it will be updated back into the property once the "save" button is pressed.

The same analogy will translate to other html <input> types, such as radio buttons, select menus and text areas:

                      Text: <textarea name="about_text" rows="5" cols="40">${about_text}</textarea>

Be careful when using checkboxes however, as by definition of checkbox behavior, no value is submitted when a box is unchecked, and therefore there will not be any way to know that a property was cleared by unchecking the box. You will only be able to use checkboxes with the help of javascript code that would set and clear a hidden field elswhere in the form.

With the two above examples we are ready to construct an edit file for our about page:

template_path/simple/personal/about/edit.body :

            <include global.path+"generic/other">
            <call startPage("About page")>
            <center>Edit About page</center>
            Title: <input name="title" value="${title}"> <br>
            Text: <textarea name="about_text" rows="5" cols="40">${about_text}</textarea><br>
            <call pluginSelector()>
            <call saveButton()>
            <call endPage()>

As you see, we have defined the two properties that were used in the "html" file. Together the files provide a complete definition for the newly added "about" page. However, the functionality is not very exciting yet. So far we can only edit the page's title, and its body, which consists of one paragraph of text.

We can add more paragraphs by simply adding properties to the edit page, and displaying them in the "html" file. We can also add headers to these paragraphs by adding

Header 1: <input name="header1" value="${header1}"> <br>

to the edit page and


to the "html" page.

All these changes will allow us to create a rather complex set of headers and paragraphs in the page. We can also add images to the page. An image in a site stuido template is nothing more than a property that has sub-properties specific to an image, such as its source path.

All images should be named "image.imgName". imgName refers to the name under which the image will be accessible through the page, not the physical file name of the image. For example if you want an image called "myPhoto", it should be referred to as ${image.myPhoto}. SiteStudio has a special notation for inserting, editing and viewing images, a set of functions that integrate it with a supplied ImageUploader application.

To add the above image to the edit file, you should insert the following line:

               Your Photo: ${image.myPhoto.edit}

This line will print the label "Your photo" and then display a control for adding or changing the image stored under the "myPhoto" property. If an image is currently selected, its thumbnail will also be shown.

To actually show the image on the layout page, you must add the code to display that image into the "html" file for the given page. The simplest moethod is to use the ${} variable, which contains the HTML code for a fully formed <img> tag displaying the image. If you need more control over how the image should look, such as adding a border, or changing alignment or size of the image, you will want to write your own <img> tag with those parameters and use ${image.myPhoto.src} for the image source:

    Simple image display     ${}
    Complex image display    <img border="1" align="left" src="${image.myPhoto.src}">

If we use the simple method, the new code of the html file becomes:

template_path/simple/personal/about/html :


As you see, we have inserted the image at the top of the page, before the title.

Using plain textboxes, select menus, radio buttons and images it is possible to craft rather flexible pages and lay them out to your liking. However the addition of transparent sub-pages to the mix will give you even more power and flexibility.

Imagine that instead of coding each paragraph into the "about" page's html file and edit.body file, we were to create a sub-page to the about page called "paragraph". This would allow the user to select the number of paragraphs that they wanted to be included in the About page, and add more if necessary. To allow for this, we must first declare and define the paragraph sub-page as a child of the about page in the XML file:

         <page name="about" class="psoft.masonry.HierarchicalPage">
               <page name="paragraph" class="psoft.masonry.TransparentPage"/>
               <child name="paragraph" page="paragraph"/>
         <child name="about_me" page="about">
                <param name="title" value="About Me"/>

Notice that the page class for the about page was changed to psoft.masonry.HierarchicalPage in order to allow for child pages, and that the paragraph page class is set to psoft.masonry.TransparentPage so that individual paragraphs do not get published as physical pages.

Now we must add a subdirectory to


For the paragraph, we will define only the edit file as the actual display will be done by the parent:

              <include global.path+"generic/other">
              <call startPage("Paragraph")>
              <center>Edit Paragraph</center>
              Heading:<input name="title" value="${title}"><br>
              Text: <textarea name="text" rows="5" cols="40">${text}</textarea><br>
              <call saveButton()>
              <call endPage()>

Note the absence of the line <call pluginSelector()> in the edit file above. This is because transparent pages cannot display plugins, something that will be explained in more detail further on.

Now that we have defined the edit page for the paragraph sub-page, we need to go back and allow for the sub-page's inclusion into the "about" page. This is something that must be done in both the "edit.body" file (so that a paragraph can be added) and the "html" file (so that the existing paragraphs are displayed).

The code to add to the edit.body file should call a special SiteStudio function that draws a list of current pages and allows you to add edit and delete them. The function is <win2fullest()>and its example use in this case is

<call win2fullest("400","Edit Paragraphs", this, pages.paragraph, add.paragraph )>
The syntax is
<call win2fullest(width,title, page, page_list, add_code )>

width is the width of the list window
title is the title of the list window
page is the freemarker page object that references the parent page. If you are listing the children of the current page, you will want to use the variable ${this} for the purpose
page_list is the freemarker list of children pages. Each HierarchicalPage has a ${pages} object in its rootmodel, which is a listing of all the current child pages. If the parent page can have different types of children, you can get the list if children of a particular type by qualifying the variabl name at the end (call to ${pages.paragraph} will return a listing only of paragraph sub-pages)
add_code iis the code needed to add a page to the list. You should use the ${add} hash to retrieve the appropriate code for the type of sub-page you want. for example ${add.paragraph} will return the code for adding a paragraph sub-page. similarly ${add.somepage} will return a code for adding a page of some type "somepage"

Having added the list edit box to our "about" page's "edit.body" file, all that is left is to add the code to display the paragraphs to out "html" file.

This is done by <list>ing the ${pages} list:

                          <list pages as paragraph>
                                ${paragraph.text} <br>

This code will iterate through all the sub-pages and display their titles and text sequentially. If you want to ensure that only the paragraph sub-pages are iterated here (in case you have sub-pages of a different type) you can use the code.

                          <list pages.paragraph as paragraph>
                                ${paragraph.text} <br>

The added qualifier "paragraph" in <list pages.paragraph ...> will ensure that only sub-pages of type "paragraph" get listed. The resulting "html" file will look as follows:


                          <list pages.paragraph as paragraph>
                                           ${paragraph.text} <br>

The functionality of pages can be extended even further with plugins. Plugins are mini-applications that can reside within a page, such as a graphical web-counter or a poll. Various plugins may or may not be included in a given SiteStudio installation, but the standard plugins are:

                          counter        a web counter service
                          poll           a web poll service
                          board          a discussion board
                          guestbook      a guestbook service

Some pages can be more fit to include some plugins than other pages. That is why you have the option of enabling only the plugins you want on any given page. To do this, you must add a special <param> tag to the <page> definition you want in the main XML file for the super-website. For example to add the poll and cownter plugins to the "about" page, you would add the following tag:

                          <param name="supported_plugins">

In general, you must add a <param> tag that is named "supported_plugins", and that contains a <value>tag for each plugin supported.

Then, as long as you did not omit a <call> to <pluginSelector()> in the "edit.body" file for the given page, you should see the chosen plugins appear in the select box for the plugins that can be added.

Now that a page can contain plugins, it is important to allow you and the user to control where on the page these plugins should be located. Since different pages can be layed out in different ways, there is no way for SiteStudio to pre-determine where the best place for a given plugin would be on a given page. That is why this control was left to the template designer and the end user.

As a template designer, you will spot the areas on a given page that are best suited for plugins. For example in our about page, it would be possible to include the plugin at the very bottom, or, perhaps right under the "myPhoto" image. To notify SiteStudio about this, let us assign each of these locations a name: "top" and "bottom".

Now, we must add another <param> tag to the <page> definition of "about". This one will be:

                      <param name="plugin_spots">

In general, it must be a <param> tag named "plugin_spots" that has a <value> tag for each available spot in the page. Each spot should be assigned some arbitrary name that is unique to that page. (It is advisable to have names that somehow indicate the positioning of the plugin spot.)

Now let's move to the code for the page's layout, it's "html" file. In this file we must add appropriate function calls for appropriate positions. The call is
<call showPluginSpot(name)> where name is the name of the spot as it was defined in the XML file. To continue with our example the "html" file for the about page becomes:


                        <call showPluginSpot("top")>
                        <list pages.paragraph as paragraph>
                              ${paragraph.text} <br>
                        <call showPluginSpot("bottom")>

The call to <showPluginSpot()> will automatically insert all the plugins that the user has decided should go to the particular spot. Once these changes are made the user will be able to add to the "about" page a counter and a poll, and for each select whether they appear at the top of the page or at its bottom.

. Positive Software Corporation.
All rights reserved.