Extend the import pipeline
You can extend the import pipeline for the code-first workflow to customize various aspects of your application's data.
This procedure shows you how to extend the import process to allow customizing the path of templates you create.
To extend the import pipeline:
-
Extend your manifest data by adding your component to the JSS Manifest.
RequestResponseexport default manifest => { manifest.addComponent({ name: "Welcome", // we added this property to our welcome component path: "/sitecore/templates/Welcome", fields: [ { name: "title", type: manifest.fieldTypes.singleLineText }, ] }); };
-
To make the custom path work, you must extend the import pipeline to alter how templates are created by the import process. Specifically, you must target the
ProcessTemplates
processor in theimport
pipeline, derive from it, and alter its behavior. For example:RequestResponseusing System; using Sitecore.Data.Items; using Sitecore.Diagnostics; using Sitecore.JavaScriptServices.AppServices.Data; using Sitecore.JavaScriptServices.AppServices.Extensions; using Sitecore.JavaScriptServices.AppServices.Models; using Sitecore.JavaScriptServices.Configuration; namespace Sitecore.JavaScriptServices.AppServices.Pipelines.Import { public class ProcessTemplatesWithPath : ProcessTemplates { protected override TemplateItem CreateTemplate(TemplateDef templateDef, Item parent, Item multilistRoot, AppConfiguration app, IdManager idManager) { // the AdditionalData property is a dictionary of any JSON properties that were _not_ mapped to a TemplateDef property // so our path property - and any other custom properties that are added - will show up here. It will be null if no unmapped // properties exist so make sure to check everything for nulls with ? // // All import pipeline model objects have an AdditionalData property like this. var path = templateDef.AdditionalData?["path"]?.ToString(); // path not set, use default behavior if (path == null) return base.CreateTemplate(templateDef, parent, multilistRoot, app, idManager); // resolve the custom path's parent (to keep things simple, we're not creating any parent hierarchy) var parentItemPath = path.Substring(0, path.LastIndexOf("/")); var customParentItem = parent.Database.GetItem(parentItemPath, parent.Language); if (customParentItem == null) throw new InvalidOperationException($"Parent item for custom import path item {templateDef.Name} ({path}) did not exist."); var templateName = ItemUtil.ProposeValidItemName(templateDef.Name); // JSS imports use _consistent IDs_ so that imports across instances use the same Sitecore item GUIDs // This code generates the consistent ID and ensures that it is unique. var templateId = idManager.GetTemplateId(app.Name, templateDef); idManager.AssertIdIsUnused(templateId, $"template {templateDef.Name}"); // ensure we have permissions to create the item if (!customParentItem.CanImportChild(templateName, templateId, out var templateItem)) { return null; } if (templateItem == null) { Log.Info($"[JSS] - Creating template - {templateName} (Custom path: {path})", this); templateItem = parent.Database.Templates.CreateTemplate(templateName, customParentItem); // make the db see our new template parent.Database.Engines.TemplateEngine.Reset(); } else { Log.Debug($"[JSS] - Found existing template - {templateName}", this); } // sets the requisite fields on the template item UpdateTemplateItem(templateItem, templateDef, parent, multilistRoot, app, idManager, templateItem.DisplayName); return templateItem; } } }
-
You must now tell Sitecore to use the custom processor
ProcessTemplatesWithPath
instead of the defaultProcessTemplates
processor. Create a configuration patch, for exampleApp_Config/Include/PickAnyFileName.config
and add the following configuration:RequestResponse<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/"> <sitecore role:require="ContentManagement or Standalone"> <pipelines> <group groupName="javaScriptServices"> <pipelines> <import> <processor type="Sitecore.JavaScriptServices.AppServices.Pipelines.Import.ProcessTemplatesWithPath, Sitecore.JavaScriptServices.AppServices" patch:instead="*[contains(@type, 'ProcessTemplates')]" /> </import> </pipelines> </group> </pipelines> </sitecore> </configuration>
-
Deploy your JSS app:
-
If this is the first time deploying the app, in a terminal, run the following command:
RequestResponsejss deploy app -c
-
Otherwise, run the following command:
RequestResponsejss deploy items
NoteWhen you run one of the scripts, JSS generates the manifest automatically in the file
sitecore/manifest/sitecore-import.json
.The script outputs among other things, a message similar to the following:
RequestResponse[JSS] - Creating template - Welcome (Custom path: /sitecore/templates/Welcome)
-
-
In the Sitecore content tree, verify that the template was created at the path you requested.
NoteIf you previously deployed your JSS app and have an existing template item in the default location, remove it and change any usage of it to the new template.