1753245417
2025-07-22 18:29:00
Optimizely CMSネイティブは、さまざまなコンテンツ管理システムから知られている概念であるBranch Templatesをサポートしていません。ブランチテンプレートは、コンテンツ著者が複数のコンテンツアイテムを使用して繰り返しタスクを自動化するのを支援したい場合に役立ちます。たとえば、サブページで新しい製品ページを作成します。この問題は、exisitngページをコピーして貼り付け、コピーのコンテンツを調整することで解決できますが、問題を部分的に解決する回避策のようなものです。 Optimizely CMSのブロックの初期値については、使用できます SetDefaultValues 方法ですが、より大きな構造のためにコードからそれを管理することは痛みを伴う可能性があります。また、自動化されたサブページの作成の問題を解決しません。 CMSにブランチテンプレート機能を追加することにより、両方の問題を解決できます。
簡単なコードを追加することで実現できます。まず、新しいアイテムテンプレートを追加しましょう。フォルダーとしてのみ使用するため、フィールドは必要ありません。
[ContentType(DisplayName = "White Label Template Folder",
GUID = "2acce58b-41cc-4edc-a361-a1baa86b51bc",
Description = "A folder which allows to structure new branch templates.",
GroupName = TabNames.BranchTemplate, Order = 40)]
public class TemplateFolderPage : PageData
{
}
フォルダーアイコンを構成することもできます。
[UIDescriptorRegistration]
public class TemplateFolderPageUIDescriptor : UIDescriptor
{
public TemplateFolderPageUIDescriptor()
: base(ContentTypeCssClassNames.Folder)
{
}
}
コア機能を実装するには、以下のコードを使用できます。一言で言えば、内側 CreatedContent イベント、最初にいくつかのプレチェックを行います:
– それは「新しいアイテム」イベントですか? (コピー/ペーストオペレーションなど、コードを実行したくありません)。
– ルートの下にブランチテンプレートがあるフォルダーがありますか?
– ルートブランチテンプレートフォルダー内に現在作成されているタイプのページアイテムがありますか?
すべてのチェックが渡された場合、ブランチフォルダーからアイテムのディープコピーを作成し、それを使用して元のページを置き換えます。ページ名とurlsegmentがユニークであることを確認します。
[InitializableModule]
[ModuleDependency(typeof(InitializationModule))]
public class BranchTemplateInitialization : IInitializableModule
{
private IContentRepository _contentRepository;
private IContentLoader _contentLoader;
private UrlSegmentOptions _urlSegmentOptions;
private IUniqueIdentityCreator _uniqueIdentityCreator;
public void Initialize(InitializationEngine context)
{
var contentEvents = ServiceLocator.Current.GetInstance();
_contentRepository ??= ServiceLocator.Current.GetInstance();
_contentLoader ??= ServiceLocator.Current.GetInstance();
_urlSegmentOptions ??= ServiceLocator.Current.GetInstance();
_uniqueIdentityCreator ??= ServiceLocator.Current.GetInstance();
contentEvents.CreatedContent += ContentEvents_CreatedContent;
}
public void Uninitialize(InitializationEngine context)
{
var contentEvents = ServiceLocator.Current.GetInstance();
contentEvents.CreatedContent -= ContentEvents_CreatedContent;
}
private void ContentEvents_CreatedContent(object sender, ContentEventArgs e)
{
var saveArgs = e as SaveContentEventArgs;
if (e.Content == null || (saveArgs != null && saveArgs.MaskedAction == SaveAction.CheckOut))
{
// skip other actions like copying
return;
}
var templateFolder = _contentLoader.GetChildren(ContentReference.RootPage).FirstOrDefault();
if (templateFolder == null)
{
return;
}
// this is simplified code which only take 1st branch template item with the given type.
var myTemplateItem = _contentLoader.GetChildren(templateFolder.ContentLink)?.FirstOrDefault(x => x.ContentTypeID == e.Content.ContentTypeID);
if (myTemplateItem == null)
{
return;
}
var name = e.Content.Name;
var oldItemLink = e.ContentLink;
var parentLink = e.Content.ParentLink;
var newItemLink = _contentRepository.Copy(myTemplateItem.ContentLink, parentLink, AccessLevel.NoAccess, AccessLevel.NoAccess, false);
var newItem = _contentRepository.Get(newItemLink);
_contentRepository.Delete(oldItemLink, true);
// rename page name and url segment to the one entered by author
var newPage = newItem.CreateWritableClone();
// we need to rename to new name and before forcing uniqueness
newPage.Name = name;
newPage.URLSegment = name;
newPage.Name = _uniqueIdentityCreator.CreateName(newPage, name);
newPage.URLSegment = _uniqueIdentityCreator.CreateURLSegment(newPage, _urlSegmentOptions);
_contentRepository.Save(newPage, SaveAction.Default, AccessLevel.NoAccess);
// update content link to point to new item
e.ContentLink = newItemLink;
e.Content = newItem;
}
}
それを機能させるには、タイプのフォルダーを作成する必要があります TemplateFolderPage ルート(「製品ウィザード」と呼ばれます)の下で、そのフォルダー内で、選択したタイプと事前定義されたレイアウトの新しいページを作成します(「シンプルな製品テンプレート」と呼び、「製品ページ」タイプを使用しましたが、これは単なる例です)。また、「Gallery」というサブページを独自のレイアウトで追加しました。この構造は、すべての新製品ページのテンプレートとして機能します。
コードを導入すると、標準の「新しいページ」ダイアログを使用してW New “Product Page”アイテムを作成できるようになりました。指定された名前とURLセグメントの下に新しい製品ページを作成する必要がありますが、事前定義されたレイアウトとギャラリーサブページが内部にあります。
#Optimizely #CMSの分岐テンプレート