<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.getben.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.getben.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Ben Tiedt's Blog</title><link>http://getben.com/default.aspx</link><description>News about my work on Community Server and development in ASP.Net, C#, XHTML, CSS, JavaScript, and AJAX.</description><dc:language>en</dc:language><generator>CommunityServer 2008 SP1 (Build: 30619.63)</generator><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.getben.com/BenTiedt" type="application/rss+xml" /><item><title>Community Server 2008 Hack-a-thon</title><link>http://feeds.getben.com/~r/BenTiedt/~3/286860392/community-server-2008-hack-a-thon.aspx</link><pubDate>Fri, 09 May 2008 14:26:00 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6859</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6859</wfw:commentRss><comments>http://getben.com/archive/2008/05/09/community-server-2008-hack-a-thon.aspx#comments</comments><description>&lt;p&gt;One of the fun benefits of working for &lt;a href="http://telligent.com/"&gt;Telligent&lt;/a&gt; is the ability to participate in regular &amp;quot;hack-a-thon&amp;quot; contests.&amp;nbsp; These contests usually involve working with a new feature or product and result in great prizes!&lt;/p&gt;
&lt;p&gt;Last week, while the Community Server team was in Dallas, we had a hack-a-thon to make cool products using the new REST API in &lt;a href="http://communityserver.com/"&gt;Community Server 2008&lt;/a&gt; in less than 20 hours (the contest started at 3PM and ended at 10AM the next day).&amp;nbsp; There were a lot of great entries and everyone showed what they had made the next day.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;My entry was the &lt;a href="http://www.screencast.com/t/rnHi03StiX"&gt;Print/Send to Media Gallery application&lt;/a&gt; which makes it easy to get documents of any type into a CS media gallery.&lt;/p&gt;
&lt;p&gt;See more about &lt;a href="http://communityserver.com/news/team-blog/community-server-hack-a-thon/"&gt;the latest hack-a-thon on the&amp;nbsp;Community Server&amp;nbsp;site&lt;/a&gt;...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6859" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/286860392" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Software+Development/default.aspx">Software Development</category><category domain="http://getben.com/tags/Telligent/default.aspx">Telligent</category><category domain="http://getben.com/tags/CS2008/default.aspx">CS2008</category><feedburner:origLink>http://getben.com/archive/2008/05/09/community-server-2008-hack-a-thon.aspx</feedburner:origLink></item><item><title>What is a Good Online Video Service for Screencasts?</title><link>http://feeds.getben.com/~r/BenTiedt/~3/286131063/what-is-a-good-online-video-service-for-screencasts.aspx</link><pubDate>Thu, 08 May 2008 14:59:00 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6844</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6844</wfw:commentRss><comments>http://getben.com/archive/2008/05/08/what-is-a-good-online-video-service-for-screencasts.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;d like to start posting more video-based demonstrations and walk-throughs of theming and customizing &lt;a href="http://communityserver.com/" class="null"&gt;Community Server&lt;/a&gt;, but I don&amp;#39;t really want to store the videos on my shared web host (and pay for storage and bandwidth).&lt;/p&gt;
&lt;p&gt;What is a good online video service for screencasts?&amp;nbsp; &lt;a href="http://blip.tv/"&gt;Blip.tv&lt;/a&gt;?&amp;nbsp; &lt;a href="http://vimeo.com/"&gt;Vimeo&lt;/a&gt;?&amp;nbsp; &lt;a href="http://www.veoh.com/"&gt;Veoh&lt;/a&gt;? Other?&lt;/p&gt;
&lt;p&gt;Please let me know in the comments.&amp;nbsp; Also, please let me know of any topics that you&amp;#39;d like me to cover.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6844" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/286131063" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Software+Development/default.aspx">Software Development</category><category domain="http://getben.com/tags/Theming/default.aspx">Theming</category><category domain="http://getben.com/tags/Reviews/default.aspx">Reviews</category><feedburner:origLink>http://getben.com/archive/2008/05/08/what-is-a-good-online-video-service-for-screencasts.aspx</feedburner:origLink></item><item><title>Community Server 2008 - Groups Overview</title><link>http://feeds.getben.com/~r/BenTiedt/~3/284203228/community-server-2008-groups-overview.aspx</link><pubDate>Mon, 05 May 2008 21:35:55 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6802</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>20</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6802</wfw:commentRss><comments>http://getben.com/archive/2008/05/05/community-server-2008-groups-overview.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://communityserver.com/"&gt;Community Server&lt;/a&gt; 2008 includes a new feature, Groups.&amp;nbsp; Groups are miniature community sites within the larger community site, similar to Google- or Yahoo-groups.&amp;nbsp; Each Group has its own content, membership, and permissions.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;What&amp;#39;s in a Group?&lt;/h2&gt; &lt;p&gt;A group can contain a single blog, single media gallery, single forum, and can also contain &amp;quot;pages.&amp;quot;&amp;nbsp; The blog, media gallery, and forum can be individual enabled by the group owner.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The blog, media gallery, and forum behave exactly the same as the non-grouped versions of these applications with the exception that they are completely managed outside of the Community Server Control Panel.&amp;nbsp; These applications, instead, expose their management and moderation options through the group&amp;#39;s pages and navigation options.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;How is a Group Created?&lt;/h2&gt; &lt;p&gt;By default, only system administrators can create groups, however, group creation can be enabled for any registered user of the Community Server site via the Group Administration control panel.&amp;nbsp; When a user is in a role that is granted the permission to create a group, that user can click the &amp;quot;Create a Group&amp;quot; link in the sidebar of the &amp;quot;Groups&amp;quot; home page to immediately create a group.&lt;/p&gt; &lt;p&gt;System and Group administrators can also create, edit, and delete groups via the Group Administration Control Panel.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Public/Private and Membership Options&lt;/h2&gt; &lt;p&gt;Groups can be defined to be &amp;quot;Public (Open Membership)&amp;quot;, &amp;quot;Public (Closed Membership)&amp;quot;, or &amp;quot;Private&amp;quot;.&amp;nbsp; &lt;/p&gt; &lt;h3&gt;Public (Open Membership)&lt;/h3&gt; &lt;p&gt;Public groups can be viewed by users who are not members of the group, however, non-members cannot post new content or reply to existing content.&amp;nbsp; When the membership is &amp;quot;Open&amp;quot;, any user of the Community Server site can choose to become a member without being approved by the owner of the group.&amp;nbsp; Membership is granted immediately.&lt;/p&gt; &lt;h3&gt;Public (Closed Membership)&lt;/h3&gt; &lt;p&gt;Just as with &amp;quot;Public (Open Membership)&amp;quot; groups, &amp;quot;Public (Closed Membership)&amp;quot; groups can be viewed by users who are not members of the group.&amp;nbsp; When membership is set to &amp;quot;Closed&amp;quot;, however, users must request membership and be approved by the owner of the group before becoming a member of the group.&lt;/p&gt; &lt;h3&gt;Private&lt;/h3&gt; &lt;p&gt;Private groups and their content cannot be seen by non-members.&amp;nbsp; New members can only be added by owners of the group who either add the new member manually, or invite the new member by their email address.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Group Membership Types and Permissions&lt;/h2&gt; &lt;p&gt;Within a group, there are four types of users: non-members, members, managers, and owners.&amp;nbsp; Each membership type is associated to a specific set of permissions within the group.&lt;/p&gt; &lt;h3&gt;Non-Members&lt;/h3&gt; &lt;p&gt;In private groups, non-members cannot view or interact with any content.&lt;/p&gt; &lt;p&gt;In public groups, non-members can view (but not interact) with the group&amp;#39;s content.&lt;/p&gt; &lt;h3&gt;Members&lt;/h3&gt; &lt;p&gt;Members can view and reply to existing content (blog posts, media files, forum threads) and view pages.&amp;nbsp; If enabled (via the &amp;quot;Edit Group&amp;quot; form), members may also be able to start new forum discussions or post their own media files.&lt;/p&gt; &lt;h3&gt;Managers&lt;/h3&gt; &lt;p&gt;Managers can do everything that regular members can, with the addition of: posting new pages and editing/deleting their own pages, posting/editing/deleting blog posts, starting new forum discussions (including sticky posts, announcements, polls, and video), editing/deleting any forum posts, moderating forum posts, posting/editing/deleting media files, and moderating media files.&lt;/p&gt; &lt;h3&gt;Owners&lt;/h3&gt; &lt;p&gt;Owners can do everything that managers can, with the addition of: editing the group, editing the group&amp;#39;s theme, adding/removing members, and editing any pages.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Theming Groups&lt;/h2&gt; &lt;p&gt;Each group can be individually themed (similar to blogs).&amp;nbsp; The owner of each group can select a theme for the group and configure any options exposed by that theme via the &amp;quot;Edit Group Theme&amp;quot; link in the administrative sidebar of the group.&lt;/p&gt; &lt;h3&gt;Customizing Group Themes&lt;/h3&gt; &lt;p&gt;The group-related themes are located in the web/themes/hubs/ folder (groups are called hubs within the API and themes).&amp;nbsp; Within theme files, the same &lt;a href="http://getben.com/Documentation/CS2008/Chameleon/ControlList.aspx?tagprefix=CSMedia"&gt;&amp;lt;CSMedia:&lt;/a&gt;, &lt;a href="http://getben.com/Documentation/CS2008/Chameleon/ControlList.aspx?tagprefix=CSForum"&gt;&amp;lt;CSForum:&lt;/a&gt;, and &lt;a href="http://getben.com/Documentation/CS2008/Chameleon/ControlList.aspx?tagprefix=CSBlog"&gt;&amp;lt;CSBlog:&lt;/a&gt; controls used for media gallery, forum, and blog content outside of groups can be used within the group to reference the group&amp;#39;s content from these application types.&amp;nbsp; Additionally, the &lt;a href="http://getben.com/Documentation/CS2008/Chameleon/ControlList.aspx?tagprefix=CSHub"&gt;&amp;lt;CSHub:&lt;/a&gt; control prefix is used to identify group/hub-specific data and functionality.&lt;/p&gt; &lt;p&gt;For more specific information about group-related controls, see the &lt;a href="http://getben.com/Documentation/CS2008/Chameleon/default.aspx"&gt;Chameleon documentation&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This was a quick overview of the features, permissions, and theming options of groups.&amp;nbsp; Please ask any questions in the comments.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6802" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/284203228" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Software+Development/default.aspx">Software Development</category><category domain="http://getben.com/tags/Theming/default.aspx">Theming</category><category domain="http://getben.com/tags/Chameleon/default.aspx">Chameleon</category><category domain="http://getben.com/tags/CS2008/default.aspx">CS2008</category><feedburner:origLink>http://getben.com/archive/2008/05/05/community-server-2008-groups-overview.aspx</feedburner:origLink></item><item><title>Dynamic Navigation Add On for Community Server</title><link>http://feeds.getben.com/~r/BenTiedt/~3/278310017/dynamic-navigation-add-on-for-community-server.aspx</link><pubDate>Sat, 26 Apr 2008 15:04:00 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6706</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>21</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6706</wfw:commentRss><comments>http://getben.com/archive/2008/04/26/dynamic-navigation-add-on-for-community-server.aspx#comments</comments><description>&lt;p&gt;Common requests for new users of &lt;a href="http://communityserver.com/"&gt;Community Server&lt;/a&gt; are &amp;quot;how do I edit the navigation bar?&amp;quot;, &amp;quot;how do I add a second level of navigation items?&amp;quot;, and &amp;quot;how do I add drop-down menus to the navigation items?&amp;quot;&amp;nbsp; In all of these cases, changes are required to a few config files, some additional javascript needs to be added, and, even then, the items are only editable by modifying the theme files.&amp;nbsp; To make these changes/scenarios easier, I&amp;#39;ve implemented a new add-on for Community Server 2007 and 2008: &lt;a href="http://getben.com/media/p/6705.aspx"&gt;Dynamic Navigation Support&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This add-on extends the dynamic theme configuration support included in CS2007 and CS2008 to add support for editing the navigation items through the control panel.&amp;nbsp; It supports the following scenarios:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A single row of navigation items &lt;/li&gt;
&lt;li&gt;Multiple rows of navigation items &lt;/li&gt;
&lt;li&gt;One or more rows of navigation items and drop-down sub-navigation items &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Another related request is &amp;quot;how do I add new content pages to Communtiy Server?&amp;quot;&amp;nbsp; With this add-on installed, new site articles can be created and added to the navigation bar via this add-on&amp;nbsp;-- all without any additional editing of theme files!&lt;/p&gt;
&lt;p&gt;If you&amp;#39;ve wanted to implement any of these scenarios, this add-on makes it very simple (after a few setup steps... instructions are included in the download).&amp;nbsp; &lt;a href="http://getben.com/media/p/6705.aspx"&gt;Give it a shot&lt;/a&gt; and let me know what you think in the comments.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note that this is not an official Telligent product and is provided as-is.&amp;nbsp; Questions should be directed to me directly on this site.&lt;/em&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6706" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/278310017" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Theming/default.aspx">Theming</category><category domain="http://getben.com/tags/Dynamic+Configuration/default.aspx">Dynamic Configuration</category><category domain="http://getben.com/tags/CS2008/default.aspx">CS2008</category><category domain="http://getben.com/tags/CS2007/default.aspx">CS2007</category><feedburner:origLink>http://getben.com/archive/2008/04/26/dynamic-navigation-add-on-for-community-server.aspx</feedburner:origLink></item><item><title>Community Server 2008 - Centralized File System (CFS) Overview</title><link>http://feeds.getben.com/~r/BenTiedt/~3/277107733/community-server-2008-centralized-file-system-cfs-overview.aspx</link><pubDate>Thu, 24 Apr 2008 19:01:00 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6694</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6694</wfw:commentRss><comments>http://getben.com/archive/2008/04/24/community-server-2008-centralized-file-system-cfs-overview.aspx#comments</comments><description>&lt;p&gt;In Community Server 2007 and earlier versions, the many file-related features (post attachments, site files, blog files, avatars, role icons, etc) all implemented their own file management logic and supported (a) storing files in the database (b) storing files in the file system or (c) configurable options allowing file storage in the database and/or file system.&amp;nbsp; Adding new file-based features (in the core application or in add-ons) required implementing custom file management logic.&amp;nbsp; Database-based storage was the default for post attachments.&amp;nbsp; Write permissions needed to be granted in many locations within the CS application.&amp;nbsp; Storing files in external systems (such as Amazon S3) required modifications to the custom file management logic used for each file-based feature.&amp;nbsp; In general, there were some file management issues.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;In Community Server 2008, the Centralized File System (or Centralized File Storage or CFS) was implemented to centralize file management (so there was one instance of file management logic used for all file-based features), support file storage providers (so that new file storage services, such as Amazon S3, could be used to store files), and to make it generally easier to add file-based features to Community Server (both in the core product as well as in add-ons).&lt;/p&gt;
&lt;p&gt;The CFS sits deep in the Community Server API, between the API for file-based features and the configured storage providers:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="center"&gt;&lt;img border="0" width="699" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_3.png" alt="image" height="499" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="left"&gt;Interacting with individual file-based features has not changed (or changed very little) between CS2007 and CS2008.&amp;nbsp; The individual file-based features, however, use the CFS instead of their own custom file management logic.&lt;/p&gt;
&lt;p align="left"&gt;In general, users and developers will not directly interact with the CFS.&amp;nbsp; Only when new file-based functionality must be implemented is direct access to the CFS required.&amp;nbsp; For example, to add/update/delete post attachments and their content, code should not access the CFS, but should instead access the add/update/delete methods of the &lt;span style="font-family:courier new,courier;"&gt;PostAttachments&lt;/span&gt; class (which themselves interact with the CFS file store for post attachments).&amp;nbsp; When implementing a new feature, such as video transcoding, it may be useful to have a new file store and interact with the CFS directly as a new file-based feature.&lt;/p&gt;
&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;CFS Terminology&lt;/h2&gt;
&lt;p align="left"&gt;The CFS uses file store keys, paths, and filenames to store files:&lt;/p&gt;
&lt;h3&gt;File Store Key&lt;/h3&gt;
&lt;p align="left"&gt;The file store key is the name identified on the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;fileStore /&amp;gt;&lt;/span&gt; node representing the file store in the communityserver.config file (defined later).&amp;nbsp; It represents a unique set of files that are managed independently of other file stores.&lt;br /&gt;&lt;br /&gt;File store keys must be between 3 and 255 characters and cannot contain any characters that are not valid in windows file system paths.&lt;/p&gt;
&lt;h3&gt;Path&lt;/h3&gt;
&lt;p align="left"&gt;Paths are similar to directories, but are technically used more like keys.&amp;nbsp; Paths can represent multiple values separated by periods (the period is used for defining sub-paths and is also programmatically accessible via the &lt;span style="font-family:courier new,courier;"&gt;CentralizedFileSystemProvider.DirectorySeparator&lt;/span&gt; property).&amp;nbsp; For example, a common file system path may be &amp;quot;my\files\are\here&amp;quot; and the similar CFS path would be &amp;quot;my.files.are.here&amp;quot;&lt;br /&gt;&lt;br /&gt;There is a technical difference between directories and CFS paths, however.&amp;nbsp; When querying for files in a directory, files are generally accessed within a single folder, &amp;quot;my\files\are&amp;quot; for example.&amp;nbsp; In the CFS, because paths are treated as keys, files can also be accessed using partial paths, such as &amp;quot;my.files.a&amp;quot;, which would match files in the &amp;quot;my.files.are&amp;quot; path as well as the &amp;quot;my.files.and&amp;quot; and &amp;quot;my.files.any&amp;quot; paths.&lt;br /&gt;&lt;br /&gt;Paths must be between 0 and 769 characters and cannot contain any characters that are not valid in windows file system paths.&lt;/p&gt;
&lt;h3&gt;Filename&lt;/h3&gt;
&lt;p align="left"&gt;Filenames are the names of the files stored in the CFS.&amp;nbsp; They must be between 1 and 255 characters in length and must not contain any characters that are invalid in window file system file names.&lt;/p&gt;
&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;File Stores in the CFS&lt;/h2&gt;
&lt;p align="left"&gt;Each file-based feature can use one or more &amp;quot;file stores&amp;quot; in the CFS.&amp;nbsp; Each file store is defined within the communityserver.config file by a &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;fileStore /&amp;gt;&lt;/span&gt; node within the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CentralizedFileStorage /&amp;gt;&lt;/span&gt; node.&amp;nbsp; &lt;/p&gt;
&lt;p align="left"&gt;Each file store must define two attributes: &lt;span style="font-family:courier new,courier;"&gt;name&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;type&lt;/span&gt;.&amp;nbsp; Additionally, the &lt;span style="font-family:courier new,courier;"&gt;downloadValidatorType&lt;/span&gt; attribute can optionally be set.&lt;/p&gt;
&lt;h3&gt;name&lt;/h3&gt;
&lt;p align="left"&gt;The &lt;span style="font-family:courier new,courier;"&gt;name&lt;/span&gt; attribute defines the name of the file store (also referred to as the file store key) -- this is how the code used to implement file-based features will identify the file store when it interacts with the CFS.&amp;nbsp; &lt;/p&gt;
&lt;h3&gt;type&lt;/h3&gt;
&lt;p align="left"&gt;The &lt;span style="font-family:courier new,courier;"&gt;type&lt;/span&gt; attribute identifies the CFS file storage provider to use to store files for the file store.&amp;nbsp; &lt;/p&gt;
&lt;p align="left"&gt;CFS file storage providers are .net classes that inherit and implement the &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.CentralizedFileStorageProvider&lt;/span&gt; base class (in the CommunityServer.Components.dll assembly).&amp;nbsp; Community Server 2008 ships with two CFS file storage providers: &lt;span style="font-family:courier new,courier;"&gt;AmazonS3FileStorageProvider&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;FileSystemFileStorageProvider&lt;/span&gt;. &lt;/p&gt;
&lt;p align="left"&gt;Each file store can define its own file storage provider, with its own configuration.&amp;nbsp; For example, post attachments could be stored in Amazon S3 but user avatars could be stored in the local file system.&amp;nbsp; By default, CS2008 uses the file system file storage provider for all file stores and stores files in the &amp;quot;filestorage/&amp;quot; folder.&lt;/p&gt;
&lt;h3&gt;downloadValidatorType&lt;/h3&gt;
&lt;p align="left"&gt;Each file store can optionally identify a download validator.&amp;nbsp; A download validator is a .net class that implements the &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.ICentralizedFileAccessValidator&lt;/span&gt; interface (in the CommunityServer.Components.dll assembly).&amp;nbsp; &lt;/p&gt;
&lt;p align="left"&gt;A download validator is used to implement logic that identifies, for the file store, whether a file should be allowed to be accessed or not.&amp;nbsp; In CS2008, only post attachments identify a download validator -- it is used to ensure that users have view and/or read permission to the attachment&amp;#39;s associated post before allowing the attachment to be downloaded.&lt;/p&gt;
&lt;h3&gt;Additional Attributes&lt;/h3&gt;
&lt;p align="left"&gt;Each provider requires additional attributes to be defined on the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;fileStore /&amp;gt;&lt;/span&gt; node.&amp;nbsp; These additional attributes are documented in the comments just above the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CentralizedFileStorage /&amp;gt;&lt;/span&gt; node in the communityserver.config file included with Community Server 2008.&lt;/p&gt;
&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Creating New CFS File Stores&lt;/h2&gt;
&lt;p align="left"&gt;Creating a new CFS file store is as simple as adding a new &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;fileStore /&amp;gt;&lt;/span&gt; node to the &amp;lt;CentralizedFileStorage /&amp;gt; node of the communityserver.config file with a new name.&amp;nbsp; When the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;fileStore /&amp;gt;&lt;/span&gt; node exists, that file store can be used to add/delete/query files.&lt;/p&gt;
&lt;p align="left"&gt;The existing file stores are named according to the full name of the class in the Community Server API that interacts with the file store.&amp;nbsp; For example, post attachments are created/updated/deleted via the &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.PostAttachments&lt;/span&gt; class in the CS API so the CFS file store used to store post attachment files is named &amp;quot;CommunityServer.Components.PostAttachments.&amp;quot;&amp;nbsp; I would suggest continuing this naming convention when adding additional file stores to the CFS.&lt;/p&gt;
&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Coding Against a CFS File Store&lt;/h2&gt;
&lt;p align="left"&gt;When implementing new file-based features for Community Server, I strongly suggest using the CFS for file storage.&amp;nbsp; The CFS provides a simple API for adding, deleting and querying files and paths. &lt;/p&gt;
&lt;p align="left"&gt;The following methods are exposed by the CFS (and must be supported by all CFS providers):&amp;nbsp; &lt;span style="font-family:courier new,courier;"&gt;GetFile&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;GetFiles&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;GetPaths&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;AddPath&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;AddUpdateFile&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;Delete&lt;/span&gt;.&amp;nbsp; &lt;/p&gt;
&lt;p align="left"&gt;To interact with these methods, code must first retrieve the file storage provider for a specific file store.&amp;nbsp; This is done using the file store key, as in:&lt;/p&gt;
&lt;p align="left"&gt;&lt;span style="font-family:courier new,courier;"&gt;CentralizedFileSystemProvider myFileStore = CentralizedFileSystemProvider.Instance(&amp;quot;FILE_STORE_KEY&amp;quot;);&lt;/span&gt;&lt;/p&gt;
&lt;p align="left"&gt;Which would load the file storage provider for the &amp;quot;FILE_STORE_KEY&amp;quot; file store (note that there must be a corresponding &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;fileStore /&amp;gt;&lt;/span&gt; node in the communityserver.config file named &amp;quot;FILE_STORE_KEY&amp;quot;, otherwise, the &lt;span style="font-family:courier new,courier;"&gt;Instance&lt;/span&gt; method will return &lt;span style="font-family:courier new,courier;"&gt;null&lt;/span&gt;).&amp;nbsp; The file management methods could then be called on the &lt;span style="font-family:courier new,courier;"&gt;myFileStore&lt;/span&gt; object.&amp;nbsp; Any operations preformed using the &lt;span style="font-family:courier new,courier;"&gt;myFileStore&lt;/span&gt; object would be performed within the context of the file store named &amp;quot;FILE_STORE_KEY&amp;quot;.&lt;/p&gt;
&lt;h3&gt;ICentralizedFile GetFile(string path, string fileName)&lt;/h3&gt;
&lt;p align="left"&gt;Gets the file store&amp;#39;s provider&amp;#39;s implementation of the &lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile&lt;/span&gt; interface representing the file with the given path and file name.&amp;nbsp; If the file is not found, the &lt;span style="font-family:courier new,courier;"&gt;GetFile&lt;/span&gt; method will return &lt;span style="font-family:courier new,courier;"&gt;null&lt;/span&gt;.&lt;/p&gt;
&lt;p align="left"&gt;&lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile&lt;/span&gt; file is an abstract representation of a file and supports retrieving the &lt;span style="font-family:courier new,courier;"&gt;ContentLength&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;FileName&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;Path&lt;/span&gt;, and &lt;span style="font-family:courier new,courier;"&gt;FileStoreKey&lt;/span&gt; of the file and also supports retrieving a stream of the content of the file (via the &lt;span style="font-family:courier new,courier;"&gt;OpenReadStream&lt;/span&gt; method) and getting a URL to download a file (via the &lt;span style="font-family:courier new,courier;"&gt;GetDownloadUrl&lt;/span&gt; method).&lt;/p&gt;
&lt;h3&gt;List&amp;lt;ICentralizedFile&amp;gt; GetFiles(PathSearchOption searchOption)&lt;/h3&gt;
&lt;h3&gt;List&amp;lt;ICentralizedFile&amp;gt; GetFiles(string path, PathSearchOption searchOption)&lt;/h3&gt;
&lt;p align="left"&gt;Gets a list of files for the given path matching the defined search option (&lt;span style="font-family:courier new,courier;"&gt;TopLevelPathOnly&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;AllPaths&lt;/span&gt;).&amp;nbsp; When using the &lt;span style="font-family:courier new,courier;"&gt;TopLevelPathOnly&lt;/span&gt; search option, the file store works like a file system.&amp;nbsp; When using the &lt;span style="font-family:courier new,courier;"&gt;AllPaths&lt;/span&gt; search option, the file store works more like a key-based system.&amp;nbsp; &lt;/p&gt;
&lt;p align="left"&gt;Note that paths are technically keys, not directories.&amp;nbsp; If I have a file in the path &amp;quot;my.files.are.here&amp;quot;, the file can be retrieved from the path &amp;quot;my.files&amp;quot; or &amp;quot;my.fil&amp;quot; when using the &lt;span style="font-family:courier new,courier;"&gt;AllPaths&lt;/span&gt; search option.&lt;/p&gt;
&lt;h3&gt;List&amp;lt;string&amp;gt; GetPaths()&lt;/h3&gt;
&lt;h3&gt;List&amp;lt;string&amp;gt; GetPaths(string path)&lt;/h3&gt;
&lt;p align="left"&gt;Gets a list of paths within the defined path.&amp;nbsp; Omitting the path will retrieve all top-level paths.&amp;nbsp; Paths are separated using periods (identified by the &lt;span style="font-family:courier new,courier;"&gt;CentralizedFileSystemProvider.DirectorySeparator&lt;/span&gt; property).&lt;/p&gt;
&lt;h3&gt;void AddPath(string path)&lt;/h3&gt;
&lt;p align="left"&gt;Adds a path.&amp;nbsp; &lt;/p&gt;
&lt;p align="left"&gt;There is no concept of &amp;quot;parent&amp;quot; folder and &amp;quot;child&amp;quot; folder, instead, paths are treated as keys.&amp;nbsp; So I could add a path named &amp;quot;my.files.are.here&amp;quot; just as easily as incrementally adding &amp;quot;my&amp;quot; then &amp;quot;my.files&amp;quot; then &amp;quot;my.files.are&amp;quot; and finally &amp;quot;my.files.are.here&amp;quot;.&amp;nbsp; The CFS will handle either case.&amp;nbsp; &lt;/p&gt;
&lt;h3&gt;ICentralizedFile AddUpdateFile(string path, string fileName, Stream contentStream)&lt;/h3&gt;
&lt;p align="left"&gt;Adds or updates a file to the file store.&amp;nbsp; If a file with the same &lt;span style="font-family:courier new,courier;"&gt;path&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;fileName&lt;/span&gt; already exists, it is overwritten.&amp;nbsp; The path does not need to be manually created.&lt;/p&gt;
&lt;h3&gt;void Delete()&lt;/h3&gt;
&lt;h3&gt;void Delete(string path)&lt;/h3&gt;
&lt;h3&gt;void Delete(string path, string fileName)&lt;/h3&gt;
&lt;p align="left"&gt;Deletes a file or path.&amp;nbsp; If the path is omitted, all paths and files are deleted from the file store.&lt;/p&gt;
&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Implementing New CFS File Storage Providers&lt;/h2&gt;
&lt;p align="left"&gt;New CFS file storage providers can be implemented by inheriting from the &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.CentralizedFileStorageProvider&lt;/span&gt;.&amp;nbsp; A few notes regarding implementing custom CFS storage providers:&lt;/p&gt;
&lt;ol&gt;
&lt;li style="margin-bottom:1em;"&gt;
&lt;div align="left"&gt;&lt;strong&gt;Are You Sure?&lt;/strong&gt;&lt;br /&gt;New CFS file storage providers do not need to be implemented to store file in the CFS.&amp;nbsp; Only when you want to store files outside of the file system or Amazon S3 will a new file storage provider be required.&lt;/div&gt;
&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;
&lt;div align="left"&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;br /&gt;Because the creation of new CFS file storage providers should be rare, I&amp;#39;m not going to list all of the considerations in this article.&amp;nbsp; Instead, I would suggest reviewing the notes and comments in the &lt;span style="font-family:courier new,courier;"&gt;CentralizedFileSystemProvider&lt;/span&gt; class in the CS2008 SDK and the two included implementations for specific information and implementation guidelines for each method.&lt;/div&gt;
&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;
&lt;div align="left"&gt;&lt;strong&gt;ICentralizedFile&lt;/strong&gt;&lt;br /&gt;Each &lt;span style="font-family:courier new,courier;"&gt;CentralizedFileSystemProvider&lt;/span&gt; must also implement the &lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile&lt;/span&gt; interface and support reading files as a stream (via the &lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile.OpenReadStream&lt;/span&gt; method) and downloading files via a URL (via the &lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile.GetDownloadUrl&lt;/span&gt; method).&amp;nbsp; All CFS functionality should be fully implemented to support all of the ways a file store can be used.&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;General CFS Notes&lt;/h2&gt;
&lt;p align="left"&gt;A few general notes about using the CFS in CS2008:&lt;/p&gt;
&lt;ol&gt;
&lt;li style="margin-bottom:1em;"&gt;
&lt;div align="left"&gt;&lt;strong&gt;Avoid Publishing the ICentralizedFile.GetDownloadUrl()&lt;/strong&gt;&lt;br /&gt;In general, the &lt;span style="font-family:courier new,courier;"&gt;CentralizedFileStorageProvider.GetGenericDownloadUrl(ICentralizedFile)&lt;/span&gt; method should be used when rendering download links to a file.&amp;nbsp; The URL generated by this method is generic and, when accessed, will determine the current file storage provider for the file and redirect to it.&amp;nbsp; This will allow the storage provider to be changed without having to update all existing links to files (since &lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile.GetDownloadUrl()&lt;/span&gt; would otherwise return a storage-provider-specific URL that would not be valid when the storage provider is changed).&lt;/div&gt;
&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;
&lt;div align="left"&gt;&lt;strong&gt;Avoid Calling ICentralizedFile.OpenReadStream()&lt;/strong&gt;&lt;br /&gt;Whenever possible, render a URL and don&amp;#39;t read the contents of the file.&amp;nbsp; In most cases, a URL can be rendered to a user instead of reading a file and writing it manually.&amp;nbsp; In some cases, however, this is not possible... such as when resizing an image.&lt;/div&gt;
&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;
&lt;div align="left"&gt;&lt;strong&gt;When a URL is really a CFS-stored File&lt;/strong&gt;&lt;br /&gt;When processing URLs, the &lt;span style="font-family:courier new,courier;"&gt;CentralizedFileStorageProvider&lt;/span&gt; class exposes a few static methods that can help to translate a URL into a CFS-stored &lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile&lt;/span&gt;:&amp;nbsp; &lt;span style="font-family:courier new,courier;"&gt;bool IsCentralizedFile(string url) &lt;/span&gt;and &lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile GetCentralizedFileByUrl(string url)&lt;/span&gt;.&amp;nbsp; These methods can be used to detect and retrieve CFS files by their URL.&amp;nbsp; Note that these methods only work with URLs generated by the &lt;span style="font-family:courier new,courier;"&gt;CentralizedFileStorageProvider.GetGenericDownloadUrl&lt;/span&gt; method.&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="left"&gt;Questions? Comments?&amp;nbsp; It was a long article... feel free to ask in the comments.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6694" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/277107733" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Software+Development/default.aspx">Software Development</category><category domain="http://getben.com/tags/Centralized+File+System/default.aspx">Centralized File System</category><category domain="http://getben.com/tags/CS2008/default.aspx">CS2008</category><feedburner:origLink>http://getben.com/archive/2008/04/24/community-server-2008-centralized-file-system-cfs-overview.aspx</feedburner:origLink></item><item><title>Community Server 2008 - Implementing Custom File Viewers</title><link>http://feeds.getben.com/~r/BenTiedt/~3/276191623/community-server-2008-implementing-custom-file-viewers.aspx</link><pubDate>Wed, 23 Apr 2008 14:13:00 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6680</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6680</wfw:commentRss><comments>http://getben.com/archive/2008/04/23/community-server-2008-implementing-custom-file-viewers.aspx#comments</comments><description>&lt;p&gt;File viewers are the unsung heroes that make Community Server 2008 media-friendly.&amp;nbsp; They implement the support for viewing and resizing images, viewing uploaded and remote video files, viewing video from online video services, and playing uploaded and remote audio clips.&amp;nbsp; Without file viewers, the media gallery would be the file gallery from CS2007.&lt;/p&gt;
&lt;p&gt;File viewers are supported when rendering post attachments or by using the &amp;quot;Insert Media&amp;quot; toolbar item in the content editor for blog/media/forum posts, content parts, announcements, profile comments, conversation messages, user biographies, group descriptions, user signatures, HTML-based dynamic configuration properties, and the &amp;quot;Generic Content&amp;quot; widget.&lt;/p&gt;
&lt;p&gt;New file viewers can be easily implemented to support new or additional file types or rendering methods.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Implementing Custom File Viewers&lt;/h2&gt;
&lt;p&gt;File viewers are .net classes that implement the &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.IFileViewer&lt;/span&gt; interface.&amp;nbsp; This interface defines only two methods (with two variations each): &lt;span style="font-family:courier new,courier;"&gt;Render&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;GetMediaType&lt;/span&gt;.&amp;nbsp; The &lt;span style="font-family:courier new,courier;"&gt;Render&lt;/span&gt; method is used to render a provided file or URL and the &lt;span style="font-family:courier new,courier;"&gt;GetMediaType&lt;/span&gt; is used to retrieve the type of content that will be generated when a file or URL is rendered.&lt;/p&gt;
&lt;h3&gt;string Render(ICentralizedFile file, FileViewType viewType, int width, int height)&lt;/h3&gt;
&lt;h3&gt;string Render(Uri url, FileViewType viewType, int width, int height)&lt;/h3&gt;
&lt;p&gt;The &lt;span style="font-family:courier new,courier;"&gt;Render&lt;/span&gt; method is called to get the HTML markup used to render a file or URL configured to be viewed by this file viewer.&amp;nbsp; For local files, an &lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile&lt;/span&gt;-implementing object will be provided that represents a file in the Centralized File System.&amp;nbsp; For URLs, the &lt;span style="font-family:courier new,courier;"&gt;Uri&lt;/span&gt; object representing the URL is provided.&amp;nbsp; For both local files and URLs, the type of view (&lt;span style="font-family:courier new,courier;"&gt;Preview&lt;/span&gt; or &lt;span style="font-family:courier new,courier;"&gt;View&lt;/span&gt;) and the requested width and height (in pixels) is provided.&amp;nbsp; &lt;/p&gt;
&lt;h3&gt;PostMediaType GetMediaType(ICentralizedFile file, FileViewType viewType)&lt;/h3&gt;
&lt;h3&gt;PostMediaType GetMediaType(Uri url, FileViewType viewType)&lt;/h3&gt;
&lt;p&gt;The &lt;span style="font-family:courier new,courier;"&gt;GetMediaType&lt;/span&gt; method is used by Community Server to determine what type of media will be rendered for a given view of a file.&amp;nbsp; The returned value is from the &lt;span style="font-family:courier new,courier;"&gt;PostMediaType&lt;/span&gt; enumeration (&lt;span style="font-family:courier new,courier;"&gt;Empty&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;Image&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;Video&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;Audio&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;Poll&lt;/span&gt;).&amp;nbsp; This value is used to set the &lt;span style="font-family:courier new,courier;"&gt;PostMedia&lt;/span&gt; property of posts based on the files referenced within the post and/or the post attachment and can also be used to perform conditional formatting via the post-attachment-related view condition controls in Chameleon.&lt;/p&gt;
&lt;p&gt;I&amp;#39;d suggest downloading the Community Server 2008 SDK and looking at the existing file viewers for examples of file viewer implementations.&amp;nbsp; The existing viewers all exist in the Components/UI folder and use file names ending in &amp;quot;FileViewer.&amp;quot;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Registering Custom File Viewers&lt;/h2&gt;
&lt;p&gt;All file viewers are registered with Community Server in the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;FileViewers&amp;gt;&lt;/span&gt; region of the communityserver.config file.&amp;nbsp; Each file viewer requires an &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;add /&amp;gt;&lt;/span&gt; node such as the following (which is used for the image file viewer):&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;add &lt;br /&gt;&amp;nbsp; type=&amp;quot;CommunityServer.Components.ImageFileViewer, CommunityServer.Components&amp;quot;&lt;br /&gt;&amp;nbsp; extensions=&amp;quot;gif;jpg;jpeg;bmp;png&amp;quot;&lt;br /&gt;&amp;nbsp; urlPattern=&amp;quot;^[^\?]*?\.(?:gif|jpg|jpeg|bmp|png)(?:\?.*)?$&amp;quot;&lt;br /&gt;&amp;nbsp; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In this example, all three supported attributes to the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;add /&amp;gt;&lt;/span&gt; node are shown: &lt;span style="font-family:courier new,courier;"&gt;type&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;extensions&lt;/span&gt;, and &lt;span style="font-family:courier new,courier;"&gt;urlPattern&lt;/span&gt;.&lt;/p&gt;
&lt;h3&gt;type&lt;/h3&gt;
&lt;p&gt;The &lt;span style="font-family:courier new,courier;"&gt;type&lt;/span&gt; attribute identifies the class implementing the &lt;span style="font-family:courier new,courier;"&gt;IFileViewer&lt;/span&gt; interface that should be registered.&amp;nbsp; In this case, its the &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.ImageFileViewer&lt;/span&gt; class in the &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components&lt;/span&gt; assembly.&amp;nbsp; &lt;/p&gt;
&lt;h3&gt;extensions&lt;/h3&gt;
&lt;p&gt;The &lt;span style="font-family:courier new,courier;"&gt;extensions&lt;/span&gt; attribute identifies the semi-colon-separated list of file extensions that are supported by this viewer.&amp;nbsp; Note that these extensions will only be matched to local files (those stored in the Centralized File System in Community Server 2008) and will not match to remote attachments or external URLs.&lt;/p&gt;
&lt;h3&gt;urlPattern&lt;/h3&gt;
&lt;p&gt;The &lt;span style="font-family:courier new,courier;"&gt;urlPattern&lt;/span&gt; identifies a regular expression that will match URLs that the file viewer can support.&amp;nbsp; In this case, the &lt;span style="font-family:courier new,courier;"&gt;ImageFileViewer&lt;/span&gt; identifies that it can render URLs that identify an image file extension. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;File Viewer Implementation Notes&lt;/h2&gt;
&lt;p&gt;The following are notes and guidelines regarding implementing file viewers:&lt;/p&gt;
&lt;ol&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;Width and Height are Suggestions&lt;/strong&gt;&lt;br /&gt;The width and height provided to the &lt;span style="font-family:courier new,courier;"&gt;IFileViewer.Render&lt;/span&gt; method should be treated as suggestions and/or not-to-exceed values.&amp;nbsp; For example, rending an audio clip at 400 pixels in height will probably not make sense.&amp;nbsp; Instead, as long as the audio clip fits within the suggested height, it could render at 32 pixels in height... which is a more reasonable value. &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;View and Preview Rendering&lt;/strong&gt;&lt;br /&gt;In general, when the &lt;span style="font-family:courier new,courier;"&gt;FileViewType.Preview&lt;/span&gt; is requested, a static and or quick-rendering version of the file should be displayed -- an image or icon, in general.&amp;nbsp; When the &lt;span style="font-family:courier new,courier;"&gt;FileViewType.View&lt;/span&gt; is requested, the full and/or interactive version of the file can be rendered -- a video player, audio player, &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;object /&amp;gt;&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;embed /&amp;gt;&lt;/span&gt;, etc. &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;File vs URL Support&lt;/strong&gt;&lt;br /&gt;File viewers do not need to support both File and URL-based files.&amp;nbsp; The &lt;span style="font-family:courier new,courier;"&gt;YouTubeFileViewer&lt;/span&gt;, for example, only supports URLs from YouTube.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;If a file viewer does not support local files, the &lt;span style="font-family:courier new,courier;"&gt;extensions&lt;/span&gt; attribute on its &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;add /&amp;gt;&lt;/span&gt; node in the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;FileViewers /&amp;gt;&lt;/span&gt; region of the communityserver.config file can be omitted and the &lt;span style="font-family:courier new,courier;"&gt;Render&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;GetMediaType&lt;/span&gt; methods that accept &lt;span style="font-family:courier new,courier;"&gt;ICentralizedFile&lt;/span&gt; objects can throw exceptions or return default values (since they should never be called).&amp;nbsp; &lt;br /&gt;&lt;br /&gt;If a file viewer does not support URLs, the &lt;span style="font-family:courier new,courier;"&gt;urlPattern&lt;/span&gt; on its &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;add /&amp;gt;&lt;/span&gt; node in the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;FileViewers /&amp;gt;&lt;/span&gt; region of the communityserver.config file can be omitted and the &lt;span style="font-family:courier new,courier;"&gt;Render&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;GetMediaType&lt;/span&gt; methods that accept &lt;span style="font-family:courier new,courier;"&gt;Uri&lt;/span&gt; objects can throw exceptions or return default values (since they should never be called). &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;FileViewer Priority&lt;/strong&gt;&lt;br /&gt;Within the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;FileViewers /&amp;gt;&lt;/span&gt; region of the communityserver.config file, order does matter.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;For duplicate &lt;span style="font-family:courier new,courier;"&gt;extensions&lt;/span&gt; (where multiple file viewers handle the same extension), the last viewer registered to handle the extension will be used to handle all files with the extension.&lt;br /&gt;&lt;br /&gt;For overlapping &lt;span style="font-family:courier new,courier;"&gt;urlPattern&lt;/span&gt;s (where a single URL may match the &lt;span style="font-family:courier new,courier;"&gt;urlPattern&lt;/span&gt; of more than on file viewer), the first matching file viewer will be used to handle the URL.&lt;br /&gt;&lt;br /&gt;Note that it is possible to register the same file viewer multiple times (with different &lt;span style="font-family:courier new,courier;"&gt;extensions&lt;/span&gt; or &lt;span style="font-family:courier new,courier;"&gt;urlPattern&lt;/span&gt;s) in the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;FileViewers /&amp;gt;&lt;/span&gt; list to implement the desired priority. &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;Rendering JavaScript&lt;/strong&gt;&lt;br /&gt;In general, the &lt;span style="font-family:courier new,courier;"&gt;IFileViewer.Render&lt;/span&gt; method can render whatever markup it chooses.&amp;nbsp; When rendering JavaScript, however, I suggest following these guidelines:&lt;ol&gt;
&lt;li style="margin-bottom:1em;"&gt;Render Scripts Inline&amp;nbsp; &lt;br /&gt;When including script resources, either inline or external, render the&lt;span style="font-family:courier new,courier;"&gt; &amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt; tag within the string returned by the &lt;span style="font-family:courier new,courier;"&gt;Render&lt;/span&gt; method instead of attempting to register the script via the &lt;span style="font-family:courier new,courier;"&gt;Page&lt;/span&gt; object or &lt;span style="font-family:courier new,courier;"&gt;CSControlUtility&lt;/span&gt; class.&amp;nbsp; This will ensure that media embedding and the out-of-the-box slide shows will function properly. &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;Do Not Use document.write&lt;br /&gt;In general, &lt;span style="font-family:courier new,courier;"&gt;document.write&lt;/span&gt; should not be used in JavaScript.&amp;nbsp; To support media embedding, the out-of-the-box slide shows, and XHTML in general, &lt;span style="font-family:courier new,courier;"&gt;document.write&lt;/span&gt; should not be used by file viewers.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Questions?&amp;nbsp; Issues?&amp;nbsp; Let me know in the comments.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6680" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/276191623" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Software+Development/default.aspx">Software Development</category><category domain="http://getben.com/tags/Theming/default.aspx">Theming</category><category domain="http://getben.com/tags/CS2008/default.aspx">CS2008</category><feedburner:origLink>http://getben.com/archive/2008/04/23/community-server-2008-implementing-custom-file-viewers.aspx</feedburner:origLink></item><item><title>Improved Chameleon Documentation for Community Server 2008</title><link>http://feeds.getben.com/~r/BenTiedt/~3/274988198/improved-chameleon-documentation-for-community-server-2008.aspx</link><pubDate>Mon, 21 Apr 2008 22:26:14 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6659</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6659</wfw:commentRss><comments>http://getben.com/archive/2008/04/21/improved-chameleon-documentation-for-community-server-2008.aspx#comments</comments><description>&lt;p&gt;The updates to the official documentation sites are still a little way out, so, in the meantime, I&amp;#39;ve gotten permission to post the new, improved Chameleon control documentation on this site.&lt;/p&gt; &lt;p&gt;Here it is: &lt;a href="http://getben.com/Documentation/CS2008/Chameleon/default.aspx"&gt;CS2008 Chameleon Documentation&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The new Chameleon documentation merges the old CHM download file and property documentation (along with some additional information and assumptions) to provide a single, integrated, searchable, control-based reference for all Chameleon controls in CS2008.&amp;nbsp; It also provides direct access to QueryOverrides information for list controls (which was previously difficult to find) and helpful &amp;quot;see also&amp;quot; links.&lt;/p&gt; &lt;p&gt;Let me know what you think.&amp;nbsp; Questions? Issues? Suggestions?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6659" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/274988198" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Software+Development/default.aspx">Software Development</category><category domain="http://getben.com/tags/Theming/default.aspx">Theming</category><category domain="http://getben.com/tags/Chameleon/default.aspx">Chameleon</category><category domain="http://getben.com/tags/CS2008/default.aspx">CS2008</category><feedburner:origLink>http://getben.com/archive/2008/04/21/improved-chameleon-documentation-for-community-server-2008.aspx</feedburner:origLink></item><item><title>Community Server 2008 - How to Implement Custom Widgets</title><link>http://feeds.getben.com/~r/BenTiedt/~3/274889255/community-server-2008-how-to-implement-custom-widgets.aspx</link><pubDate>Mon, 21 Apr 2008 18:38:00 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6654</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>14</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6654</wfw:commentRss><comments>http://getben.com/archive/2008/04/21/community-server-2008-how-to-implement-custom-widgets.aspx#comments</comments><description>&lt;p&gt;After &lt;a href="http://getben.com/archive/2008/04/18/community-server-2008-how-to-support-widgets-in-a-custom-theme.aspx"&gt;adding support for widgets in custom themes&lt;/a&gt;, it may be useful to create a few custom widgets.&lt;/p&gt;
&lt;p&gt;Widgets in Community Server 2008 (internally identified as content fragments) are server-side .net classes implementing the &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.IContentFragment&lt;/span&gt; interface.&amp;nbsp; Community Server will load all classes implementing this interface from all assemblies in the bin/ folder and make them available in the widget selection form (subject to application-type filters) -- there is no additional configuration required to add support for new content fragment types.&lt;/p&gt;
&lt;p&gt;To help implement new content fragments, CS2008 includes two base classes:&amp;nbsp; &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.ContentFragmentBase&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.ConfigurableContentFragmentBase&lt;/span&gt;.&amp;nbsp; These base classes implement the administrative members of the &lt;span style="font-family:courier new,courier;"&gt;IContentFragment&lt;/span&gt; interface and require that only the content-related members be implemented to complete a new content fragment.&amp;nbsp; Furthermore, the &lt;span style="font-family:courier new,courier;"&gt;ConfigurableContentFragmentBase&lt;/span&gt; base-class adds support for exposing configuration options (via Dynamic Configuration) for new content fragments.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Implementing a Basic Widget&lt;/h2&gt;
&lt;p&gt;A basic widget is very easy to implement.&amp;nbsp; Simply create a new class library project in Visual Studio and add a reference to CommunityServer.Components.dll and System.Web.dll.&amp;nbsp; Then, create a new class file and inherit from &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.ContentFragmentBase&lt;/span&gt;.&amp;nbsp; Allowing Visual Studio to complete the implementation of this abstract class automatically results in the following:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;namespace WidgetSamples&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class MyWidget : CommunityServer.Components.ContentFragmentBase&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void AddContentControls(System.Web.UI.Control control)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception(&amp;quot;The method or operation is not implemented.&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string FragmentDescription&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { throw new Exception(&amp;quot;The method or operation is not implemented.&amp;quot;); }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string FragmentName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { throw new Exception(&amp;quot;The method or operation is not implemented.&amp;quot;); }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To complete the implementation of this widget, the three required members above must be implemented.&amp;nbsp; &lt;/p&gt;
&lt;h3&gt;void AddContentControls(Control)&lt;/h3&gt;
&lt;p&gt;The &lt;span style="font-family:courier new,courier;"&gt;AddContentControls&lt;/span&gt; method is used to populate the content of the widget.&amp;nbsp; All content must be added to the &lt;span style="font-family:courier new,courier;"&gt;control.Controls&lt;/span&gt; collection.&amp;nbsp; To add literal text, the &lt;span style="font-family:courier new,courier;"&gt;System.Web.UI.LiteralControl&lt;/span&gt; can be used, for example:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;public override void AddContentControls(System.Web.UI.Control control)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; control.Controls.Add(new System.Web.UI.LiteralControl(&amp;quot;This is my widget!&amp;quot;));&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Because content fragments use &lt;span style="font-family:courier new,courier;"&gt;Control&lt;/span&gt; objects, the content of widgets can take advantage of all of the existing ASP.Net and Chameleon controls.&amp;nbsp; Controls in widgets participate in the full page lifecycle and can initiate and handle call backs and post backs.&lt;/p&gt;
&lt;h3&gt;string FragmentDescription&lt;/h3&gt;
&lt;p&gt;The &lt;span style="font-family:courier new,courier;"&gt;FragmentDescription&lt;/span&gt; returns the description of this content fragment and is rendered in the widget selection control used in theme configuration pages.&amp;nbsp; The description should be a single, concise sentence, such as:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;public override string FragmentDescription&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return &amp;quot;Renders &amp;#39;This is my widget!&amp;#39;&amp;quot;; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;string FragmentName&lt;/h3&gt;
&lt;p&gt;The &lt;span style="font-family:courier new,courier;"&gt;FragmentName&lt;/span&gt; returns the name of this content fragment and is rendered in the widget selection control as well, above the description.&amp;nbsp; The name should be only a few words, such as:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;public override string FragmentName&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return &amp;quot;My widget&amp;quot;; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Once these three members are implemented, the class library can be compiled and it&amp;#39;s output DLL can be deployed to Community Server&amp;#39;s bin/ folder.&amp;nbsp; Then, navigating to a theme configuration page,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_2.png"&gt;&lt;img border="0" width="282" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_thumb.png" alt="image" height="237" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/a&gt; &lt;a href="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_4.png"&gt;&lt;img border="0" width="260" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_thumb_5F00_1.png" alt="image" height="237" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/a&gt; &lt;a href="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_6.png"&gt;&lt;img border="0" width="238" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_thumb_5F00_2.png" alt="image" height="237" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Implementing a Configurable Widget&lt;/h2&gt;
&lt;p&gt;Many widgets benefit from exposing end-user configurable options.&amp;nbsp; To support such options, the alternate &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.ConfigurableContentFragmentBase&lt;/span&gt; base-class can be used.&amp;nbsp; The &lt;span style="font-family:courier new,courier;"&gt;ConfigurableContentFragmentBase&lt;/span&gt; class is similar to the &lt;span style="font-family:courier new,courier;"&gt;ContentFragmentBase&lt;/span&gt; class used in the simple widget example above, but adds support for exposing and using Dynamic Configuration options.&lt;/p&gt;
&lt;p&gt;To create a configurable content fragment, create a new class library project in Visual Studio and add a reference to CommunityServer.Components.dll, Telligent.DynamicConfiguration.dll, and System.Web.dll.&amp;nbsp; Then, create a new class file and inherit from &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Components.ConfigurableContentFragmentBase&lt;/span&gt;.&amp;nbsp; Allowing Visual Studio to complete the implementation of this abstract class automatically results in the following:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;namespace WidgetSamples&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class MyConfigurableWidget : CommunityServer.Components.ConfigurableContentFragmentBase&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void AddContentControls(System.Web.UI.Control control)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception(&amp;quot;The method or operation is not implemented.&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string FragmentDescription&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { throw new Exception(&amp;quot;The method or operation is not implemented.&amp;quot;); }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string FragmentName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { throw new Exception(&amp;quot;The method or operation is not implemented.&amp;quot;); }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override Telligent.DynamicConfiguration.Components.PropertyGroup[] GetPropertyGroups()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception(&amp;quot;The method or operation is not implemented.&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As you can see, the members are the same as with the simple widget with the exception of the new &lt;span style="font-family:courier new,courier;"&gt;GetPropertyGroups&lt;/span&gt; method.&lt;/p&gt;
&lt;h3&gt;PropertyGroup[] GetPropertyGroups()&lt;/h3&gt;
&lt;p&gt;The &lt;span style="font-family:courier new,courier;"&gt;GetPropertyGroups&lt;/span&gt; method is used to identify the Dynamic Configuration property groups, sub-groups, properties, selectable values, etc supported by the content fragment.&amp;nbsp; The layout of exposed properties is similar to themes&amp;#39; theme.config files, but instead of using an XML file, the layout is defined programmatically using classes in the &lt;span style="font-family:courier new,courier;"&gt;Telligent.DynamicConfiguration.Components&lt;/span&gt; namespace.&amp;nbsp; For example, to define a simple text entry field (note that I added a &amp;quot;&lt;span style="font-family:courier new,courier;"&gt;using Telligent.DynamicConfiguration.Components&lt;/span&gt;&amp;quot; statement to the top of the class file):&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;public override Telligent.DynamicConfiguration.Components.PropertyGroup[] GetPropertyGroups()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PropertyGroup group = new PropertyGroup(&amp;quot;group1&amp;quot;, &amp;quot;Options&amp;quot;, 0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Property textToRender = new Property(&amp;quot;textToRender&amp;quot;, &amp;quot;Text to Render&amp;quot;, PropertyType.String, 0, &amp;quot;&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; group.Properties.Add(textToRender);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new PropertyGroup[] { group };&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This defines a single configuration group (which renders as a tab) named &amp;quot;Options&amp;quot; containing a single string-based property named &amp;quot;Text to Render.&amp;quot;&amp;nbsp; A full description of the Dynamic Configuration API is beyond the scope of this article, but the Intellisense for the Telligent.DynamicConfiguration.dll assembly as well as the existing examples of content fragments in the &lt;a href="http://get.communityserver.com/download/moredownloads.aspx"&gt;Community Server 2008 SDK&lt;/a&gt; should provide ample examples for defining configuration options.&lt;/p&gt;
&lt;p&gt;The rendering of the configuration form and storage of the values entered by end-users is handled automatically by Community Server based on the definition of the &lt;span style="font-family:courier new,courier;"&gt;GetPropertyGroups&lt;/span&gt; method.&lt;/p&gt;
&lt;h3&gt;Using Configuration Options&lt;/h3&gt;
&lt;p&gt;To use the configuration options defined by the &lt;span style="font-family:courier new,courier;"&gt;GetPropertyGroups&lt;/span&gt; method, the following methods (defined on the &lt;span style="font-family:courier new,courier;"&gt;ConfigurableContentFragmentBase&lt;/span&gt; class) can be used based on the data type defined for the property:&lt;/p&gt;
&lt;ul&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;bool GetBoolValue(string id, bool defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;int GetIntValue(string id, int defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;double GetDoubleValue(string id, double defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;string GetStringValue(string id, string defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;string GetHtmlValue(string id, string defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;DateTime GetDateValue(string id, DateTime defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;DateTime GetTimeValue(string id, DateTime defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;DateTime GetDateTimeValue(string id, DateTime defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Guid GetGuidValue(string id, Guid defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;System.Drawing.Color GetColorValue(string id, System.Drawing.Color defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;System.Web.UI.WebControls.Unit GetUnitValue(string id, System.Web.UI.WebControls.Unit defaultValue) &lt;/span&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Uri GetUrlValue(string id, Uri defaultValue)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In all of these examples, the first parameter is the ID of the property for which a value should be retrieved.&amp;nbsp; In our sample definition of the &lt;span style="font-family:courier new,courier;"&gt;GetPropertyGroups&lt;/span&gt; method above, we defined a single string field with the ID &amp;quot;textToRender.&amp;quot;&amp;nbsp; To render that field as the content of the content fragment, the &lt;span style="font-family:courier new,courier;"&gt;GetStringValue&lt;/span&gt; method can be used, for example:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;public override void AddContentControls(System.Web.UI.Control control)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; control.Controls.Add(new System.Web.UI.LiteralControl(this.GetStringValue(&amp;quot;textToRender&amp;quot;, &amp;quot;&amp;quot;)));&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This will render the user-defined value for the &amp;quot;Text to Render&amp;quot; field as the content of the control. &lt;/p&gt;
&lt;p&gt;To finish the implementation of our configurable widget, the &lt;span style="font-family:courier new,courier;"&gt;FragmentDescription&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;FragmentName&lt;/span&gt; still need to be implemented as with the simple widget:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;public override string FragmentDescription&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return &amp;quot;Renders custom text&amp;quot;; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;public override string FragmentName&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return &amp;quot;My Configurable Widget&amp;quot;; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The class library can now be compiled and it&amp;#39;s output DLL can be deployed to Community Server&amp;#39;s bin/ folder.&amp;nbsp; Then, navigating to a theme configuration page,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_8.png"&gt;&lt;img border="0" width="286" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_thumb_5F00_3.png" alt="image" height="235" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/a&gt; &lt;a href="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_10.png"&gt;&lt;img border="0" width="260" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_thumb_5F00_4.png" alt="image" height="235" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/a&gt; &lt;a href="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_12.png"&gt;&lt;img border="0" width="279" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_thumb_5F00_5.png" alt="image" height="235" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/a&gt; &lt;a href="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_14.png"&gt;&lt;img border="0" width="278" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_thumb_5F00_6.png" alt="image" height="235" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/a&gt; &lt;a href="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_16.png"&gt;&lt;img border="0" width="268" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_thumb_5F00_7.png" alt="image" height="235" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Additional Options&lt;/h2&gt;
&lt;p&gt;The base classes implement a few additional &lt;span style="font-family:courier new,courier;"&gt;IContentFragment&lt;/span&gt; members that can be overridden by specific implementations to further customize widget rendering:&lt;/p&gt;
&lt;h3&gt;string GetFragmentHeader(Control)&lt;/h3&gt;
&lt;p&gt;By default, the &lt;span style="font-family:courier new,courier;"&gt;FragmentName&lt;/span&gt; is rendered as the header of a rendered widget.&amp;nbsp; This behavior can be modified by overriding the base implementation of the &lt;span style="font-family:courier new,courier;"&gt;GetFragmentHeader&lt;/span&gt; method.&amp;nbsp; This method returns the HTML to render as the content fragment&amp;#39;s header.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The control parameter to this method can be used to load contextual data, for example, via the &lt;span style="font-family:courier new,courier;"&gt;CommunityServer.Controls.CSControlUtility&lt;/span&gt; class.&lt;/p&gt;
&lt;h3&gt;string GetFragmentMoreUrl(Control)&lt;/h3&gt;
&lt;p&gt;The out-of-the-box themes in Community Server 2008 support rendering a &amp;quot;more URL&amp;quot; for each widget -- for example, viewing all tags for the tag cloud widget or viewing the full list of active posts for the active posts widget.&amp;nbsp; By default, the &amp;quot;more URL&amp;quot; is blank and will not be rendered.&lt;/p&gt;
&lt;p&gt;To set a &amp;quot;more URL&amp;quot;, the &lt;span style="font-family:courier new,courier;"&gt;GetFragmentMoreUrl&lt;/span&gt; method can be overridden to return the URL to navigate to view additional, related information.&amp;nbsp; Similar to the &lt;span style="font-family:courier new,courier;"&gt;GetFragmentHeader&lt;/span&gt; method, the control parameter is supplied to support retrieving contextual information through Chameleon.&lt;/p&gt;
&lt;h3&gt;ApplicationType[] GetRelatedApplicationTypes()&lt;/h3&gt;
&lt;p&gt;As mentioned in the &lt;a href="http://getben.com/archive/2008/04/18/community-server-2008-how-to-support-widgets-in-a-custom-theme.aspx"&gt;How to Support Widgets in a Custom Theme&lt;/a&gt; article, Community Server has built-in support for filtering available widgets by application types.&amp;nbsp; By default, the base classes identify no related application type which results in the content fragment being listed regardless of the application type filter.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;To identify the application type or types that relate to a content fragment, the &lt;span style="font-family:courier new,courier;"&gt;GetRelatedApplicationTypes&lt;/span&gt; method can be overridden to return the array of related application types.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Any questions?&amp;nbsp; Please let me know in the comments.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6654" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/274889255" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Software+Development/default.aspx">Software Development</category><category domain="http://getben.com/tags/Theming/default.aspx">Theming</category><category domain="http://getben.com/tags/Chameleon/default.aspx">Chameleon</category><category domain="http://getben.com/tags/Dynamic+Configuration/default.aspx">Dynamic Configuration</category><category domain="http://getben.com/tags/CS2008/default.aspx">CS2008</category><feedburner:origLink>http://getben.com/archive/2008/04/21/community-server-2008-how-to-implement-custom-widgets.aspx</feedburner:origLink></item><item><title>Community Server 2008 - How to Support Widgets in a Custom Theme</title><link>http://feeds.getben.com/~r/BenTiedt/~3/273203787/community-server-2008-how-to-support-widgets-in-a-custom-theme.aspx</link><pubDate>Fri, 18 Apr 2008 22:56:00 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6637</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6637</wfw:commentRss><comments>http://getben.com/archive/2008/04/18/community-server-2008-how-to-support-widgets-in-a-custom-theme.aspx#comments</comments><description>&lt;p&gt;After &lt;a href="http://getben.com/archive/2008/04/18/community-server-2008-how-to-upgrade-themes-from-cs2007-to-cs2008.aspx"&gt;updating a custom theme for CS2008&lt;/a&gt;, support for widgets can be added.&lt;/p&gt;
&lt;p&gt;Community Server 2008 provides built-in support for extending Dynamic Theme Configuration to support selecting custom widgets to be displayed within a theme.&amp;nbsp; CS2008 includes widgets for showing post lists, user lists, group lists, tag clouds, custom HTML (including viewer support for videos, images, and audio), as well as external widgets from Google, Widgetbox, and Springwidgets.&amp;nbsp; Here&amp;#39;s a short example of using widgets in CS2008:&lt;/p&gt;
&lt;div style="width:430px;margin:1em auto;"&gt;(Please visit the site to view this media)&amp;nbsp;&lt;/div&gt;
&lt;p&gt;Adding support for widgets in a custom theme is simple--it requires only two steps:&amp;nbsp; (1) Add the Dynamic Configuration property for each &amp;quot;column&amp;quot; of widgets and (2) Add Chameleon controls to the theme to render the widget &amp;quot;column&amp;quot;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Adding Widget Dynamic Configuration Properties&lt;/h2&gt;
&lt;p&gt;Widget support in CS2008 is implemented as an extension to Dynamic Configuration support in themes.&amp;nbsp; For each set (or column) of widgets in a theme, a new &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; node needs to be added to the theme&amp;#39;s theme.config file.&lt;/p&gt;
&lt;p&gt;The following &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; node identifies a column of widgets:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property &lt;br /&gt;&amp;nbsp;&amp;nbsp; id=&amp;quot;myWidgetColumn&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; text=&amp;quot;Widgets&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; dataType=&amp;quot;Custom&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; controlType=&amp;quot;CommunityServer.Controls.ContentFragmentsCustomControl, CommunityServer.Controls&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In this example, the &lt;span style="font-family:courier new,courier;"&gt;id&lt;/span&gt; (&amp;quot;myWidgetColumn&amp;quot;) is the unique name for this column of widgets (this will be used later when we want to render this column of widgets in the theme), the &lt;span style="font-family:courier new,courier;"&gt;text&lt;/span&gt; identifies this widget column, the &lt;span style="font-family:courier new,courier;"&gt;dataType&lt;/span&gt; identifies that widgets will be stored as custom data (they&amp;#39;re actually stored as XML), and the &lt;span style="font-family:courier new,courier;"&gt;controlType&lt;/span&gt; identifies the built-in Dynamic Configuration control that renders the widget editor:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img border="0" width="260" src="http://getben.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/blog/image_5F00_5.png" alt="Example of the Widget Dynamic Configuration Control" height="239" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;This &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; node can be added within any existing&lt;span style="font-family:courier new,courier;"&gt; &amp;lt;propertyGroup /&amp;gt;&lt;/span&gt; or &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;propertySubGroup /&amp;gt;&lt;/span&gt; node in the theme&amp;#39;s theme.config file.&amp;nbsp; A full discussion of the theme.config file is beyond the scope of this article, but browsing around an existing theme.config file should provide enough pointers to add a widget column.&lt;/p&gt;
&lt;p&gt;A &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; node identifying the &lt;span style="font-family:courier new,courier;"&gt;dataType&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;controlType&lt;/span&gt; mentioned above must be added for each unique list/column of widgets that will be included in the theme.&lt;/p&gt;
&lt;p&gt;Once the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; nodes are added to the theme.config file, users are able to select their desired widgets.&amp;nbsp; The next step is actually rendering them somewhere in the theme...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Adding Chameleon Controls to Render Widget Dynamic Configuration Properties&lt;/h2&gt;
&lt;p&gt;Community Server 2008 provides &lt;a href="http://getben.com/archive/2007/01/08/introduction-to-chameleon.aspx" class="null"&gt;Chameleon &lt;/a&gt;controls to render widgets.&amp;nbsp; Widgets are identified as &lt;span style="font-family:courier new,courier;"&gt;ContentFragments&lt;/span&gt; in Chameleon and the following Chameleon controls can be used to interact with &lt;span style="font-family:courier new,courier;"&gt;ContentFragments&lt;/span&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragment /&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;em&gt;Renders the content/body of a &lt;span style="font-family:courier new,courier;"&gt;ContentFragment&lt;/span&gt;.&lt;/em&gt; &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragmentData /&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;em&gt;&lt;a href="http://getben.com/archive/2007/01/10/introduction-to-chameleon-single-value-base-controls.aspx" class="null"&gt;API-related single value control&lt;/a&gt; that renders a property on a &lt;span style="font-family:courier new,courier;"&gt;ContentFragment&lt;/span&gt;, such as: &lt;span style="font-family:courier new,courier;"&gt;OrderNumber&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;FragmentName&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;FragmentDescription&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;FragmentHeader&lt;/span&gt;, or &lt;span style="font-family:courier new,courier;"&gt;FragmentMoreUrl&lt;/span&gt;. &lt;/em&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragmentList /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;em&gt;&lt;a href="http://getben.com/archive/2007/01/11/introduction-to-chameleon-list-base-controls.aspx" class="null"&gt;List control&lt;/a&gt;&amp;nbsp;that renders&amp;nbsp;the list/column of widgets for a single configuration property (as defined in the theme&amp;#39;s theme.config file). &lt;/em&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragmentPropertyComparison /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;em&gt;&lt;a href="http://getben.com/archive/2007/01/15/introduction-to-chameleon-condition-controls.aspx" class="null"&gt;Condition control&lt;/a&gt; providing support for comparing two properties of a &lt;span style="font-family:courier new,courier;"&gt;ContentFragment&lt;/span&gt;. &lt;/em&gt;&lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragmentPropertyValueComparison /&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;em&gt;&lt;a href="http://getben.com/archive/2007/01/15/introduction-to-chameleon-condition-controls.aspx" class="null"&gt;Condition control&lt;/a&gt; providing support for comparing a property of a &lt;span style="font-family:courier new,courier;"&gt;ContentFragment&lt;/span&gt; to a static value.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These controls can be included in any page, master page, or user control in a theme. &lt;/p&gt;
&lt;p&gt;The most simple inclusion would be the default &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragmentList /&amp;gt;&lt;/span&gt; control:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragmentList Property=&amp;quot;myWidgetColumn&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This would render the body/content of each ContentFragment configured for the property with &lt;span style="font-family:courier new,courier;"&gt;id&lt;/span&gt; &amp;quot;myWidgetColumn&amp;quot; within &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;li&amp;gt;&lt;/span&gt; tags in an &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt; list. &lt;/p&gt;
&lt;p&gt;As with other Chameleon controls, the formatting of &lt;span style="font-family:courier new,courier;"&gt;ContentFragments&lt;/span&gt; can be customized by defining custom formatting templates on the list control.&amp;nbsp; The following is the standard format for &lt;span style="font-family:courier new,courier;"&gt;ContentFragment&lt;/span&gt; lists rendered in the Hawaii theme:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragmentList runat=&amp;quot;server&amp;quot; Property=&amp;quot;myWidgetColumn&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;ItemTemplate&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;CSControl:ContentFragment runat=&amp;quot;server&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;LeaderTemplate&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div class=&amp;quot;CommonContentBox&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;CSControl:ContentFragmentData Property=&amp;quot;FragmentHeader&amp;quot; runat=&amp;quot;server&amp;quot; Tag=&amp;quot;H4&amp;quot; CssClass=&amp;quot;CommonContentBoxHeader&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div class=&amp;quot;CommonContentBoxContent&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/LeaderTemplate&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TrailerTemplate&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;CSControl:ContentFragmentData ResourceName=&amp;quot;ViewMore&amp;quot; LinkTo=&amp;quot;More&amp;quot; runat=&amp;quot;server&amp;quot; Tag=&amp;quot;Div&amp;quot; CssClass=&amp;quot;CommonContentBoxFooter&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/TrailerTemplate&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/CSControl:ContentFragment&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/ItemTemplate&amp;gt;&lt;br /&gt;&amp;lt;/CSControl:ContentFragmentList&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Note the custom formatting of the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;ItemTemplate /&amp;gt;&lt;/span&gt; of the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragmentList /&amp;gt;&lt;/span&gt; and the customizations of the rendering of the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:ContentFragment /&amp;gt;&lt;/span&gt; to define a custom &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;LeaderTemplate /&amp;gt;&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;TrailerTemplate /&amp;gt;&lt;/span&gt;.&amp;nbsp; In this example, the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;LeaderTemplate /&amp;gt;&lt;/span&gt; is used to render the &lt;span style="font-family:courier new,courier;"&gt;ContentFragment&lt;/span&gt;&amp;#39;s header and the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;TrailerTemplate /&amp;gt;&lt;/span&gt; is used to render the &lt;span style="font-family:courier new,courier;"&gt;ContentFragment&lt;/span&gt;&amp;#39;s &amp;quot;view more&amp;quot; link if it is defined.&lt;/p&gt;
&lt;p&gt;The control templates can be adjusted to fit the look/feel/markup of any custom theme.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Additional Options&lt;/h2&gt;
&lt;p&gt;There are a few additional notes and considerations when adding support for widgets to a theme: Setting Default and Filtering Selectable Widgets.&lt;/p&gt;
&lt;h3&gt;Setting Defaults for Widget Dynamic Configuration Properties&lt;/h3&gt;
&lt;p&gt;When shipping a custom theme, it is useful to include a default set of widgets for each column of widgets supported by the theme.&amp;nbsp; The easiest way to add default widgets is to&lt;/p&gt;
&lt;ol&gt;
&lt;li style="margin-bottom:1em;"&gt;Define the widget &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; node and add the supporting Chameleon controls to the theme as described above. &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;Use the theme configuration page for the theme to select and configure the widgets that you want to include by default and save the theme changes. &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;When your widgets are properly defined, use the export feature of the theme configuration page to get the sharable XML version of your configuration data. &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;Locate the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; node in this XML file with the &lt;span style="font-family:courier new,courier;"&gt;id&lt;/span&gt; matching the &lt;span style="font-family:courier new,courier;"&gt;id&lt;/span&gt; given to each widget column. &lt;/li&gt;
&lt;li style="margin-bottom:1em;"&gt;For each &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; node relating to a widget column in the XML export file, copy the contents of the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;value /&amp;gt;&lt;/span&gt; node (&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;![CDATA[... blah ... ]]&amp;gt;&lt;/span&gt;) and paste it into a &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;defaultValue /&amp;gt;&lt;/span&gt; node within the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; node defining the widget column in the theme&amp;#39;s theme.config file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The final result should look like:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property id=&amp;quot;myWidgetColumn&amp;quot; text=&amp;quot;Widgets&amp;quot; dataType=&amp;quot;Custom&amp;quot; controlType=&amp;quot;CommunityServer.Controls.ContentFragmentsCustomControl, CommunityServer.Controls&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;defaultValue&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;![CDATA[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;contentFragments&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;contentFragment type=&amp;quot;CommunityServer.Controls.SiteUrlContentFragment, CommunityServer.Controls&amp;quot; id=&amp;quot;2df9ece8-fe74-46c6-b82a-a42a65664fe8&amp;quot; configuration=&amp;quot;fragmentTitle=Shortcuts&amp;amp;amp;controlpanel=False&amp;amp;amp;blogAdmin=False&amp;amp;amp;mediaAdmin=True&amp;amp;amp;user_List=False&amp;amp;amp;post_NotRead=False&amp;amp;amp;forumSubscriptions=False&amp;amp;amp;usersOnline=False&amp;amp;amp;forumModeration=False&amp;amp;amp;hub_create=False&amp;amp;amp;allGroups=False&amp;amp;amp;groupAdmin=False&amp;amp;amp;customLinks=&amp;amp;amp;listCssClass=CommonSidebarList&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;contentFragment type=&amp;quot;CommunityServer.Controls.TagCloudContentFragment, CommunityServer.Controls&amp;quot; id=&amp;quot;2b1a7190-3b89-4a19-985c-eaf6c41e993d&amp;quot; configuration=&amp;quot;applicationType=MediaGallery&amp;amp;amp;ignoreFilterTags=False&amp;amp;amp;maximumTags=25&amp;amp;amp;minimumPostsPerTag=0&amp;amp;amp;filterTags=&amp;amp;amp;fragmentTitle=Tags&amp;amp;amp;tagCloudCss=CommonSidebarTagCloud&amp;amp;amp;tagCss=CommonTag6%2cCommonTag5%2cCommonTag4%2cCommonTag3%2cCommonTag2%2cCommonTag1&amp;amp;amp;showTagCounts=False&amp;amp;amp;noTagsText=No+Tags+Found&amp;amp;amp;linkTo=ContextualTagBrowser&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/contentFragments&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ]]&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/defaultValue&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This will set the default set of widgets used by a new installation of the theme as well as the set of widgets used after clicking the &amp;quot;Restore Defaults&amp;quot; button on the theme configuration page.&lt;/p&gt;
&lt;h3&gt;Filtering the Available Widgets for a Widget Dynamic Configuration Property&lt;/h3&gt;
&lt;p&gt;If a column of widgets is only going to be shown in a blog, why show forums-related widgets in the widget drop-down?&lt;/p&gt;
&lt;p&gt;CS2008 supports filtering the widget drop-down list by application type.&amp;nbsp; To add an application-type-based filter to a widget dynamic configuration property, add the applicationTypes attribute to the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property /&amp;gt;&lt;/span&gt; in the theme.config file defining the widget column.&amp;nbsp; The value of this attribute is a comma-separated list of the application types for which associated widgets should be listed. For example,&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;property &lt;br /&gt;&amp;nbsp;&amp;nbsp; id=&amp;quot;myWidgetColumn&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; text=&amp;quot;Widgets&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; dataType=&amp;quot;Custom&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; controlType=&amp;quot;CommunityServer.Controls.ContentFragmentsCustomControl, CommunityServer.Controls&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; applicationTypes=&amp;quot;Forum,Weblog&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;would only allow blog- and forum-related widgets to be selected for this widget list/column.&lt;/p&gt;
&lt;p&gt;Note that when filtering widgets by application type, widgets that do not identify an associated application type will always be included in the list of available widgets--this includes the &amp;quot;Generic Content&amp;quot;, &amp;quot;Google Gadget&amp;quot; and other application-generic widgets.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In my next article covering CS2008, I&amp;#39;ll talk about implementing custom widgets.&lt;/p&gt;
&lt;p&gt;Questions? Please ask in the comments.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6637" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/273203787" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Theming/default.aspx">Theming</category><category domain="http://getben.com/tags/Chameleon/default.aspx">Chameleon</category><category domain="http://getben.com/tags/Dynamic+Configuration/default.aspx">Dynamic Configuration</category><feedburner:origLink>http://getben.com/archive/2008/04/18/community-server-2008-how-to-support-widgets-in-a-custom-theme.aspx</feedburner:origLink></item><item><title>Community Server 2008 - How to Upgrade Themes from CS2007 to CS2008</title><link>http://feeds.getben.com/~r/BenTiedt/~3/272997650/community-server-2008-how-to-upgrade-themes-from-cs2007-to-cs2008.aspx</link><pubDate>Fri, 18 Apr 2008 16:28:00 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6631</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6631</wfw:commentRss><comments>http://getben.com/archive/2008/04/18/community-server-2008-how-to-upgrade-themes-from-cs2007-to-cs2008.aspx#comments</comments><description>&lt;p&gt;My last article outlined the &lt;a href="http://getben.com/archive/2008/04/16/community-server-2008-changes-to-chameleon.aspx"&gt;changes made to Chameleon and Theming between CS2007 and CS2008&lt;/a&gt; and could be used as a guide for an in-depth, manual upgrade of a CS2007 theme to CS2008.&amp;nbsp; In this article, however, I&amp;#39;ll provide my suggested approach to upgrading themes for CS2008.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Upgrading a CS2007 Site Theme for CS2008&lt;/h2&gt; &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;Remove Old Files/Folders&lt;/strong&gt;&lt;br /&gt;The following files and folders are no longer used in CS2008 and should be removed (if they exist) to prevent unnecessary review when upgrading to future versions of Community Server:  &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;Files/ folder  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Galleries/ folder  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Roller/ folder  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/privatemessagelist.aspx file &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;Search and Replace&lt;/strong&gt;&lt;br /&gt;Some changes from CS2007 just require a few simple search-and-replaces against a theme&amp;#39;s files.&amp;nbsp; Using a tool that can perform search-and-replace operations within files in a folder (including sub-folders), such as my personal favorite &lt;a href="http://www.emeditor.com/"&gt;EmEditor&lt;/a&gt;, perform the following case-insensitive replacements across all files in the custom theme:  &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;LinkTo=&amp;quot;UserPrivateMessages&amp;quot;&lt;/span&gt; to&lt;span style="font-family:courier new,courier;"&gt; LinkTo=&amp;quot;UserConversations&amp;quot;&lt;/span&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;LinkTo=&amp;quot;PrivateMessage&amp;quot;&lt;/span&gt; to &lt;span style="font-family:courier new,courier;"&gt;LinkTo=&amp;quot;SendConversationMessage&amp;quot;&lt;/span&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;ImagesBaseUrl=&amp;quot;~/Themes/default/images/common/&amp;quot;&lt;/span&gt; to &lt;span style="font-family:courier new,courier;"&gt;ImagesBaseUrl=&amp;quot;~/utility/images/&amp;quot;&lt;/span&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Src=&amp;quot;~/Themes/default/common/UserWelcome.ascx&amp;quot;&lt;/span&gt; to &lt;span style="font-family:courier new,courier;"&gt;Src=&amp;quot;~/utility/usercontrols/UserWelcome.ascx&amp;quot;&lt;/span&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Formatter.Truncate(&lt;/span&gt; to &lt;span style="font-family:courier new,courier;"&gt;Formatter.MaxLength( &lt;/span&gt; &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Formatter.CheckStringLength(&lt;/span&gt; to &lt;span style="font-family:courier new,courier;"&gt;Formatter.MaxLength(&lt;/span&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Formatter.StripAllTags(&lt;/span&gt; to &lt;span style="font-family:courier new,courier;"&gt;Formatter.RemoveHtml(&lt;/span&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;Search and Think&lt;/strong&gt;&lt;br /&gt;All &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSFile:&amp;gt;&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSGallery:&amp;gt;&lt;/span&gt; prefixed controls are no longer valid in CS2008.&amp;nbsp; I&amp;#39;d suggest searching for such controls and either (1) remove them or (2) replace them with an appropriate &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSMedia:&amp;gt;&lt;/span&gt; prefixed control.&amp;nbsp; To find all remaining references to these controls, use a search tool (as used in step 2) to find:&lt;br /&gt; &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSFile:&lt;/span&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSGallery:&lt;/span&gt; &lt;/li&gt;&lt;/ol&gt;Additionally, occurrences of the following inline code should be updated as these methods are no longer supported.&amp;nbsp; For each occurrence, I would suggest reviewing the corresponding theme file from one of the CS2008 themes and implementing the modification that was made in those themes in the custom theme.&amp;nbsp; Occurrences of the following text should be reviewed:  &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Formatter.FormatAgoDate&lt;/span&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Formatter.WhiteSpace&lt;/span&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Formatter.FormatUsername&lt;/span&gt; &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;Copy New Files/Folders&lt;/strong&gt;&lt;br /&gt;With new functionality comes new theme files.&amp;nbsp; The following files did not exist in CS2007 but are required for a full-featured CS2008 theme.&amp;nbsp; The following files can be copied from an existing CS2008 theme (Hawaii, Calypso, and Lean-and-Green support all CS2008 features) and then modified to work with the custom theme&amp;#39;s master pages and styles.&amp;nbsp; The following files and folders are new to CS2008:  &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;Blogs/tagslist.aspx file &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Forums/tagslist.aspx file &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/activitylist.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/announcementlist.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/commentlist.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/conversation.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/conversationlist.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/createeditconversation.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/createeditprofilemessage.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/editapikeymodal.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/editapikeys.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/favoritelist.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/friendshiplist.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/requestfriend.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/userfile.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/userfilelist.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/userfileslideshow.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Utility/insertmedia.aspx file  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Media/ folder  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Hubs/ folder &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;Copy Heavily Modified Files&lt;/strong&gt;&lt;br /&gt;Some theme files in CS2008 were modified heavily to support new features.&amp;nbsp; For these files, I would suggest copying the CS2008 version of the file from one of the included themes (Hawaii, Calypso, or Lean-and-Green) and restyle the copied file to work with the custom theme.&amp;nbsp; The following files were heavily modified:  &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;Forums/createeditforumpostform.aspx  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Forums/thread-threadedview.ascx  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/edituser.aspx  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/userprofile.aspx  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Utility/selectcontent.aspx &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;strong&gt;Be Aware of CSS Rules&lt;/strong&gt;&lt;br /&gt;When copying files from an existing theme to a custom theme, be sure to review the CSS classes and rules used by those files.&amp;nbsp; While copying the theme pages will render the content, without the associated CSS style rules, the pages may not render well. &lt;/li&gt;&lt;/ol&gt; &lt;p style="margin-bottom:1em;"&gt;NOTE: There were many changes to the underlying API in Community Server.&amp;nbsp; While these steps should cover most themes, if a CS2007 theme relied heavily on inline code, it is possible that some of the API references are no longer valid.&amp;nbsp; In themes that make frequent use of inline code, I suggest manually reviewing all of the inline code for the theme to ensure that it is valid in CS2008.&lt;/p&gt; &lt;p style="margin-bottom:1em;"&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Upgrading a CS2007 Blog Theme for CS2008&lt;/h2&gt; &lt;p style="margin-bottom:1em;"&gt;Luckily, fewer changes were made to blog themes in CS2008.&amp;nbsp; To upgrade a blog theme, follow steps #2 and #3 above.&lt;/p&gt; &lt;p style="margin-bottom:1em;"&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Group/Hub Themes in CS2008&lt;/h2&gt; &lt;p style="margin-bottom:1em;"&gt;Sub-communites, referred to as &amp;quot;Groups&amp;quot; in the UI and &amp;quot;Hubs&amp;quot; in themes and the API, are new to Community Server 2008.&amp;nbsp; To support groups/hubs with a custom theme upgraded from CS2008, a new theme within the themes/hubs/ folder will need to be created.&lt;/p&gt; &lt;p style="margin-bottom:1em;"&gt;As with new blog and site themes, I suggest copying an existing theme and implementing the desired changes.&lt;/p&gt; &lt;p style="margin-bottom:1em;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin-bottom:1em;"&gt;Questions?&amp;nbsp; Issues?&amp;nbsp; Let me know in the comments.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://getben.com/aggbug.aspx?PostID=6631" width="1" height="1"&gt;&lt;img src="http://feeds.getben.com/~r/BenTiedt/~4/272997650" height="1" width="1"/&gt;</description><category domain="http://getben.com/tags/Community+Server/default.aspx">Community Server</category><category domain="http://getben.com/tags/Theming/default.aspx">Theming</category><category domain="http://getben.com/tags/Chameleon/default.aspx">Chameleon</category><category domain="http://getben.com/tags/CS2008/default.aspx">CS2008</category><category domain="http://getben.com/tags/CS2007/default.aspx">CS2007</category><feedburner:origLink>http://getben.com/archive/2008/04/18/community-server-2008-how-to-upgrade-themes-from-cs2007-to-cs2008.aspx</feedburner:origLink></item><item><title>Community Server 2008 - Changes to Chameleon</title><link>http://feeds.getben.com/~r/BenTiedt/~3/271717374/community-server-2008-changes-to-chameleon.aspx</link><pubDate>Wed, 16 Apr 2008 21:22:00 GMT</pubDate><guid isPermaLink="false">c109d48e-4759-4905-a889-e68e82846b24:6615</guid><dc:creator>Ben Tiedt</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://getben.com/rsscomments.aspx?PostID=6615</wfw:commentRss><comments>http://getben.com/archive/2008/04/16/community-server-2008-changes-to-chameleon.aspx#comments</comments><description>&lt;p&gt;In this post, I&amp;#39;ll outline the changes to the Chameleon theming engine (and themes in general) between Community Server 2007 and Community Server 2008.&amp;nbsp; If you&amp;#39;re interested in the changes to themes between an earlier version of Community Server (before 2007) and the 2008 version, I suggest reading my &lt;a href="http://getben.com/archive/2007/01/08/introduction-to-chameleon.aspx"&gt;Introduction to Chameleon&lt;/a&gt; posts from the release of CS2007.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;New Functionality&lt;/h2&gt; &lt;p&gt;Community Server 2008 merges the File Gallery and Photo Gallery applications into a single Media Gallery application.&amp;nbsp; New messaging support (activities, profile comments, profile announcements, and private conversations) and support for sub-communities (groups) was also added.&amp;nbsp; For all of the new API objects, there are new Chameleon controls.&amp;nbsp; Also, for all of the new UI locations, Community Server expects new pages to exist in themes.&lt;/p&gt; &lt;p&gt;In terms of themes and Chameleon, this means:&lt;/p&gt; &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;All controls with the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSFile:&amp;gt;&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSGallery:&amp;gt;&lt;/span&gt; prefix from CS2007 no longer exist in CS2008 -- they cannot be used anywhere in a CS2008 theme.  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;All theme pages in the Files/, Galleries/, and Roller/ folders of a theme are no longer used.  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;There are now controls with the prefix &lt;font face="Courier New"&gt;&amp;lt;CSMedia:&amp;gt;&lt;/font&gt;, &lt;font face="Courier New"&gt;&amp;lt;CSMessage:&amp;gt;&lt;/font&gt; and &lt;font face="Courier New"&gt;&amp;lt;CSHub:&amp;gt;&lt;/font&gt; to support accessing media gallery, messaging, and sub-community (group) content (respectively).&amp;nbsp; Documentation for these new controls is coming as soon as our CS2008 documentation sites are publicly available (I&amp;#39;ll make an announcement on my blog when that happens). &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Pages linking to or displaying private messages must now use the new &amp;lt;CSMessage:&amp;gt; controls.  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;The &amp;quot;PrivateMessage&amp;quot; and &amp;quot;UserPrivateMessages&amp;quot; values for the &lt;span style="font-family:courier new,courier;"&gt;LinkTo&lt;/span&gt; property of the &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;CSControl:UserData /&amp;gt;&lt;/span&gt; control should be changed to &amp;quot;SendConversationMessage&amp;quot; and &amp;quot;UserConversations&amp;quot; (respectively).  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;The User/privatemessagelist.aspx theme page is no longer used.  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;The following pages were added:&lt;/li&gt; &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;User/activitylist.aspx&lt;br /&gt;&lt;em&gt;Lists activity messages for a user&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/announcementlist.aspx&lt;br /&gt;&lt;em&gt;Lists announcements made by a user&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/commentlist.aspx&lt;br /&gt;&lt;em&gt;Lists comments made on a user&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/conversation.aspx&lt;br /&gt;&lt;em&gt;Displays a single conversation&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/conversationlist.aspx&lt;br /&gt;&lt;em&gt;Lists all conversations for the accessing user&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/createeditconversation.aspx&lt;br /&gt;&lt;em&gt;Starts and enables replying to a conversation&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/createeditprofilemessage.aspx&lt;br /&gt;&lt;em&gt;Adds a comment on a user or Adds and supports editing an announcement&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/editapikeymodal.aspx&lt;br /&gt;&lt;em&gt;Edits a REST API key&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/editapikeys.aspx&lt;br /&gt;&lt;em&gt;Lists and manages REST API keys&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/favoritelist.aspx&lt;br /&gt;&lt;em&gt;Lists a users favorite posts and sections&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/friendshiplist.aspx&lt;br /&gt;&lt;em&gt;Lists all friends for a current user and provides support for accepting and reviewing friendship requests&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/requestfriend.aspx&lt;br /&gt;&lt;em&gt;Initiates a friendship request&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/userfile.aspx&lt;br /&gt;&lt;em&gt;Displays a single file uploaded into a user&amp;#39;s &amp;quot;My Files&amp;quot; area&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/userfilelist.aspx&lt;br /&gt;&lt;em&gt;Lists files uploaded into a user&amp;#39;s &amp;quot;My Files&amp;quot; area&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;User/userfileslideshow.aspx&lt;br /&gt;&lt;em&gt;Displays a slideshow of files in a user&amp;#39;s &amp;quot;My Files&amp;quot; area&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Utility/insertmedia.aspx&lt;br /&gt;&lt;em&gt;Renders the &amp;quot;Insert Media&amp;quot; window used by the editor to insert file viewers for external or local media&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Media/*&lt;br /&gt;&lt;em&gt;All files in the Media/ folder are new and are used to render the Media Gallery application pages&lt;/em&gt;  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Hubs/*&lt;br /&gt;&lt;em&gt;All files in the Hubs/ folder are new and are used to render aggregate group information (Groups are called Hubs in the API, Chameleon, and themes)&lt;/em&gt; &lt;/li&gt;&lt;/ol&gt; &lt;li style="margin-bottom:1em;"&gt;The old &amp;quot;Default&amp;quot; theme was renamed to &amp;quot;Calypso&amp;quot; -- so there is no longer a &amp;quot;Default&amp;quot; theme.&amp;nbsp; This was done to prevent the need to overwrite the default theme in future versions of Community Server which may cause issues with saved Dynamic Configuration options.&amp;nbsp; This change a few implications for existing themes that referenced files in the &amp;quot;Default&amp;quot; theme:&lt;/li&gt; &lt;ol&gt; &lt;li style="margin-bottom:1em;"&gt;The UserWelcome.ascx user control used to render the &amp;quot;Sign In&amp;quot;, &amp;quot;Sign Out&amp;quot;, &amp;quot;Help&amp;quot; and other links (usually in the upper-right of a Community Server site) must be copied into new themes or the theme should be updated to reference the shared version of this user control located at utility/UserControls/UserWelcome.ascx &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;Ratings controls that reference the star images in the default theme in the &lt;font face="Courier New"&gt;ImagesBaseUrl&lt;/font&gt; property are no longer valid.&amp;nbsp; Such references can be updated to use the shared version of these files located in utility/images.&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Removal of Base Page Types&lt;/h2&gt; &lt;p&gt;In CS2007, Chameleon required that all ASPX pages inherit from CSThemePage (or one of its sub-classes... &lt;span style="font-family:courier new,courier;"&gt;CSBlogThemPage&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;CSFileThemePage&lt;/span&gt;, etc).&amp;nbsp; This is no longer the case in CS2008.&lt;/p&gt; &lt;p&gt;To better support integrating content and functionality from Community Server in other ASP.Net-based web applications, Chameleon no longer requires that each ASPX page inherit from &lt;span style="font-family:courier new,courier;"&gt;CSThemePage&lt;/span&gt;.&amp;nbsp; Instead, Chameleon now uses an application-type-specific &amp;quot;page context&amp;quot; object to interpret the querystring, register page headers, etc.&lt;/p&gt; &lt;p&gt;For existing CS2007 themes, no changes are necessarily required.&amp;nbsp; The base theme pages still exist in CS2008 and expose the same functionality (such as the &lt;span style="font-family:courier new,courier;"&gt;SetTitle()&lt;/span&gt; method and &lt;span style="font-family:courier new,courier;"&gt;CurrentX&lt;/span&gt; properties), but, these methods/properties now use the base page context instead of implementing the functionality themselves.&lt;/p&gt; &lt;p&gt;If a theme needs to use a different base page type, all references to the properties and methods of the &lt;span style="font-family:courier new,courier;"&gt;CSThemPage&lt;/span&gt; must be removed (see New General-Purpose Chameleon Controls for more information).&amp;nbsp; The themes that ship with CS2008 should not be dependent on &lt;span style="font-family:courier new,courier;"&gt;CSThemePage&lt;/span&gt; and can be used as a reference on a page-by-page basis.&lt;/p&gt; &lt;p&gt;&lt;em&gt;In CS2007, the base page types also identified the application-type context for the page.&amp;nbsp; This application-type context was used to interpret post IDs/names, section IDs/names, etc (if the application-type context was &amp;quot;weblog&amp;quot; for example, Chameleon would attempt to interpet a post ID on the query string as a blog post).&amp;nbsp; In CS2008, the application-type context is now set by the &lt;font face="Courier New"&gt;applicationType&lt;/font&gt; attribute on &lt;font face="Courier N"&gt;&amp;lt;location /&amp;gt;&lt;/font&gt; and &lt;font face="Courier New"&gt;&amp;lt;url /&amp;gt;&lt;/font&gt; nodes in the SiteUrls.config file.&lt;/em&gt;&amp;nbsp; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Changes to Existing Chameleon Controls&lt;/h2&gt; &lt;p&gt;With respect to the topic further down the page (Property Templates), there are very few changes to existing Chameleon controls and none of the implemented changes should impact existing themes.&lt;/p&gt; &lt;p&gt;Here is an overview of the changes, by control type:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;API-related Single Value Controls&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The following properties were added to &lt;a href="http://getben.com/archive/2007/01/10/introduction-to-chameleon-single-value-base-controls.aspx"&gt;API-related Single Value Controls&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;LinkTabIndex&lt;/span&gt;&lt;br /&gt;Defines the tab-index for the link identified by the &lt;span style="font-family:courier new,courier;"&gt;LinkTo&lt;/span&gt; property.  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;EnsureVisibleHtml&lt;/span&gt;&lt;br /&gt;When set to true (the default is false), the content of the control will only be rendered if the value of the defined &lt;span style="font-family:courier new,courier;"&gt;Property&lt;/span&gt; or &lt;span style="font-family:courier new,courier;"&gt;ExtendedAttribute&lt;/span&gt; contains visible HTML -- that is, text or &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;img /&amp;gt;&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;object /&amp;gt;&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;embed /&amp;gt;&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;applet /&amp;gt;&lt;/span&gt;, or &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;iframe /&amp;gt;&lt;/span&gt; tags.&amp;nbsp; This setting is helpful when determining whether to show content entered from an HTML editor.  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;IgnoreLinkPermissions&lt;/span&gt;&lt;br /&gt;When set to true (the default is false), the link identified by the &lt;span style="font-family:courier new,courier;"&gt;LinkTo&lt;/span&gt; property will be rendered regardless of the accessing user&amp;#39;s permissions to that link.&amp;nbsp; For example, in forums, the &amp;quot;Reply&amp;quot; link is displayed even for users who do not have access to reply to a post.&amp;nbsp; When the link is clicked, the user is either asked to log in or alerted that they do not have access to reply.  &lt;/li&gt;&lt;li style="margin-bottom:1em;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Encoding&lt;/span&gt; (&lt;span style="font-family:courier new,courier;"&gt;None&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;HTML&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;JavaScript&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;URL&lt;/span&gt;)&lt;br /&gt;To help remove the need to use inline code, the &lt;span style="font-family:courier new,courier;"&gt;Encoding&lt;/span&gt; property was added.&amp;nbsp; When set (the default is &lt;span style="font-family:courier new,courier;"&gt;None&lt;/span&gt;), the value of the defined &lt;span style="font-family:courier new,courier;"&gt;Property&lt;/span&gt; or &lt;span style="font-family:courier new,courier;"&gt;ExtendedAttribute&lt;/span&gt; will be encoded for the identified output -- HTML, JavaScript or URL.&amp;nbsp; This property is useful when including dynamic content within inline JavaScript scripts or with property templates (defined below) that will be included in URLs. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;API-related Condition Controls&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;API-related &lt;a href="http://getben.com/archive/2007/01/15/introduction-to-chameleon-condition-controls.aspx"&gt;Condition Controls&lt;/a&gt;, such as &lt;span style="font-family:courier new,courier;"&gt;XPropertyValueComparison&lt;/span&gt; and &lt;span style="font-family:courier new,courier;"&gt;XPropertyComparison&lt;/span&gt;, now support an additional value for the &lt;span style="font-family:courier new,courier;"&gt;Operator&lt;/span&gt; property: &lt;span style="font-family:courier new,courier;"&gt;ContainsVisibleHtml&lt;/span&gt;.&amp;nbsp; Using this operator will cause the condition to evaluate to true only if the &amp;quot;left&amp;quot; value contains visible HTML (visible text or &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;img /&amp;gt;&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;object /&amp;gt;&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;embed /&amp;gt;&lt;/span&gt;, &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;applet /&amp;gt;&lt;/span&gt;, or &lt;span style="font-family:courier new,courier;"&gt;&amp;lt;iframe /&amp;gt;&lt;/span&gt; tags).&lt;/p&g