-
Notifications
You must be signed in to change notification settings - Fork 5
/
d95842e2-484a-4386-9001-7fa003b5b871.xml
152 lines (115 loc) · 6.64 KB
/
d95842e2-484a-4386-9001-7fa003b5b871.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?xml version="1.0" encoding="utf-8"?>
<contentitemdata.kenticocommunity.blogpostcontent>
<BlogPostContentAuthor>
<![CDATA[[{"Identifier":"f9ac36a5-e1a6-4d21-9cb7-beb385d0fea0"}]]]>
</BlogPostContentAuthor>
<BlogPostContentContentMarkdown>
<![CDATA[
## CD Exclusions
When using Xperience by Kentico's CI/CD functionality, we can specify [object exclusions](https://docs.xperience.io/x/ygAcCQ) in our `repository.config` file - this works for both the CI and CD config files.
I generally don't recommend excluding content from CI since this is how you stay in sync with your development team.
But excluding content from CD is very common since the content we create in our local environments for testing functionality might not be appropriate for production 😅.
### Exclude by Object Type
We can exclude full object types by specific their type name.
```xml
<ExcludedObjectTypes>
<ObjectType>emaillibrary.emailchannelsender</ObjectType>
</ExcludedObjectTypes>
```
This works great for custom module [Object Types](https://docs.xperience.io/x/AKDWCQ) where all objects are represented by a single type name. For example, we can exclude all "Office Location" records from CD with a single line.
However, this is less helpful when we want to exclude sets of Content items or Web pages - that's because these excludes target the Object Type, no the Content Type. We can't use `<ObjectType>DancingGoat.CoffeePage</ObjectType>` to exclude all Coffee Web pages - that's not the Object Type of Web pages - `cms.webpageitem` is 😔. We also want to exclude the "content" part of a Web page - the Content Item - which has an Object Type `cms.contentitem`.
So, what do we do if we want to exclude all Coffee Web pages from CD?
### Exclude by Object Filter
Fortunately we can exclude more granularly using the `<ObjectFilter>` portion of our `repository.config`.
Unfortunately, we need to target an object code name, like this.
```xml
<ObjectFilters>
<!-- Excludes the "articles" and "graphics" media libararies -->
<ExcludedCodeNames ObjectType="media.library">articles;graphics</ExcludedCodeNames>
</ObjectFilters>
```
We can use wildcard `%` characters at the beginning or end of the code name value here, but the code names of Web pages are automatically generated by Xperience so it's going to be difficult to target something consistently.
But of course, Xperience by Kentico is known for its customization! We can use [global events](https://docs.xperience.io/x/r4t1CQ) to hook into the saving process for Web pages and modify their code names to something we can target with the `<ExcludedCodeNames>` filter.
## [#](#global-events) Global Events
To hook into global events, we first need a [Module](https://docs.xperience.io/x/Q4XWCQ).
```csharp
[assembly: RegisterModule(typeof(ApplicationModule))]
namespace DancingGoat;
public class ApplicationModule : Module
{
public ApplicationModule() : base(nameof(ApplicationModule)) { }
// ...
}
```
Now, we need to add our event handler in the `OnInit()` method.
```csharp
protected override void OnInit()
{
base.OnInit();
var env = Service.Resolve<IWebHostEnvironment>();
/*
* Ensure all pages that should be excluded from CD
* deployments end in the correct code name
*/
if (env.IsDevelopment())
{
WebPageEvents.Create.Before += EnsureLocalCodeNames;
}
}
```
We make sure that we only execute this event in "Development" environments - we don't need to mess with code names in QA/UAT/Production.
Now let's create our `EnsureLocalCodeNames` event handler method.
```sharp
private void EnsureLocalCodeNames(object sender, CreateWebPageEventArgs e)
{
if (string.Equals(e.ContentTypeName, CoffeePage.CONTENT_TYPE_NAME))
{
if (e.Name.EndsWith("-localtest"))
{
return;
}
e.Name = e.Name[..Math.Min(90, e.Name.Length)] + "-localtest";
}
}
```
Code names can be up to 100 characters for Web pages, so we limit the name to 90 characters max and then add `-localtest` to the end.
:::note
Xperience adds a random series of 8 characters to the end of every auto generated code name value. This is done to prevent conflicts in code names, which must be unique.
We could update our logic to ensure we don't remove that uniqueness from the end of a code name - I'll leave this up to the reader 😉.
It's also worth noting that we don't handle update events. The code name is generated from the content item name but only on creation. After that it's not updated. And, we probably want to let developers set a fully custom code name if they want to.
:::
## [#](#modify-our-exclusions) Modify Our Exclusions
Now that we have our custom module and global event handler in the project, we can update our CD `repository.config` file to exclude items that match our new code name pattern.
```xml
<ObjectFilters>
<ExcludedCodeNames ObjectType="cms.webpageitem">%-localtest</ExcludedCodeNames>
<ExcludedCodeNames ObjectType="cms.contentitem">%-localtest</ExcludedCodeNames>
</ObjectFilters>
```
And, with that, we're all set!
If we need to exclude other items in the future, we can update our global event handler and add some logic to account for new Content types or other contextual information.
]]>
</BlogPostContentContentMarkdown>
<BlogPostContentPublishedDate>2023-10-21 19:48:00Z</BlogPostContentPublishedDate>
<BlogPostContentShortDescription>
<![CDATA[Trying to keep your local test content from being deployed to other environments? Not sure how to leverage Xperince by Kentico's CI/CD object exclusions for Content items and Web Pages? Read on to learn a simple solution.]]>
</BlogPostContentShortDescription>
<BlogPostContentTaxonomy>Article</BlogPostContentTaxonomy>
<BlogPostContentTeaserMediaFileImage>
<![CDATA[[{"Identifier":"1441c1a7-37b5-45ac-a7d5-be3dc6f9a8c9","Name":"kentico-background.webp","Size":99376,"Dimensions":{"Width":5000,"Height":2960}}]]]>
</BlogPostContentTeaserMediaFileImage>
<BlogPostContentTitle>
<![CDATA[Excluding Content Items from Continuous Deployment using Global Events]]>
</BlogPostContentTitle>
<BlogPostPageContentSourceType>markdown</BlogPostPageContentSourceType>
<ContentItemDataCommonDataID>
<GUID>d7759517-4202-44d3-aa17-a23597e8cf7d</GUID>
<ObjectType>cms.contentitemcommondata</ObjectType>
<Parent>
<CodeName>ExcludingContentItemsFromContinuousDeploymentUsingGlobalEvents-p07bvgpx-localtest</CodeName>
<GUID>c25fb8dc-b89d-4ce4-97eb-cbdbba842dee</GUID>
<ObjectType>cms.contentitem</ObjectType>
</Parent>
</ContentItemDataCommonDataID>
<ContentItemDataGUID>d95842e2-484a-4386-9001-7fa003b5b871</ContentItemDataGUID>
</contentitemdata.kenticocommunity.blogpostcontent>