Beginning with XML controls

XML Controls are webcontrols that are specified as an XML document. Each tag in the XML Document corresponds to a webcontrol including other XML controls. The XML Documents are compiled into a regular ASP.NET webcontrol to ensure maximum performance.

 

XML Controls are built on top of standard ASP.NET and standard webcontrols. Anything that is possible in ASP.NET is possible with XML Controls, but the writing, managing and reusability is much easier with XML Controls.

1.  Architecture

An XML Control is an XML file located in configurable file folder. When the application starts, the configured folders are searched and each XML file is compiled into a webcontrol. The application watches the file folders for changed files and recompiles any changed XML Controls.

 

This approach makes it easy to write and edit XML Controls – the applictions automatically compiles changed XML Controls, so that the developer does not have to manually compile the project.

 

The compilation of an XML Control consists of two steps – first the XML document is transformed into an interim C# source file, which is then compiled into a temporary assembly. Each compiled web control is located in a separate assembly.

 

Each tag in the XML Control XML Document corresponds to a web control. As an XML Control is a webcontrol itself, XML Controls can be reused witin another XML Control. This makes XML Controls powerful as complex controls can be broken into smaller fragments that are more easily managed and reused. This is analogeous to methods in a programming language.

 

XML Controls supports placeholders. Placeholders make it possible to specify the inner content of an XML Control. A placeholder can be named which enables an XML Control to specify multiple placeholders.

 

XML Controls can be parameterized which increased reusability and decreases development time. Expressions are also allowed for more complex operations.

 

When compiled the web control is a subtype of the Sitecore.Web.UI.XmlControls.XmlControl class. The developer can specify another class to inherit from, which allows the developer to add custom code to the XML Control.

2.  Configuration

XML Controls are configured in the web.config. It is possible to configure the file folders, assembly references and using statements.

 

Section

Description

/ui/using

Defines using statements that are included in the interim C# file.

/ui/references

Defines the assemblies to reference in the compilation step.

/controlSources

Defines the file directories to look for XML Controls and assemblies where web controls may appear.

 

An entry in the control sources section can have the following attributes:

 

Attribute

Description

Mode

If mode is “off”, the entry is ignored.

Namespace

Defines the namespace of the webcontrols in this source.

Folder

The file directory.

Assembly

An assembly that contains webcontrols.

Deep

Defines that subfolders should be included, if the source is a directory.

Prefix

If specified, controls in the XML Control must have this namespace.

 

Control sources are searched in the sequence that is specified in the web.config. If two XML Controls have the same name, the control that occurs in the first control source is used and the other ignored. This allows XML Controls to be overridden, simply by insert the new control in a control source that is placed first.

2.1.  XML Control Configuration example

:
    
<controlSources>
      
<source mode="on" namespace="Sitecore.Web.UI.XmlControls" folder="/sitecore/shell/override" deep="true"/>
      
<source mode="on" namespace="myNameSpace" folder="/sitecore modules/controls" deep="true"/>
        :
    
</controlSources>
      :
    
<!-- UI -->
    
<ui>
      
<usings>
        
<using>System.Collections</using>
        
<using>System.Reflection</using>
          :
      
</usings>
      
<references>
        
<reference>System.dll</reference>
        
<reference>System.Data.dll</reference>
          :
      
</references>
      :
    
</ui>

3.  Using XML Controls in Sitecore

Sitecore supports XML Layouts which are XML Controls that are rendered as a layout. In Sitecore simply create a new XML Layout and specify the name of the control in the Control field. When the layout is rendered, the XML Control is instantiated and rendered.

4.  Using XML Controls from an ASP.NET page

The web control ControlRenderer renders a webcontrol including XML Controls. This control can be used to render XML Controls in a standard ASP.NET page.

<sc:ControlRenderer runat=”server” ControlName=”MyControl”/>

5.  Structure of an XML Control

To write a new XML Control simply create a new XML file in a control source folder, e.g. /layouts/MyControl.xml. All compiled XML Controls inherits from the Sitecore.Web.UI.XmlControls.XmlControl class unless other specified.

6.  Root node

An XML Control has a root node which is usually called “control” although the name can be anything. The root node always has a namespace declaration named “def”. The “def” namespace is known by Sitecore and is used to identify special attributes.

 

You can also specify the Visual Studio Intellisense namespace, which will enable the Visual Studio editor to show Intellisense when editing an XML Control.

 

The standard root looks like this:

6.1.  Visual Studio Intellisense example

<?xml version="1.0" encoding="utf-8" ?>
<control
  
xmlns:def="Definition"
  xmlns
="http://schemas.sitecore.net/Visual-Studio-Intellisense">

7.  Control nodes

The XML Controls are specified under the root node. The name of the node is the name of the XML Control.

 

A XML Control file may contain more than one XML Control although it is recommended that each file only contains a single control.

 

For instance the following example defines the MyControl Xml Control.

7.1.  MyControl

<control
  
xmlns:def="Definition"
  xmlns
="http://schemas.sitecore.net/Visual-Studio-Intellisense"
  xmlns:shell
="http://www.sitecore.net/shell">
  
<MyControl/>

8.  Generic Controls

When an Xml Control is parsed each tag (XML node) is converted into a web control. If no matching web control can be found, the tag is converted into a Generic Control which is implemented in the Sitecore.Web.UI.XmlControls.GenericControl class. The GenericControl control simply outputs the tag and any attributes directly.

 

This allows standard HTML tags to be included in the Xml Control. For instance the following example uses the standard HTML tag <li> to display a list item.

 

<HtmlListItem>

   <li>

    <Literal Text=”Item”/>

  </li>

</HtmlListItem>

 

Please notice that Xml Controls are case-sensitive, e.g. the tags ListItem and Listitem do not refer to the same control.

9.  Parameters

XML Controls supports parameters. A parameter is an identifier prefixed with a dollar sign, e.g. “$MyParameter”. The identifier must be a valid C# identifier. At runtime parameters are substituted by any value provided as an attribute on the XML Control usage tag.

 

For instance, this following XML Control accepts two parameters, Style and Text.

 

<FormattedText>

  <Border Style=”$Style”

    <Literal Text=”$Text”/>

  </Border>

</FormattedText>

 

<MyControl>

  <FormattedText Style=”color:red” Text=”Hello World”/>

</MyControl>

 

The parameter identifier can be only a part of an attribute. For instance:

 

<ColoredText>

  <Border Style=”color:$Color”

    <Literal Text=”$Text”/>

  </Border>

</ColoredText>

 

<MyControl>

  <ColoredText Color=”red” Text=”Hello World”/>

</MyControl>

 

When the Xml Control is compiled, each parameter becomes a property on the resulting web control. The developer must take care not to name a parameter the same as an already existing property on the XmlControl class.

10.  Expressions

Parameters can be expressions. Expressions uses the syntax ${ <expression> }. Expressions are evaluated at runtime. In the compiled webcontrol, the expression is inserted directly into the code, so any valid C# code can be used.

 

A common expression ensures a default value for a parameter. In this following example the text will be red, if the color parameter is not specified.

10.1.  Expression for ColoredText Control

<ColoredText>
  
<Border Style='color:${StringUtil.GetString($Color, "red")}'
    <Literal Text
="$Text"/>
  
</Border>
</ColoredText>

<MyControl>
  
<ColoredText Text="Hello World"/>
</MyControl>

11.  Placeholders

Standard Sitecore placeholders can be used to specify the inner content of a webcontrol. This allows complex controls to be built. Placeholder are defined in the def namespace, this is : “<def:Placeholder/>”.

 

For instance, this following controls displayes a window with a caption and text inside the window. The Literal control in MyControl is inserted into the placeholder in the WindowFrame placeholder at run time. This allows the Window Xml Control to display any kind of content.

11.1.  WindowFrame control default placeholder

<WindowFrame>
  
<Border Border="1px solid black">
    
<Border Background="blue">
      
<Literal Text="$Header"/>
    
</Border>
    
<def:Placeholder/>
  
</Border>
</WindowFrame>

<MyControl>
  
<WindowFrame Header="My Frame">
    
<Literal Text="This is the inner content of the window."/>
  
</WindowFrame>
</MyControl>

Placeholders can be named, which allows a control to define multiple placeholders. The default placeholder does not have a name.

11.2.  WindowFrame control with named placeholder

<WindowFrame>
  
<Border Border="1px solid black">
    
<Border Background="blue">
      
<def:Placeholder def:name="Header"/>
    
</Border>
    
<def:Placeholder/>
  
</Border>
</WindowFrame>

<MyControl>
  
<WindowFrame Header="My Frame">
    
<Border def:placeholder="Header" Background="red">
        Red Caption
    
</Border>
    
<Literal Text="This is the inner content of the window."/>
  
</WindowFrame>
</MyControl>

The Border control is inserted into the Header placeholder, while the Literal control is inserted into the default placeholder. The attribute def:placeholder defines which placeholder the control is inserted into.

12.  Web control Inheritance

The compiled web control inherits from Sitecore.Web.UI.XmlControls.XmlControl class. The def:inherits attribute on the control node allows the developer to specify another class to inherit from. This class should however have the Sitecore.Web.UI.XmlControls.XmlControl as an superclass. This allows the developer to extent an Xml Control with additional functionality.

 

The def:inherits attribute specifies a type and assembly, which uniquely identifies a type. For instance, in the following example the ColoredText webcontrol inherites from the MyControls.ColoredText web control which is located in the MyAssembly assembly.

12.1.  ColoredText XML Control Inheritance

<ColoredText def:inherits="MyControls.ColoredText,MyAssembly.dll">
  
<Border ID="Border"
      Style
='color:${StringUtil.GetString($Color, "red")}'>
    
<Literal ID="Text" Text="$Text"/>
  
</Border>
</ColoredText>

Using this construct, it is possible to apply logic to the control. For instance, the following example hides the control if the Text parameter is blank. Also notice that web controls that have an ID, can be referenced directly in the code.

12.2.  Colored Text XML Control source

public class ColoredText : Sitecore.Web.UI.XmlControls.XmlControl  {
  
protected Border Border;
  
protected Literal Text;

  
protected override void OnLoad(EventArgs e) {
    
base.OnLoad(e);

    
if (Text.Text.Length == 0) {
      Border.Visible
= false;
    }
  }
}

13.  def:ID

While giving each web control an ID to identify the control in an inherited class, makes it easy to reference the control, it also makes it impossible to use the control more than once on a page, as the ID will occur multiple times which ASP.NET does not accept. XML Controls does not yet support namespaces, but another work-around exists.  

A control can be given an pseudo ID by using the attribute def:ID. This assigns the pseudo ID to the control so that it can be resolved for referencing, but does not actually assign the value to the ID property. From ASP.NET point of view the control does not have an ID, but it can be referenced by the inherited class nonetheless.  

Usually the ASP.NET ID is then assigned in the inherited class with a unique prefix, for instance:

13.1.  def:ID XML source

<ColoredText def:inherits="MyControls.ColoredText,MyAssembly.dll">
  
<Border def:ID="Border" Style='color:${StringUtil.GetString($Color, "red")}'>
    
<Literal ID="Text" Text="$Text"/>
  
</Border>
</ColoredText>

13.2.  def:ID C# Source

public class ColoredText : Sitecore.Web.UI.XmlControls.XmlControl {
  
protected Border Border;
  
protected Literal Text;

  
protected override void OnLoad(EventArgs e) {
    
base.OnLoad(e);

    
if (Text.Text.Length == 0) {
      Border.Visible
= false;
    }

    Border.ID
= Control.GetUniqueID();
  }
}

14.  Optimizing XML Controls

As each tag in an Xml Control is converted into a web control, Xml Controls generates many more web control that standard ASP.NET. The developer should therefore take care when using using Xml Controls and try to reduce the number of tags. The standard ASP.NET 1.1 engine performs poorly when the number of web controls on a page exceeds 500 controls.

15.  Debug XML Controls

The interim C# file that is generated when an XML Control is compiled, is stored in a folder named “debug” under the control source folder. It is not possible to using breakpoint from Visual Studio as web controls are compiled to temporary assemblies.

 

Sitecore support a special way of displaying XML Controls directly. Simply add a parameter xmlcontrol=<name> on the URL and the XML Control is rendered. For instance the following URL renders the XML Control MyControl:

 

http://localhost/default.aspx?xmlcontrol=MyControl