Writing a SiteFusion Extension: The Basics (Part I)

As you may have noticed by now, SiteFusion and XUL technologies offer a large set of functionalities and tools for both the end user and the developer. There may be situations however, in which a developer would like to perform actions that are not supported by either SiteFusion itself or it’s underlying XUL foundation. When this missing functionality needs to be executed client-side, it is generally a wise idea to write a client side extensions. Since SiteFusion uses XUL , just like Mozilla Firefox, we use this as a starting point.

Prior to reading the rest of this tutorial, I assume you have taken notice of the Firefox extension fundamentals provided by Mozilla. The following links provide a good starting point:

The first link also offers a helloworld extension as well as an online extension generator. I encourage you to try them both and try out your extension within the Firefox prior to reading the rest of this article.

There are two fundamental differences between Firefox extensions and SiteFusion extension.

  • SiteFusion naturally, has an different application ID. Extensions use application ID's for settings their target applications. This is done in install.rdf. You can find SiteFusion's application ID in application.ini. Or just copy paste it from this page: {58e7ba83-7f6f-4058-ab62-20556676f818}.
  • While Firefox extension are often used to enrich the GUI using a technique called overlays, e.g. by adding toolbars or toolbar buttons, this is not the case for SitFusion extensions. SiteFusion applications are writting in PHP and the interface get dynamicly updated to the client, using javascript. Therefore, using overlays in a SiteFusion context is not a good idea. In our context, we use extensions to add client side functionality in the form javascript code, not for extending the user interface. Please take notice of this difference when reading more sophisticated mozilla resources that focus on extensions.

Extensions can contain both javascript and binary code. When not using platform dependant XPCOM objects (like the Windows Registry), Javascript code generally has the advantage that it can be used on all different platform, whilst binary code has an obvious speed advantage over Javascript. Binary code however, is not platform independant.

Firefox extensions come with the .xpi file extension, and are in fact zipped folder structures that contain a number of files and folders. The files/folders written in bold are obligatory.


install.rdf contains instructions for installing the extension. It might look like this:

<?xml version="1.0"?>

<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

  <Description about="urn:mozilla:install-manifest">
    <!-- Target Application this extension can install into,
         with minimum and maximum supported versions. -->
    <!-- Front End MetaData -->
    <em:description>A test extension</em:description>
    <em:creator>Your Name Here</em:creator>

Please take notice of the targetApplication tag and it's contents. The minimal release version of SiteFusion that supports extensions is 1.2.1. Since we're not planning an intermediate release that breaks with the current extensions, the maxversion can safely be set to 2.*. Also notice the ID which has to equal SiteFusion's application ID: {58e7ba83-7f6f-4058-ab62-20556676f818}.

The rest of the xml formatted file contains metadata for your extension. The id of the extension we are creating is foo@bar.com and it's version is 1.0.

Next thing we need to do is create a chrome manifest file.

Chrome is the set of user interface elements of the application window that are outside of a window's content area. Toolbars, menu bars, progress bars, and window title bars are all examples of elements that are typically part of the chrome. However, since we are only interested in javascript extensions for our client, we use it in a different manner.

The root chrome.manifest is the only chrome manifest we need for a SiteFusion extension. It can contain multiple providers, but we only need the content provide. Put the following code in your chrome.manifest file.
content foobar chrome/content/

Now, let's add some code to our extensions. In chrome/content create the file code.js. Put the following lines in it:

function foobar() {
    alert('hello world');

Now save the file. Our extension is now ready. Zip it up and rename it to foo@bar.com.xpi. You don't necessarily need to use it's ID as the filename as of now, but you will need to, to enable extension pushing later on.

Installing your extension into your sitefusion client can be done in a number of ways. The easiest way is to use the extension manager. Refer to Other extension installation methods for other means of installing extensions. Since the SiteFusion Admin application that is contained in the default server package includes a link to the extension manager, let's fire it up. When the application has loaded, click on tools in the menubar, followed by 'Manage Addons'.  Now pick the Extensions tab and click Install. Point the dialog to your newly created extension. When you followed the instructions correctly, SiteFusion will install the extension and ask you permission to restart itself. Close, or restart and close SiteFusion for now.

The last thing we need to do is create a server side component, so that the SiteFusion server can use the client side code we added to our extension. SiteFusion components can consist out of both javascript and php code, just like a SiteFusion Node. When you create a component, you can create a simple PHP class which calls Javascript methods on the client, or create a more sophisticated SiteFusion Node that is beeing add to the client's registry and can respond to events and such. For our beloved foobar extension, the first sollution suffices. I will explain the more sophisticated way later on in this tutorial.

SiteFusion components reside in the /components folder inside your SiteFusion directory. Please note that this has nothing to do with the components dir in the client directory! Let's create a foobar.js file in sitefusion/components/ and fill it up with the following code:

SiteFusion.ClientComponents.Foobar = {

    Foobar: function() {
        var tmpNameSpace = {};                         
        var sl = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].createInstance(Components.interfaces.mozIJSSubScriptLoader);
        sl.loadSubScript("chrome://foobar/content/code.js", tmpNameSpace);

This will create a Foobar object in the ClientComponents object. Next we create foobar.php.inc so we are able to instantiate this object through server side php code. Put the following code in it:
class Foobar
    static public function 
Open() {

We are now done with the server side part of our component. The last thing we need to do is implement the component in our application.

First we have to perform a LoadClass call that will include both the server and the client side code of the component in our application. You can place these calls everywhere in your application's php files, so just put the following line in the global scope of your startup.php.inc file:

'foobar''components' );

After that, it's time to create the real implementation. Let's put it in the command event handler of a XULButton. Before calling Foobar::Open(), we have to check wheter or not the client contains the extension we wish to use. Create the following event handler:


public function onCommandButton($e) {
    if (isset(
ApplicationProcess::$ExtensionInfo['foo@bar.com']['enabled'] == true)
$this->hostWindow->alert("You don't have the foobar extension installed!");

Hit the button et voila, the extension will alert! You have now succesfully called client-site code from a hand-made SiteFusion extensions! It may not seem very usefull as of yet, but we will be exploring the futher possibilities two upcomming tutorials: creating client-side brandings and creating binary extensions.

Other extension installation methods
As we already discussed, the extension manager is the prefered way of installing extensions. There are, however, also other methods of installing them, which opperate in a more automated manner.

The first method we'll discuss is using command line arguments. When you start the sitefusion stub executable (sitefusion.exe on windows) with the arguments -installextension C:\myextension.xpi, it will install this extension and then shut down. You can include multiple -installextension arguments in one call. You could also force the sitefusion stub executable to restart immediately after installing by adding -restart=true.

The second alternative method is using a predefined location for the xpi's that triggers automated installation on startup. On Microsoft Windows, this location is %APPDATA%\SiteFusion\Sitefusion\sitefusion-install-extensions. If you changed your application.ini, this path is %APPDATA%\VendorName\ApplicationName\sitefusion-install-extensions. On Mac OSX systems, this location is ~/Application Support/ApplicationName/sitefusion-install-extensions. Please note that the source .xpi's get deleted immediately after installing.

The last and most sophisticated way of installing extensions is by pushing them when a SiteFusion application needs it's specific functionality. Please make sure that your extension works cross-platform when you decide to use this method.

Before you start pushing extensions, make sure to locate them in the /extensions folder on your SiteFusion server. Name them equal to their id. In case of our sample extension, this would be foo@bar.com.xpi. Also, start up SiteFusion Admin (or any other SiteFusion app that contains a link to the Extension Manager) and uninstall the extension you are going to push. This, ofcourse, because we need to check if it installed automatically, later on.

Now open up one of your application's source files. This can be any file, also the .startup.php.inc files that contain the starting point for all SiteFusion applications. Add the following line to the global scope.

RequireExtension( "foo@bar.com");

Please note that you only provide it's basename, that is, without the .xpi file extension.

The complete syntax for this call is RequireExtension( $id, $minVersion, $maxVersion,  $alternateFile ). You can also enforce disabling an extension by using DisableExtension( $id, $minVersion, $maxVersion ).

Now start up you application. Please notice that, before the SiteFusion source files get loaded from the server, the client downloads the extension your required, installs it, restarts, and automaticly logs on again using the credentials your provided in your original login attempt.

Comment on this tutorial
Copy the code: