Even if your WebScript has an additional configuration file (e.g. one that ends '*.config.xml') then it the controller is still responsible for processing that configuration and adding it to the model ... a configuration file achieves nothing by itself!
model.myVariable='This is a variable'
...in a controller can be referenced in a FreeMarker template by:
The controller can add any variables it likes to the 'model' object but the refactored WebScripts make use of the 'widgets' attribute (e.g. 'model.widgets') and the new page creation approach relies on the 'jsonModel' attribute (e.g. 'model.jsonModel').
Surf will check for the existence of any extension controllers mapped to the WebScript before the FreeMarker template is renderer is called.
This means that one or more controller extensions can change the contents of the 'model.widgets' or 'model.jsonModel' attributes before they are processed by the custom directives in the template. The core controller will always be run to setup the default model and all applicable extension controllers will have their turn at updating the model before it is passed to the template.
If you're writing an extension module that you want to distribute around the Alfresco Community then you need to be aware that other extensions might have changed the model in an unexpected way before your extension has it's turn.
Real World Example
Let's see this in action by adding a new menu item to the header in Alfresco 4.2 Enterprise. Information on how to create and deploy your extension module have been covered in detail before so I'm not going to go over those now, instead I'll just focus on the controller extension itself.
If we want to add a new menu item (or indeed any new widget) we need to identify a parent widget to add it to. At the moment this still requires some knowledge of the Alfresco source code (although it is easy enough to identify the source files using SurfBug).
In this case we're customizing the 'share-header.get' WebScript whose controller imports the 'share-header.lib.js' file which provides functions that return a model fragment of the header menu. It's important to note that you don't want to (and indeed can't) extend the lib file directly - but instead much extend the controller that imports the lib file.
All of the widgets are given unique IDs in the JSON model so that they can be easily referenced. In this case we want to add a new 'alfresco/menus/AlfMenuBarItem' widget to the 'alfresco/header/AlfMenuBar' widget identified as 'HEADER_APP_MENU_BAR'. For the purposes of this example it doesn't really matter where the menu item takes the user, but in this case we're going to use it to navigate to the user's trashcan.
The controller extension should contain the following code:
var menuBar = widgetUtils.findObject(model.jsonModel, 'id', 'HEADER_APP_MENU_BAR');
if (menuBar != null)
label: 'My Trashcan',
targetUrl: 'user/' + encodeURIComponent(user.name) + '/user-trashcan'
...and when the module is deployed you will see the following added to the Share menu: