Skip to content

Commit 74da148

Browse files
eshanrnhgitbook-bot
authored andcommitted
GITBOOK-42: Fixed formatting
1 parent 551992b commit 74da148

File tree

2 files changed

+158
-36
lines changed

2 files changed

+158
-36
lines changed

13/umbraco-engage/developers/personalization/implement-your-own-segment-parameters.md

Lines changed: 143 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ description: >-
77

88
# Implement your own segment parameters
99

10-
You may want to build segments with custom rules not part of the Umbraco Engage by default. You can add your custom segment parameters to Umbraco Engage.
10+
You may want to build segments with custom rules not included in Umbraco Engage by default. You can add your custom segment parameters to Umbraco Engage.
1111

12-
In the following guide, we will show how this is done. There are 3 steps:
12+
In the following guide, we will show how this is done. There are three steps:
1313

14-
1. C# definition
15-
2. AngularJS definition
16-
* (optional) Cockpit visualization
14+
1. [C# Definition](implement-your-own-segment-parameters.md#id-1.-c-definition)
15+
2. [AngularJS Definition](implement-your-own-segment-parameters.md#id-2.-angularjs-definition)
16+
3. [\[Optional\] Cockpit Visualization](implement-your-own-segment-parameters.md#id-3.-optional-cockpit-visualization)
1717

1818
This guide will use code samples to add a "**Day of week**" segment parameter where you can select a single day of the week. If a pageview happens on that day the segment parameter will be satisfied.
1919

2020
You can download the following code files to your project to add the parameter directly to your solution.
2121

2222
{% file src="../../.gitbook/assets/day-of-the-week-segment-parameter.zip" %}
2323

24-
## 1. C# definition
24+
## 1. C# Definition
2525

2626
Your custom segment parameter must be defined in C# for the Umbraco Engage to use it.\
2727
In code, we refer to a segment parameter as a **segment rule**.
@@ -43,48 +43,72 @@ You will have to implement the following interfaces for a new custom parameter:
4343

4444
For the "**Day of week**" example, the code looks like this:
4545

46-
{% code overflow="wrap" lineNumbers="true" %}
4746
```csharp
48-
// Define the segment rule public class DayOfWeekSegmentRule : BaseSegmentRule{ public DayOfWeekSegmentRuleConfig TypedConfig { get; }
49-
public override SegmentRuleValidationMode ValidationMode => SegmentRuleValidationMode.Once; public DayOfWeekSegmentRule(long id, long segmentId, string type, string config, bool isNegation, DateTime created, DateTime? updated, DayOfWeekSegmentRuleConfig typedConfig) : base(id, segmentId, type, config, isNegation, created, updated) => TypedConfig = typedConfig;
50-
public override bool IsSatisfied(IPersonalizationProfile context) => context.Pageview.Timestamp.DayOfWeek == TypedConfig.DayOfWeek;}
47+
// Define the segment rule
48+
public class DayOfWeekSegmentRule : BaseSegmentRule
49+
{
50+
public DayOfWeekSegmentRuleConfig TypedConfig { get; }
51+
52+
public override SegmentRuleValidationMode ValidationMode => SegmentRuleValidationMode.Once;
53+
54+
public DayOfWeekSegmentRule(long id, long segmentId, string type, string config,
55+
bool isNegation, DateTime created, DateTime? updated, DayOfWeekSegmentRuleConfig typedConfig)
56+
: base(id, segmentId, type, config, isNegation, created, updated)
57+
=> TypedConfig = typedConfig;
58+
59+
public override bool IsSatisfied(IPersonalizationProfile context)
60+
=> context.Pageview.Timestamp.DayOfWeek == TypedConfig.DayOfWeek;
61+
}
5162
```
52-
{% endcode %}
5363

5464
And the factory which is used to create an instance of this rule:
5565

56-
{% code overflow="wrap" %}
5766
```csharp
58-
public class DayOfWeekSegmentRuleFactory : ISegmentRuleFactory{ public string RuleType { get; } = "DayOfWeek"; public ISegmentRule CreateRule(string config, bool isNegation, long id, long segmentId, DateTime created, DateTime? updated) { var typedConfig = JsonConvert.DeserializeObject<DayOfWeekSegmentRuleConfig>(config); return new DayOfWeekSegmentRule(id, segmentId, RuleType, config, isNegation, created, updated, typedConfig); }}
67+
public class DayOfWeekSegmentRuleFactory : ISegmentRuleFactory
68+
{
69+
public string RuleType { get; } = "DayOfWeek";
70+
public ISegmentRule CreateRule(string config, bool isNegation, long id,
71+
long segmentId, DateTime created, DateTime? updated)
72+
{
73+
var typedConfig = JsonConvert.DeserializeObject<DayOfWeekSegmentRuleConfig>(config);
74+
return new DayOfWeekSegmentRule(id, segmentId, RuleType, config, isNegation,
75+
created, updated, typedConfig);
76+
}
77+
}
5978
```
60-
{% endcode %}
6179

6280
We are using the class `DayOfWeekSegmentRuleConfig` as a representation of the configuration of the rule, which is not strictly necessary but makes it easier. The configuration is stored as a string in the database but in code, we like to have IntelliSense so we parse the stored configuration to this class:
6381

6482
{% code overflow="wrap" %}
6583
```csharp
66-
public class DayOfWeekSegmentRuleConfig{ public DayOfWeek DayOfWeek { get; set; }}
84+
public class DayOfWeekSegmentRuleConfig
85+
{
86+
public DayOfWeek DayOfWeek { get; set; }
87+
}
6788
```
6889
{% endcode %}
6990

7091
The segment rule factory needs to be registered so Umbraco Engage can use it.\
7192
The code below registers the factory in a new composer, you can use an existing composer for this if you like:
7293

73-
{% code overflow="wrap" %}
7494
```csharp
75-
public class DayOfWeekSegmentRuleComposer : IUserComposer{ public void Compose(Composition composition) { composition.Register<ISegmentRuleFactory, DayOfWeekSegmentRuleFactory>(Lifetime.Transient); }}
95+
public class DayOfWeekSegmentRuleComposer : IUserComposer
96+
{
97+
public void Compose(Composition composition)
98+
{
99+
composition.Register<ISegmentRuleFactory, DayOfWeekSegmentRuleFactory>(Lifetime.Transient);
100+
}
101+
}
76102
```
77-
{% endcode %}
78103

79104
In the above example, we have shown how you can define custom segment parameters using C#. Next we look into enabling and configuring our segment in the Umbraco Engage segment builder.
80105

81-
## 2. AngularJS definition
106+
## 2. AngularJS Definition
82107

83108
We implemented the business logic for the segment parameter in the previous step, however, the parameter cannot be added to your backoffice segments yet. In this step, we will add some JavaScript and HTML to enable you to add and configure your segments in the Umbraco Engage segment builder.
84109

85110
This step will show concrete code samples that belong to our demo parameter "**Day of week**".
86111

87-
\
88112
You need to create a folder in the _App\_Plugins_ folder of your project that will hold the new files.
89113

90114
For this example name it "`day-of-week`". The folder and content look like this:
@@ -111,11 +135,69 @@ The contents for each of the files are below:
111135

112136
In this file, you define the segment parameter and register it in the repository of Umbraco Engage.
113137

114-
{% code overflow="wrap" %}
115138
```javascript
116-
// If you have your own custom module, use this:// angular.module("myCustomModule", ["Engage"]);// angular.module("umbraco").requires.push("myCustomModule");// angular.module("myCustomModule").run([ ... ]) angular.module("umbraco").run([ "umsSegmentRuleRepository", function (ruleRepo) { var rule = { name: "Day of week", // Friendly name type: "DayOfWeek", // Rule type / identifier iconUrl: "/path/to/icon.png", // You can also reuse existing Umbraco Engage icons by specifying the "icon" // property rather than the "iconUrl" property. Use either one or the other, not both. // icon: "icon-browser", order: 4, // Position in segment builder // Default config is passed in to your editor when a user adds the rule to the segment defaultConfig: { dayOfWeek: null }, // If you need any data in your editor, specify it here data: { days: { 0: "Sunday", 1: "Monday", 2: "Tuesday", 3: "Wednesday", 4: "Thursday", 5: "Friday", 6: "Saturday", } }, // Specify the names of the display and editor components here. // These will be dynamically rendered in our segment builder and in some other // places. components: { display: "segment-rule-day-of-week-display", editor: "segment-rule-day-of-week-editor", }, init: function() { // Optional. Use this in case you need to fetch some data // for your segment parameter. // For example, the built-in "Browser" segment parameter will fetch // the list of possible browsers here and will update the "data" property. // The "thisArg" of this function is set to the rule definition object, // i.e. if you use "this.data" in this callback you can manipulate the data object // of this rule. } }; ruleRepo.addRule(rule); }]);
139+
// If you have your own custom module, use this:
140+
// angular.module("myCustomModule", ["Engage"]);
141+
// angular.module("umbraco").requires.push("myCustomModule");
142+
// angular.module("myCustomModule").run([ ... ])
143+
144+
angular.module("umbraco").run([
145+
"umsSegmentRuleRepository",
146+
function (ruleRepo) {
147+
var rule = {
148+
name: "Day of week", // Friendly name
149+
type: "DayOfWeek", // Rule type / identifier
150+
151+
iconUrl: "/path/to/icon.png",
152+
// You can also reuse existing Engage icons by specifying
153+
//the "icon" property rather than the "iconUrl" property.
154+
// Use either one or the other, not both.
155+
// icon: "icon-browser",
156+
157+
order: 4, // Position in segment builder
158+
159+
// Default config is passed in to your editor when a user adds
160+
// the rule to the segment
161+
defaultConfig: {
162+
dayOfWeek: null
163+
},
164+
165+
// If you need any data in your editor, specify it here
166+
data: {
167+
days: {
168+
0: "Sunday",
169+
1: "Monday",
170+
2: "Tuesday",
171+
3: "Wednesday",
172+
4: "Thursday",
173+
5: "Friday",
174+
6: "Saturday",
175+
}
176+
},
177+
178+
// Specify the names of the display and editor components here.
179+
// These will be dynamically rendered in our segment builder and in
180+
// some other places.
181+
components: {
182+
display: "segment-rule-day-of-week-display",
183+
editor: "segment-rule-day-of-week-editor",
184+
},
185+
186+
init: function() {
187+
// Optional. Use this in case you need to fetch some data
188+
// for your segment parameter.
189+
// For example, the built-in "Browser" segment parameter will fetch
190+
// the list of possible browsers here and will update
191+
// the "data" property. The "thisArg" of this function is set to
192+
// the rule definition object, i.e. if you use "this.data" in
193+
// this callback you can manipulate the data object of this rule.
194+
}
195+
};
196+
197+
ruleRepo.addRule(rule);
198+
}
199+
]);
117200
```
118-
{% endcode %}
119201

120202
* `segment-rule-day-of-week-editor.html`
121203

@@ -129,7 +211,8 @@ We use the `data.days` property of our rule definition in the editor. The editor
129211

130212
```html
131213
<ums-segment-rule-editor name="$ctrl.rule.name" type="$ctrl.rule.type" save="$ctrl.save()">
132-
<select ng-options="value as day for (value, day) in $ctrl.rule.data.days" ng-model="$ctrl.config.dayOfWeek">
214+
<select ng-options="value as day for (value, day) in $ctrl.rule.data.days"
215+
ng-model="$ctrl.config.dayOfWeek">
133216
<option value="">- Select -</option>
134217
</select>
135218
</ums-segment-rule-editor>
@@ -140,30 +223,37 @@ We use the `data.days` property of our rule definition in the editor. The editor
140223
This registers the editor component in the Umbraco Engage module so we can use it.\
141224
It should not be necessary to update this file other than update the component name and `templateUrl`.
142225

143-
{% code overflow="wrap" %}
144226
```javascript
145-
// If you have your own custom module, use that name instead of "umbraco" here.angular.module("umbraco").component("segmentRuleDayOfWeekEditor", { templateUrl: "/App_Plugins/day-of-week/segment-rule-day-of-week-editor.html", bindings: { rule: "<", config: "<", save: "&", },});
227+
// If you have your own custom module, use that name instead of "umbraco" here.
228+
angular.module("umbraco").component("segmentRuleDayOfWeekEditor", {
229+
templateUrl: "/App_Plugins/day-of-week/segment-rule-day-of-week-editor.html",
230+
bindings: {
231+
rule: "<",
232+
config: "<",
233+
save: "&",
234+
},
235+
});
146236
```
147-
{% endcode %}
148237

149238
* `segment-rule-day-of-week-display.html`
150239

151240
This is the view file used for the visual representation of the segment parameter.\
152241
We want to display the picked day to the user:
153242

154-
{% code overflow="wrap" %}
155243
```html
156-
<span class="umbEngage-segmentrule__wrapper umbEngage-segmentrule__wrapper--thin"> <span class="umbEngage-segmentrule__rulecontent" ng-bind="$ctrl.rule.data.days[$ctrl.config.dayOfWeek]"></span></span>
244+
<span class="umbEngage-segmentrule__wrapper umbEngage-segmentrule__wrapper--thin">
245+
<span class="umbEngage-segmentrule__rulecontent"
246+
ng-bind="$ctrl.rule.data.days[$ctrl.config.dayOfWeek]"></span>
247+
</span>
157248
```
158-
{% endcode %}
159249

160250
We store the chosen day of the week as an integer 0-6 ($ctrl.config.dayOfWeek) but in the display component, we want to show the actual day (e.g. `Monday`). Our rule definition defines the mapping in its `data.days` property so we convert it using that and display the name of the day.
161251

162252
* `segment-rule-day-of-week-display.js`
163253

164254
In this file, we register the display component.
165255

166-
```
256+
```csharp
167257
// If you have a custom module, use that name instead of "umbraco"
168258
here.angular.module("umbraco").component("segmentRuleDayOfWeekDisplay",
169259
{
@@ -191,7 +281,7 @@ If all goes well you will see your custom parameter editor show up in the segmen
191281

192282
![Day of week segment parameter](../../.gitbook/assets/engage-personalization-developer1.png)
193283

194-
## 3. (Optional) Cockpit visualization
284+
## 3. \[Optional] Cockpit Visualization
195285

196286
The new segment parameter will show up automatically in the [Cockpit](../../../../personalization/cockpit-insights/) that is part of our package. The cockpit is a live view of Umbraco Engage data for the current visitor.
197287

@@ -206,7 +296,27 @@ If you want to change this to be more readable you can implement the `Umbraco.En
206296
For the `DayOfWeek` demo parameter, this is the implementation:
207297

208298
```csharp
209-
public class DayOfWeekCockpitSegmentRuleFactory : ICockpitSegmentRuleFactory{ public bool TryCreate(ISegmentRule segmentRule, bool isSatisfied, out CockpitSegmentRule cockpitSegmentRule) { cockpitSegmentRule = null; if (segmentRule is DayOfWeekSegmentRule dayOfWeekRule) { cockpitSegmentRule = new CockpitSegmentRule { Name = "Day of week", Icon = "/path/to/icon.png", Config = dayOfWeekRule.TypedConfig.DayOfWeek.ToString(), IsNegation = segmentRule.IsNegation, IsSatisfied = isSatisfied, Type = segmentRule.Type, }; return true; } return false; }}
299+
public class DayOfWeekCockpitSegmentRuleFactory : ICockpitSegmentRuleFactory
300+
{
301+
public bool TryCreate(ISegmentRule segmentRule, bool isSatisfied, out CockpitSegmentRule cockpitSegmentRule)
302+
{
303+
cockpitSegmentRule = null;
304+
if (segmentRule is DayOfWeekSegmentRule dayOfWeekRule)
305+
{
306+
cockpitSegmentRule = new CockpitSegmentRule
307+
{
308+
Name = "Day of week",
309+
Icon = "/path/to/icon.png",
310+
Config = dayOfWeekRule.TypedConfig.DayOfWeek.ToString(),
311+
IsNegation = segmentRule.IsNegation,
312+
IsSatisfied = isSatisfied,
313+
Type = segmentRule.Type,
314+
};
315+
return true;
316+
}
317+
return false;
318+
}
319+
}
210320
```
211321

212322
So we transform the JSON into a human-readable representation and we configure an icon to show up in the cockpit. Make sure to register this class in a composer (you can reuse the composer from the first step):

13/umbraco-engage/developers/profiling/external-profile-data.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,27 @@ When this component is registered a new tab will be rendered in the Profiles sec
2323

2424
To render this External Profile Tab with a custom component, you have to create your component and register it with Umbraco Engage. The following code will show how to do both. Add the below code in a JavaScript file in the `App_Plugins` folder and load it using a `package.manifest` file. If you have your own custom module, you can use this:
2525

26-
{% code overflow="wrap" %}
2726
```javascript
2827
angular.module("myCustomModule", ["Engage"]);
2928
// angular.module("umbraco").requires.push("myCustomModule");
3029
// angular.module("myCustomModule").run([ ... ])
3130
// Create a component. We create a component named "myCustomExternalProfileDataComponent" here:
3231

33-
angular.module("umbraco").component("myCustomExternalProfileDataComponent", { bindings: { visitorId: "<" }, template: "<h1>My custom external profile data component! visitorId = {{$ctrl.visitorId}}</h1>", controller: [function () { this.$onInit = function () { // Your logic here } }]});// Register your custom external profile data component.// Please note you have to use kebab-case for your component name here// just like how you would use it in an AngularJS template (i.e. myCustomComponent -> my-custom-component)angular.module("umbraco").run(["myCustomComponents", function (customComponents) { customComponents.profiles.externalProfileData = "my-custom-external-profile-data-component";}]);
32+
angular.module("umbraco").component("myCustomExternalProfileDataComponent", {
33+
bindings: { visitorId: "<" },
34+
template: "<h1>My custom external profile data component! visitorId = {{$ctrl.visitorId}}</h1>",
35+
controller: [function () {
36+
this.$onInit = function () {
37+
// Your logic here
38+
}
39+
}]
40+
});
41+
// Register your custom external profile data component.
42+
// Please note you have to use kebab-case for your component name here
43+
// just like how you would use it in an AngularJS template (i.e. myCustomComponent -> my-custom-component)
44+
angular.module("umbraco").run(["myCustomComponents", function (customComponents) {
45+
customComponents.profiles.externalProfileData = "my-custom-external-profile-data-component";
46+
}]);
3447
```
35-
{% endcode %}
3648

3749
This is all that is required to render your custom component.

0 commit comments

Comments
 (0)