A rule is an automatic action that Community Server performs in response to platform triggers and conditions specified in the Rules tab of the Control Panel. They consist of three parts, a trigger (IRuleTrigger), a condition (IConfigurableRuleCondition) and an action (IConfigurableRuleAction).
[toc]
Why Should I Create a Rule?
When you want to allow users to setup actions that can be performed automatically without having to write code for an event handler then the solution would be to create a rule trigger, condition or action. Some of the out-of-the-box rules allow you to award a number of points for publishing a blog post. Or you could send a congratulatory email for liking a piece of content. There are many scenarios that can be accomplished with rules.
Creating a Rule
When the trigger occurs, the condition(s) is/are evaluated and then, if met, the action(s) are executed. In addition, a rule can enabled or disabled as necessary.
The rule trigger takes advantage of an event hander to fire the rule. In this sample the rule is triggered after a user is created. The two main factors in the trigger are the RuleTriggerExecutionContext and the IRuleController. The RuleTriggerExecutionContext collects and sets the data that will be passed along to the other parts of the rule. The IRuleController allows you to actually trigger the rule. This is typically used along with an event handler. You can think of the trigger as the When part of the rule statement.
using System; using System.Collections.Generic; using Telligent.Evolution.Extensibility; using Telligent.Evolution.Extensibility.Api.Version1; using Telligent.Evolution.Extensibility.Rules.Version1; namespace MyRules { public class MyRuleTrigger : IRuleTrigger { #region IPlugin public string Name { get { return "My Rule Trigger"; } } public string Description { get { return "This plugin will demo how the IRuleTrigger works"; } } public void Initialize() { Apis.Get<Users>().Events.AfterCreate += Events_AfterCreate; } private void Events_AfterCreate(UserAfterCreateEventArgs e) { var data = new Dictionary<string, string> { { "ContentId", e.ContentId.ToString() } }; _ruleController.ScheduleTrigger(data); } #endregion #region IRuleTrigger public Guid RuleTriggerId { get { return new Guid("61F43DB3-941E-48DA-8290-5F28940801D8"); } } public string RuleTriggerName { get { return "a user is created"; } } public string RuleTriggerCategory { get { return "Sample Rule"; } } public IEnumerable<Guid> ContextualDataTypeIds { get { return new[] { Apis.Get<Users>().ContentTypeId }; } } public RuleTriggerExecutionContext GetExecutionContext(RuleTriggerData data) { var context = new RuleTriggerExecutionContext(); var contentId = Guid.Parse(data["ContentId"]); context.Add(Apis.Get<Users>().ContentTypeId, Apis.Get<Users>().Get(new UsersGetOptions { ContentId = contentId })); return context; } private IRuleController _ruleController; public void SetController(IRuleController controller) { _ruleController = controller; } #endregion } }
This is a simple rule condition, it evaluates two strings and checks for equality. The condition has three main members. The ConfigurableValues
property which allows you to setup the controls that will be displayed in the UI for configuring the condition. This is followed by the Evaluate
method which determines if the rule should continue executing. It accepts an IRuleExecutionRuntime argument that is used to retrieve the PropertyGroup
array returned by the ConfigurableValues
. Finally you'll need to return a PrimativeType
in the RequiredPrimitiveType
property. You can think of the condition as the If part of the rule statement.
using System; using Telligent.DynamicConfiguration.Components; using Telligent.Evolution.Controls; using Telligent.Evolution.Extensibility.Rules.Version1; using Telligent.Evolution.Extensibility.Templating.Version1; namespace MyRules { public class MyRuleCondition : IConfigurableRuleCondition { #region IPlugin public string Name { get { return "My Rule Condition"; } } public string Description { get { return "This plugin will demo how the IRuleCondition works"; } } public void Initialize() { //No initialization required for IRuleCondition } #endregion #region IRuleCondition public Guid RuleComponentId { get { return new Guid("CAC4086F-AB72-4038-8760-BA794DF55FEE"); } } public string RuleComponentName { get { return "is"; } } public string RuleComponentCategory { get { return "Sample Rule"; } } public PropertyGroup[] ConfigurableValues { get { var group = new PropertyGroup("options", "Options", 0); group.Properties.Add(new Property("value", "Equal To", PropertyType.Custom, 1, "") { ControlType = typeof(TokenSelectableStringControl) }); return new[] { group }; } } public bool Evaluate(IRuleExecutionRuntime runtime) { var leftSideValue = runtime.GetContextualValue(); var rightSideValue = runtime.GetCustom("value"); return leftSideValue.Equals(rightSideValue); } public PrimitiveType RequiredPrimitiveType { get { return PrimitiveType.String; } } #endregion } }
Once the rule trigger and condition are satisfied then the action can take place. The main section if the action is the Execute
method. It is what performs the action based on the IRuleExecutionRuntime
argument that was setup in the trigger. You can think of the action as the Then part of the rule statement.
using System; using Telligent.DynamicConfiguration.Components; using Telligent.Evolution.Controls; using Telligent.Evolution.Extensibility; using Telligent.Evolution.Extensibility.Api.Version1; using Telligent.Evolution.Extensibility.Rules.Version1; namespace Samples { public class MyRuleAction : IConfigurableRuleAction { #region IPlugin public string Name { get { return "My Rule Action"; } } public string Description { get { return "This plugin will demo how the IConfigurableRuleAction works"; } } public void Initialize() { //No initialization required for IConfigurableRuleAction } #endregion #region IConfigurableRuleAction public Guid RuleComponentId { get { return new Guid("0708749F-3C9D-44AF-8BA4-780CB95CB73B"); } } public string RuleComponentName { get { return "write event log"; } } public string RuleComponentCategory { get { return "Sample Rule"; } } public PropertyGroup[] ConfigurableValues { get { var group = new PropertyGroup("options", "Options", 0); group.Properties.Add(new Property("user", "Log user", PropertyType.Custom, 2, "") { ControlType = typeof(UserTokenSelectionControl) }); return new[] { group }; } } public void Execute(IRuleExecutionRuntime runtime) { var user = runtime.GetCustomUser("user"); var options = new EventLogEntryWriteOptions { Category = "Samples" }; Apis.Get<EventLog>().Write(string.Format("Executing rule for {0} with {1} ID", user.Username, user.Id), options); } #endregion } }
Here is the result of the plugins displayed in the UI when creating a new rule.