API and Theme Changes from CS 2008

API and Theme Changes from CS 2008

Community Server 2008.5 Documentation

Rate This

Community Server 2008.5 adds support for applications that are not based on the Group/Section/Post model, freeing applications to implement their application-specific entities in any way they see fit.

In place of the Group/Section/Post model, interfaces have been added to support interacting with applications in aggregate:

  • IViewableContent -- a viewable piece of content (WeblogPost, Forum, User, etc...)
  • ITaggableContent -- IViewableContent that supports tagging
  • IFavorableContent -- IViewableContent that supports being made a favorite
  • IRateableContent -- IViewableContent that supports ratings
  • IContentContainer -- a container of content (Forum, Weblog, Wiki, Group, etc...)
  • ISecuredContentContainer -- IContentContainer that supports permissions checks
  • ITagsContainer -- IContentContainer that supports containing tags and retrieving tag-related content

These interfaces, along with changes to CSApplicationData, provide applications with more flexibility in their implementation.  For example, the Wiki application does not have a concept of "Group" and its entities do not inherit from Post or Section and are not stored in the cs_Posts and cs_Sections tables.

The following components/features were modified to support the changes to the core API:  CSContext, IPageContext, Chameleon Implicit Databinding, CSApplicationData, Tags, Hubs, Chameleon Controls.

CSContext Changes

  1. Most of the querystring-interpreted state fields on CSContext have been removed (PostID, SectionID, etc...) since they are no longer application-generic.
  2. Applications can now provide an application-specific context object loaded through the application's CSApplicationData implementation and exposed through CSContext.ApplicationContexts[ApplicationType].  This application-specific context can be used to identify top-level state information specific to the application (current Weblog, ForumPost, Conversation, etc)
  3. To retrieve state information generically, the CSContext.GetCurrent<T>() method has been added.  This method will attempt to retrieve an object of type T from the current application, and if the current application cannot produce such an object, it will query the core application context.

Usage Changes

Instead of

CSContext.Current.PostID;

use

CSContext.Current.GetCurrent<Post>().PostID;

or

CSContext.Current.GetIntFromQueryString(CommonQueryStringProperties.PostID, -1);

IPageContext Changes

  1. With the implementation of application-specific context objects (that use objects instead of IDs), IPageContext has been simplified to not expose specific types, but instead use two GetCurrent<T>() methods (one which specifies a specific application type to load from... the other that uses the current application type).
  2. IPageContext *was* used to interpret the page-level context (determining the Post object for the CSContext.PostID value).  It is now used to *override* the interpretation of the page level context (which is now implemented by application-specific context objects) and perform page-related functions (page-level security, RSS embedding, search filtering, etc).

Usage Changes

Instead of

CSControlUtility.Instance().GetPageContext(page).CurrentSection;

use

CSControlUtility.Instance().GetPageContext(page).GetCurrent<Section>() ;

Chameleon Implicit Databinding Changes

Beyond the CSContext and IPageContext changes, Chameleon has been changed to push implicit databinding into the currently-bound objects instead of defining all of the binding rules in control utility classes.

Individual entities can implement the IRelatedDataContainer interface to provide a way for Chameleon to retrieve implicitly related data (User for Post, Group for Section, etc).  

Additionally, the GetCurrent<T>(Control) method was updated to retrieve the current object from the current IPageContext implementation if the type is not found by analyzing currently binding controls.

These changes allow most control utility methods to simply call the generic CSControlUtility.Instance().GetCurrent<T>(Control) method since this method now can process implicit databining rules via IRelatedDataContainer.

Retrieving current data is now performed by: 

  1. Analyzing the currently binding control's data objects (and their related data via IRelatedDataContainer) for the type requested.
  2. If controls are not binding the requested type, the current IPageContext is analyzed for the requested type.
  3. If the IPageContext implementation does not override the loading of the requested type, the current CSContext is used to retrieve the object from the current application's context (or the core context).

Usage Changes

No changes are required for themes (since these changes are behind the scenes), but any new controls should utilize these changes.

CSApplicationData Changes

CSApplicationData is the base class for configuration data for applications.  Each application implements and registers an implementation of CSApplicationData to enable Community Server to perform aggregate behaviors. 

The following methods were removed from CSApplicationData since they are no longer application-generic:

All of the Group/Section/Post-related members of CSApplicationData have been removed.  These include:

  1. AggPublicOnly
  2. Groups()
  3. Sections()
  4. Sections(Permission)
  5. GetSection(int)
  6. GetSection(int, bool)
  7. AddFavoritePostText
  8. RemoveFavoritePostText
  9. AddFavoriteSectionText
  10. RemoveFavoriteSectionText
  11. SetAggPublicOnly(bool)
  12. GetPost(int)
  13. GetPost(string, int)
  14. GetGroup(int)
  15. GetSectionPermissionFromIDataReader(IDataReader)
  16. GetSectionFromIDataReader(IDataReader)
  17. InstantiatePost(IDataReader)
  18. SectionCount
  19. GroupUrl(int)
  20. Url(Post)  

These members have been moved to the temporary ILegacyApplication interface which is used as an interim API for SectionQuery and search until they can be updated to remove dependence on Group/Section/Post (and this related API on applications).

Changes to Existing Code

These APIs have not been replaced - instead, features that relied on these members should be updated to be application specific.  For example, SectionQuery has already been updated to operate only within the context of a single application.

Aggregate Tag Changes

The Group/Section/Post-related tag methods on CSApplicationData have been removed in favor of a new tag-related API defined on CSApplicationData that is not dependent on Group/Section/Post.

The new API consists of: 

  1. bool SupportsTags
  2. Uri GetTagBrowserUri(bool useCurrentContext)
  3. Uri GetTagBrowserUri(string[] filterTags, bool useCurrentContext)
  4. Uri GetTagsRssUri(string[] filterTags, bool logicallyOrTags, bool useCurrentContext)
  5. Collection<ITag> GetTags(bool useCurrentContext)
  6. Collection<ITag> GetTags(string[] filterTags, bool useCurrentContext)
  7. PagedSet<ITaggableContent> GetTaggedContent(string[] filterTags, bool logicallyOrTags, bool useCurrentContext, int pageIndex, int pageSize)

In these members, the useCurrentContext parameter identifies whether the application should filter the results based on the current CSContext (via the CSContext.GetCurrent<T>() method).  For example, for blogs, passing useCurrentContext=true would result in the blogs application filtering by the blog (if available) or group (if available) otherwise filtering by the application.  Passing useCurrentContext=false will results in tags being retrieved only for the application.

Each application can define additional options for use within the context of the application - but these APIs are used by the AggregateTags static class to implement aggregate tag and content retrieval.   The AggregateTags class identifies methods to retrieve tags and tag-related-content from one or more applications via the new tag API defined on CSApplicationData.

Changes to Existing Code

The AggregateTags methods should be used wherever code previously accessed the Tags static class to retrieve tag-related data from more than one application (including for Hubs).

Hub Sub-Application Changes

Hubs now support containing sub-applications that are not implemented using Sections.  The API on the Hub class for retrieving sub-sections was removed in favor of the new API:  

  1. IContentContainer GetSubApplicationContainer(ApplicationType type, bool enabledOnly)
  2. Collection<IContentContainer> GetAllSubApplicationContainers(bool enabledOnly) 

These methods poll installed applications and use the CSApplicationData.SupportsHubs and CSApplicationData.GetContainer(Hub hub, bool enabledOnly) methods to get the IContentContainer for the given Hub from the application.

Additionally, each returned container needs to implement the ITagsContainer interface to support identifying tags that can be reused within a Hub - all of the AggregateTags methods that accept a Hub as a parameter use the ITagsContainer and the Hub.GetAllSubApplicationContainers() method to retrieve aggregate tags and related content within the applications hosted within a Hub.

Changes to Existing Code

Instead of using

hub.GetSubSection(ApplicationType.Weblog);

use

Hub.GetSubApplicationContainer(ApplicationType.Weblog, true);

Section implements IContentContainer - so this second call will return a Weblog object as it did before.  Passing ApplicationType.Wiki however will return a Wiki which also implements IContentContainer but does not inherit from Section.

Chameleon Changes 

Because the base API has changed and applications are no longer based on the Post, Section, Group, etc objects.  The following changes have been made to Chameleon controls: 

  1. Removed <CSControl:FavoritePopupMenu /> (a similar control has been implemented in each application, for example, <CSBlog:FavoritePopupMenu />)
  2. Removed <CSControl:FavoriteToggleButton /> (a type-specific toggle button has been added to each application to support toggling the favorite status of that type, for example, <CSBlog:WeblogPostFavoriteToggleButton />)
  3. Removed <CSControl:DeleteFavoritePostsForm />
  4. Removed <CSControl:DeleteFavoriteUsersForm />
  5. Removed <CSControl:DeleteFavoriteSectionsForm />
  6. Removed ShareFavoriteUsersCheckBox from <CSControl:EditUserForm /> (All favorites are enabled or disabled via the ShareFavoritesCheckBox)
  7. Removed ShareFavoriteUsersCheckBox from <CSControl:CreateUserForm />  (All favorites are enabled or disabled via the ShareFavoritesCheckBox )
  8. Removed CurrentUserFavorites, AccessingUserFavorites, and UsersWatchingAccessingUser from the QueryType override for <CSControl:UserList /> (Favorites should be retrieved through <CSControl:FavorableContentList />)
  9. Removed the enumeration value FavoriteType.User, as users are not supported as favorites.
  10. Removed User.FavoritesShared (FavoriteType enum) and added User.EnableFavoriteSharing (bool) to support identifying if a user has shared their favorites or not.
  11. Removed all <CSControl:Section* />, <CSControl:Group* />, <CSControl:Link* />, <CSControl:LinkCategory* />, <CSControl:Post* />, <CSControl:PostCategory* />, <CSControl:Rating* />, <CSControl:Section* />, <CSControl:SectionMembership* />, <CSControl:SectionThemeConfiguration* />, and <CSControl:Thread* /> controls.  Application-specific implementations of these controls were added to each application supported by the old, base controls.

The themes included in CS 2008.5 have been updated to use the application-specific implementations of these modified controls and reflect the changes made to favorites.

Comments
  • Where did <CSControl:PostEmoticon runat="server" /> go?

  • CSForum:ForumPostEmoticon

    This is the pattern for a lot of these controls.  For some reason they have the application type needlessly repeated.  Seems unnecessary.  I would think that the tag prefix / namespace should be sufficient.  Was this done because of some irregularity with the the groups application?