This is a post in my blog series Introduction to Chameleon...
Chameleon represents a major shift in the implementation of themes within Community Server. Changes include:
- The removal of skin files
Community Server 2.1 and earlier included a large number of specific-purpose controls each with their own ASCX file containing their layout. Chameleon defines a single ASPX file for each URL in SiteUrls.config (potentially one ASPX file for many URLs in SiteUrls.config).
Each ASPX file defines the complete content of the rendered page allowing for more control over the entire page layout and behavior. Master pages and user controls are optional and can be used or implemented however the theme developer sees fit. No longer is a rendered page a collection of six or more ASCX files—there is just one file per rendered page by default (not including master pages).
- A complete blog theme now consists of 8 UI files (down from 55 in CS2.1, or 85% fewer files)
- A complete site theme now consists of 70 UI files (down from 164 in CS2.1, or 58% fewer files)
- General-purpose controls
Community Server 2.1 and earlier included controls with very specific UI purposes and behaviors. Most 2.1 and earlier controls looked for predefined (and often cryptic) child control IDs within their associated skin files and simply populated these recognized child controls. The control, then, put constraints on theme developers’ options—only the predefined number and type of child controls were supported and control behaviors and success actions were predefined and could not be overridden.
Chameleon, instead, defines a standardized set of general-purpose controls based on the Community Server API. Instead of “pushing” data into a page within a theme (as in CS2.1 and predefined child control support), Chameleon controls “pull” data from the Community Server API providing a huge amount of flexibility for theme developers. Chameleon controls support declarative and extendable “DisplayConditions” which define under what circumstances a control should render and declaratively-defined “Actions” that define what should happen when supporting events occur on a control (such as the successful submission of a form).
Chameleon is implemented as a simple declarative UI language with controls related to each type of data existing in the Community Server API.
For example, in Chameleon, the display name of a user can be retrieved and displayed using a UserData control:
<CSControl:UserData Property="DisplayName" runat="server" Text="Display name is {0}" LinkTo="Profile" />
which would render
Display name is Ben
linked to my profile.
Wherever you want to show user data, you use the same control: UserData. The control is aware of its context …
- Implicit, contextual data binding
All Chameleon controls support implicit, contextual data binding. For example,
- A UserData control rendered within a SectionList control would display data related to the first owner user of each Section (if at least one owner exists for the section; similarly, a UserList control would list all owners of the Section)
- A UserData control rendered within a PostList control would display data related to the author of each post
Many controls that list data (such as SectionList and UserList) also support the “QueryOverrides” option that allows the theme developer to define or override the default implicit data source as well as define pager(s) to page the data listed.
The implicit data source can be overridden by setting the DataSource property on the control, however. In most cases (all cases within the default theme of CS3.0), this is not necessary.
As an example of implicit contextual data binding, the following:
<CSForum:ForumPostList runat="server">
<QueryOverrides SortBy="SortOrder" PagerID="Pager" PageSize="40" />
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<CSForum:ForumPostData Property="Subject" runat="server" />
by
<CSControl:UserData Property="DisplayName" LinkTo="Profile" runat="server" />
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</CSForum:ForumPostList>
<CSControl:Pager runat="server" id="Pager" />
would list the forum posts according to the current context (for a thread, for example), 40 at a time, ordered by their “sort order”, and paged by a single pager below the list of posts as
* Post Subject 1 by Ben
* Post Subject 2 by Ben
* Post Subject 3 by Ben
* …
* Post Subject 40 by Ben
1 2 3
- Less (or no) predefined mark-up
Community Server 2.1 and earlier included controls and formatting methods that implemented a lot of hard-coded HTML mark-up. Chameleon controls, in general, support complete control over their rendered mark-up via properties and templates.
Only controls which implement rich client-side behaviors have strictly defined HTML mark-up. All standard controls include no hard-coded HTML mark-up. This provides theme developers with complete control over their rendered HTML.
To define simple mark-up around the content of a Chameleon control, all controls expose "Tag", "CssClass", and "ContainerID" properties, for example:
<CSControl:UserData runat="server" Property="DisplayName" Tag="H1" CssClass="CommonTitle" ContainerID="UserName" />
would render
Ben
wrapped in an H1 tag with a CSS class name of "CommonTitle" and an ID of "UserName".
To define more complicated mark-up, all Chameleon controls support a “LeaderTemplate” and “TrailerTemplate” that is rendered before (leader) and after (trailer) the content of the control, for example:
<CSControl:UserData runat=”server” Property=”DisplayName” LinkTo=”Profile”>
<LeaderTemplate>
<div id=”UserArea”>
<h2 style=”color: #ff0000; font-size: 200%;”>
</LeaderTemplate>
<TrailerTemplate>
</h2>
</div>
</TrailerTemplate>
</CSControl:UserData>
would render the DisplayName of the current user linked to the user’s profile wrapped in the defined leading and trailing HTML. Note that “LeaderTemplate” and “TrailerTemplate” is only rendered if the control is rendered—so if the theme developer defined “DisplayConditions” on the UserData control, the leading and trailing HTML, along with the control’s content, would only render if the conditions evaluated to true.
- Removal of theme inheritance
An often unused and potentially confusing feature of CS2.1 and earlier was theme inheritance. If a theme did not define a required skin file, CS2.1 and earlier would load the skin file from the default theme. This no longer occurs.
All themes in Chameleon are required to be complete. This makes each theme easier to refine and more portable. To distribute a Chameleon theme, only the contents of the web/theme/[THEME_NAME] folder need to be copied and there are no external dependencies (unless the theme developer creates additional dependencies).
- Separation of the control panel
The Control Panel is now completely separated from the site theme--all of the master pages, styles, images, etc required by the Control Panel are now contained within web/ControlPanel. Theme developers no longer need to separate the Control Panel manually or design themes that will support both the front-end site as well as the back-end Control Panel.
These are the major differences between theming in CS2.1 and CS2007. In my next Chameleon article, I will start talking about the base Chameleon controls.
If you have any questions regarding Chameleon, please send them to me via my contact form or add a comment. I will answer all of the questions in the final post in this series.