uigen.exe generates a complete Visual Studio ASP.NET project from a re-motion domain, i.e. one or more assemblies containing the domain object classes constituting the domain. uigen.exe gets a path to a directory, inspects all assemblies in it and checks whether it contains domain object classes. Based on what it sees, uigen.exe generates a basic ASP.NET application to work with those domain objects.
uigen.exe is template-based. It uses a directory tree with templates for generating a typical Visual Studio ASP.NET projects. The directory tree corresponds roughly to the generated tree.
This is how the "template tree" looks like:

This is how the generated tree for a PhoneBook ASP.NET application project looks like:

(The extra folders are bin, obj and Properties. They are not part of uigen.exe's program generation,
they are build products from building the PhoneBook web application from generated sources.)

The original tree contains files and templates from which uigen.exe makes the actual files in the generated project – at the same relative path where their copies or expansions will show up in the generated tree. Some files - like images - are just copied.
A typical example is the top-level folder in the template tree. To the left you see the templates in uigen.exe's root of the template tree, to the right you see the corresponding top-level of the generated PhoneBook tree:

In other words: most of the templates have the same name as the resulting file. The notable exception here is the name of the resulting project, in this case PhoneBook.Web.csproj. This file originates from the template named WebClient.csproj and is renamed in the course of template expansion.
If you open a template file, you will see that it contains "placeholders", denoted by "Dollar-Dollar". (e.g. "$WEB_CLIENT_GUID$"):

The $(...) items are NOT uigen-placeholders! They are Visual Studio placeholders!

You might recognize the highlighted placeholder $PROJECT_ROOTNAMESPACE$ in the picture: this is the placeholder you set in the uigen.exe configuration file. It is substituted by the placeholders value (a string).
Other good examples for directories with template files corresponding to exactly one output file is the Classes directory, with templates for

Not all templates work in such a fun-and-easy 1:1 fashion, however. If you look into the WebClient\UI template subfolder you will find the following templates:

All the first three files, NavigationTabs. serve as templates not for a single file, but for one file per domain object class. For example, for each of the classes Location, Person and PhoneNumber, a set of EditLocationControl., EditPersonControl.. and EditPhoneNumberControl. will be generated from the corresponding EditControl.* templates.
The rule applies to EditForm. and SearchResultForm.. From the NavigationTabs.* only one instance is generated, independently from the number of domain classes. These placeholders get their values from inspection of domain assemblies.

More about placeholders

Not all $PLACEHOLDERS$ get their values from the uigen.exe configuration file as strings. Some placeholders get their values from other sources. The central example here are the names for domain object classes. uigen.exe provides a mechanism to iterate over all domain object classes.
If you open the WebClient\UI\NavigationTabs.ascx template, you will see three $PLACEHOLDER$ types:

The $REPEAT_FOREACHCLASS_BEGIN$ and $REPEAT_FOREACHCLASS_END$ acts as a bracket around a loop, iterating over all domain object classes. The $DOMAIN_CLASSNAME$ acts as a counter variable with the current domain object class name as value. We call such special placeholders "Loopers".
This construction is needed in several templates – whenever some code/text has to be expanded for each domain object class.
WebClient\UI\NavigationTabs.ascx is an example for iterating over domain object classes in a single template. This is in contrast to templates like WebClient\UI\EditForm.aspx, which iterate over domain object classes and generate one file per domain object class. How can that be done? We will return to this question in section TabbedEditor.xml below. Let's look at how the looper constructions are used within a single file.

In more general terms, a looper is always based on a list of thingies (classes, properties, enums) that can be represented as strings. The class looper might be based on the list of classes Location, Person and PhoneNumber (the classes in the PhoneBook). The class looper expands the text between the start placeholder and the end placeholder for each item in the list and uses the string representation as value for the iterator variable(s).
An example for the class looper at work is the UrlMapping.xml template that expands to a full-blown UrlMapping.xml configuration file for the PhoneBook app (for example). The task here is to create an EditX- and SearchX- entry for each domain object class in the domain (i.e. Location, Person and PhoneNumber in the PhoneBook application).

Look at this section in the UrlMapping.xml template:

$REPEAT_FOREACHCLASS_BEGIN$
<add id="Edit$DOMAIN_CLASSNAME$" type="... blah..." blah />
<add id="Search$DOMAIN_CLASSNAME$" type="... blah..." blah />
$REPEAT_FOREACHCLASS_END$

In the expanded UrlMapping.xml file this section has been expanded three times, once for Location, Person and PhoneNumber:

<add id="EditLocation" type="...
<add id="SearchLocation" type="...
<add id="EditPerson" type="...
<add id="SearchPerson" type="...
<add id="EditPhoneNumber" type="...
<add id="SearchPhoneNumber" type="...

A looper can have more than one iterator variable. The class looper sports not only $DOMAIN_CLASSNAME$, but also $DOMAIN_QUALIFIEDCLASSTYPENAME$ expanding to the class name plus namespace for the current class.
More loopers exist besides $REPEAT_FOREACHCLASS_BEGIN/END$. There are:

- $REPEAT_FOREACHPROPERTY_BEGIN/END$ -- iterates over properties in the class (not used in the PhoneBook web application)
- $REPEAT_FOREACHENUM_BEGIN/END$ -- iterates over all enum types; deprecated, was used for injecting multilingual resources into the domain (see below)
- REPEAT_FOREACHREFERENCEDPROPERTY_BEGIN/END$ -- iterates over reference properties or {{ObjectList}}|s

A complete list of placeholders can be found in the file Placeholder.cs. Not all of them are used in the current templates.
Placeholders.cs can be found here.

TabbedEditor.xml

(The many faces of application generation)

The uigen.exe configuration file provides "placeholders" (macros) for substitution in other files, but not more. The central piece, the file that tells uigen.exe what to do, is the TabbedEditor.xml file. If you inspect it you will sense that generating a project for a re-motion ASP.NET web client application has several different parts:

In a way, the TabbedEditor.xml file can be seen as a batch file written in a special programming language, and uigen.exe can be seen as an interpreter for that language. The TabbedEditor.xml file is the batch file for creating tabbed editor applications (with their distinctive feature being that each domain object class gets its own tab/page in the application). You could write generators for other types of applications simply by writing a "batch file" like TabbedEditor.xml with different instructions. Flexibility is limited, however, since the "batch language" is not Turing-complete.
When staring at uigen.exe, alert readers will notice that TabbedEditor.xml is itself a template file. The $PLACEHOLDERS$, $WebClientName$, $DomainProjectName$, $DOMAIN_CLASSNAME$, etc. put it away: TabbedEditor.xml is subject to placeholder substitution and thus clearly a template. Its expansion is never stored anywhere, however.

Not contained in the template, however, are the looping elements $REPEAT_FOREACHCLASS_BEGIN$ and $REPEAT_FOREACHCLASS_END$. This function is taken over by corresponding XML tags, namely <forEachClass> and </forEachClass>.
Another such looping element is <forEachEnum>, with an iterator placeholder named $DOMAIN_ENUMNAME$.

So TabbedEditor.xml is the master configuration file for uigen.exe. Apart from containing a list of files to copy and templates to expand it controls the following chores:

Each of the chores is discussed separately in the following sections.

Files and templates

uigen.exe dedicates

This works for "inner expansion" and "outer expansion". Inner expansion means that the specified file(s) are expanded, and the expanded product gets the same name as the original template file. Example: In

<files pattern="WebClient*.aspx" target="$WebClientName$" />

the file default.aspx is fingered (among others) in the template tree and expanded to the project tree as default.aspx.
Outer expansion means that the specified file(s) are expanded for each class, and the expanded products each get a name that reflects the class for which it has been expanded. Example: In

<file template="WebClient\UI\EditControl.ascx" target="$WebClientName$\UI\Edit$DOMAIN_CLASSNAME$Control.ascx" />

the file EditControl.ascx in the template tree is expanded to EditLocationControl.ascx, EditPersonControl.ascx and EditPhoneNumberControl.ascx if there are three classes named Location, Person and PhoneNumber.
All template expansion- and copy-operators under the node global are submitted to inner expansion, all the template expansions under the ndoe <forEachClass> are subject to outer expansion.

Generating globalization (resource) files for enums

This looked like a good idea in 2006, but has run out of fashion since then. The argument is that it is bad taste for a program generator to add code to the DOMAIN, and globalizing enums clearly is part of the domain. That's why the corresponding section in TabbedEditor.xml has been commented out.

Mapping domain class property types to BOC controls

This important mapping is expressed under the node properties/controlMappings and simply contains a set of operators – <mapping>. Example: The line

<mapping propertyType="Remotion.ObjectBinding.IBusinessObjectEnumerationProperty" control="remotion:BocEnumValue" />

simply maps an enumeration property to a BocEnumValue.

The extra optional attribute isList controls whether the value can be represented by a list (drop-downlist, list box, etc.)
injecting extra .aspx-XML into .aspx/.ascx-declarations

Under the node properties/additionalAttributes and properties/additionalElements we find extra code for supplementing aspx-declarations for each property = extra attributes and extra elements.

Structure of the generated web project

Directories
Other notable files
Where to find uigen.exe in the SVN-repository

For the re-motion version 1.13.6, the one supported by the PhoneBook tutorial:

https://svn.re-motion.org/svn/Remotion/trunk/Remotion/ObjectBinding/Web.CodeGenerator/

Later versions have a new uigen.exe in

https://svn.re-motion.org/svn/Remotion-Contrib/Remotion.ObjectBinding.Web.CodeGenerator