Developer FAQ
How to attach actions to the elements in the tree using ActionExecutor (without form dialogue)?
Answer:
There is possibility to add new commands to existing tree elements, like pages, items, datatypes, media items, file system folders or files...
The commands can execute tasks like displaying a custom ASP.NET page in the C1 console or launch C1 / Workflow Foundation based UI like wizards or editors.
A typical scenario where this would come in handy is adding a "Manage extranet security" command to page and media elements which can launch a customized UI relating to the selected item.
In sample below we attached command to page element in the tree using ActionExecutor without using form dialogue.
using Composite.C1Console.Elements.Plugins.ElementActionProvider; using Composite.C1Console.Security; using Composite.C1Console.Elements; using Composite.Data; using Composite.Data.ProcessControlled.ProcessControllers.GenericPublishProcessController; using Composite.Data.Types; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using System.Collections.Generic; using Composite.C1Console.Actions; using Composite.Data.ProcessControlled; using System.Linq; using System; namespace Composite.Pages.PublishTree { [ConfigurationElementType(typeof(NonConfigurableElementActionProvider))] public sealed class PublishTreeElementActionProvider : IElementActionProvider { private static readonly ActionGroup _actionGroup = new ActionGroup("Workflow", ActionGroupPriority.PrimaryLow); public IEnumerable<ElementAction> GetActions(EntityToken entityToken) { DataEntityToken dataEntityToken = entityToken as DataEntityToken; // check if it's really data entity token if (dataEntityToken != null) { // we need only IPage - doing our check if (dataEntityToken.Data.DataSourceId.InterfaceType == typeof(IPage)) { // add our action token ElementAction action = new ElementAction(new ActionHandle(new PublishTreeActionToken())) { VisualData = new ActionVisualizedData { // right click menu icon settings - label, tooltip, image and display location settings Label = "Publish pages tree", ToolTip = "Publish pages tree", Icon = GenericPublishProcessController.Publish, ActionLocation = new ActionLocation { ActionType = ActionType.Edit, IsInFolder = false, IsInToolbar = false, ActionGroup = _actionGroup } } }; yield return action; } } } public sealed class PublishTreeActionExecutor : Composite.C1Console.Actions.IActionExecutor { public Composite.C1Console.Actions.FlowToken Execute(Composite.C1Console.Security.EntityToken entityToken, Composite.C1Console.Security.ActionToken actionToken, Composite.C1Console.Actions.FlowControllerServicesContainer flowControllerServicesContainer) { // doing our magic with data here DataEntityToken token = (DataEntityToken)entityToken; UpdateTreeRefresher treeRefresher = new UpdateTreeRefresher(token.Data.GetDataEntityToken(), flowControllerServicesContainer); IPage page = (IPage)token.Data; // call our functions PublishPagesTree(page.Id); // call refresh tree treeRefresher.PostRefreshMesseges(page.GetDataEntityToken()); return null; } #region Our functions executed here private void PublishPage(Guid pageId) { using (DataConnection connection = new DataConnection()) { var page = connection.Get<IPage>().Where(p => p.Id == pageId).FirstOrDefault(); IPublishControlled publishControlled = page as IPublishControlled; if (publishControlled != null) { if (publishControlled.PublicationStatus != GenericPublishProcessController.Published) { // publish page publishControlled.PublicationStatus = GenericPublishProcessController.Published; connection.Update<IPublishControlled>(publishControlled); } } } } private void PublishPagesTree(Guid pageId) { // publish page PublishPage(pageId); // get childrens for current page using (DataConnection connection = new DataConnection()) { IEnumerable<Guid> childPageIds = (from ps in connection.Get<IPageStructure>() where ps.ParentId == pageId orderby ps.LocalOrdering select ps.Id).ToList(); // publish childrens foreach (var childPageId in childPageIds) { PublishPagesTree(childPageId); } } } #endregion } #region We add here action token PublishTreeActionToken [ActionExecutor(typeof(PublishTreeActionExecutor))] public sealed class PublishTreeActionToken : ActionToken { // publish permissions required to execute action static private IEnumerable<PermissionType> _permissionTypes = new PermissionType[] { PermissionType.Publish }; public override IEnumerable<PermissionType> PermissionTypes { get { return _permissionTypes; } } public override string Serialize() { return "PublishTree"; } public static Composite.C1Console.Security.ActionToken Deserialize(string serializedData) { return new PublishTreeActionToken(); } } #endregion } }
How to make it work
- Add the following references to the project:
- System.Configuration
- Microsoft.Practices.EnterpriseLibrary.Common
- Composite
- Compile your code and copy the assembly to
/Bin
directory - Register your provider in Composite C1's configuration:
\App_Data\Composite\Composite.config
(see below)
The "Publish pages tree" command will appear in the context menu of a selected C1 page and will publish it as well as all its children etc.
Register Element Action Provider in Composite.config
To register your action provider in the Composite configuration file:
- add an
<add />
element to the plug-ins list of theComposite.C1Console.Elements.Plugins.ElementActionProviderConfiguration
element.
Below is how the sample provider shown above would look like.
<Composite.C1Console.Elements.Plugins.ElementActionProviderConfiguration> <ElementActionProviderPlugins> <add name="PublishTree" type="Composite.Pages.PublishTree.PublishTreeElementActionProvider, Composite.Pages.PublishTree.Lib" /> </ElementActionProviderPlugins> </Composite.C1Console.Elements.Plugins.ElementActionProviderConfiguration>Please note that you should make sure to set the correct value for the "type" attribute of the "add" element:
- type="Namespace_name.Class_name, Assembly_name”
- name is the assembly's name