public override void Transform(Engine engine, Package package) { Initialize(engine, package); // The input Component is used to relate some of the generated Binaries to (so they get unpublished if the Component is unpublished). Component inputComponent = GetComponent(); _configStructureGroup = GetSystemStructureGroup("config"); List <Binary> binaries = new List <Binary>() { PublishTaxonomyMappings(inputComponent) }; //For each active module, publish the config and add the filename(s) to the bootstrap list foreach (KeyValuePair <string, Component> module in GetActiveModules()) { string moduleName = module.Key; Component moduleConfigComponent = module.Value; Folder moduleFolder = GetModuleFolder(moduleConfigComponent); binaries.Add(PublishModuleConfig(moduleName, moduleConfigComponent)); binaries.Add(PublishModuleSchemasConfig(moduleName, moduleFolder, moduleConfigComponent)); binaries.Add(PublishModuleTemplatesConfig(moduleName, moduleFolder, moduleConfigComponent)); } // Remove empty/null entries binaries = binaries.Where(b => b != null).ToList(); //Publish the boostrap list, this is used by the web application to load in all other configuration files binaries.Add(PublishLocalizationData(binaries, inputComponent)); OutputSummary("Publish Configuration", binaries.Select(b => b.Url)); }
/// <summary> /// Add binaries from a given folder (and subfolders recursively) to the package /// publish them and update the package item with the publish path /// </summary> /// <param name="rootSGWebDavUrl">Root Structure Group to add in</param> /// <param name="folder">Root folder to look in</param> /// <param name="path">path from root structure group to add in</param> protected void AddBinariesFromFolder(string rootSGWebDavUrl, Folder folder, string path) { StructureGroup sg = null; //Loop through all components in the folder foreach (KeyValuePair <TcmUri, string> item in GetOrganizationalItemContents(folder, ItemType.Component, false)) { Component mmComp; mmComp = m_Engine.GetObject(item.Key) as Component; //if its a MM comp then add it to the package, and publish it if (mmComp.ComponentType == ComponentType.Multimedia) { if (sg == null) { //Try to get a reference to the sub Structure Group based on the folder title sg = m_Engine.GetObject(rootSGWebDavUrl + path) as StructureGroup; if (sg == null) { Exception ex = new Exception(String.Format("Could not find Structure Group {0}. Please create this and republish", rootSGWebDavUrl + path)); Logger.Error(ex.Message); throw ex; } } AddBinary(mmComp, sg); } } //Loop through all subfolders to recurse foreach (KeyValuePair <TcmUri, string> item in GetOrganizationalItemContents(folder, ItemType.Folder, false)) { Logger.Info(String.Format("Processing subfolder: {0} ({1})", item.Value, item.Key)); Folder subFolder = m_Engine.GetObject(item.Key) as Folder; AddBinariesFromFolder(rootSGWebDavUrl, subFolder, path + "/" + subFolder.Title); } }
private Binary PublishXpmRegionConfiguration(StructureGroup structureGroup, Component relatedComponent) { IDictionary <string, XpmRegionData> xpmRegions = new Dictionary <string, XpmRegionData>(); foreach (ComponentTemplate ct in Publication.GetComponentTemplates()) { string regionName = GetRegionName(ct); XpmRegionData xpmRegion; if (!xpmRegions.TryGetValue(regionName, out xpmRegion)) { xpmRegion = new XpmRegionData { Region = regionName, ComponentTypes = new List <XpmComponentTypeData>() }; xpmRegions.Add(regionName, xpmRegion); } string templateId = ct.Id.GetVersionlessUri().ToString(); IEnumerable <XpmComponentTypeData> allowedComponentTypes = ct.RelatedSchemas.Select( schema => new XpmComponentTypeData { Schema = schema.Id.GetVersionlessUri().ToString(), Template = templateId } ); xpmRegion.ComponentTypes.AddRange(allowedComponentTypes); } return(AddJsonBinary(xpmRegions.Values, relatedComponent, structureGroup, "regions")); }
private void AddNodes(XmlElement context, StructureGroup sg, string baseUrl) { XmlElement sgElmt = CreateElement(context, sg.Id, CreateUrl(baseUrl,sg.Directory), sg.Title, sg.Title); Logger.Debug("started AddNodes for sg " + sg.Title + ", with calculated url " + CreateUrl(baseUrl,sg.Directory)); foreach (RepositoryLocalObject item in sg.GetItems()) { string url; if (item is Page) { Page p = (Page)item; url = CreateUrl(baseUrl, sg.Directory, p.FileName + "." + p.PageTemplate.FileExtension); if (p.FileName.Equals("index")) { // this is the index page of the current structure group sgElmt.SetAttribute("url", url); sgElmt.SetAttribute("pageId", p.Id); } else { XmlElement pageElmt = CreateElement(sgElmt, p.Id, url, p.Title, p.Title); pageElmt.SetAttribute("pageId", p.Id); } } else if (item is StructureGroup) { AddNodes(sgElmt, (StructureGroup)item, CreateUrl(baseUrl, sg.Directory)); } } }
private StructureGroup FindOrCreateSG(Engine engine, string sgWebDav) { log.Debug(string.Format("Find or Create SG '{0}'", sgWebDav)); StructureGroup sg = engine.GetObject(sgWebDav) as StructureGroup; if (sg == null) { int lastSlash = sgWebDav.LastIndexOf("/"); string parentSGWebDav = sgWebDav.Substring(0, lastSlash); StructureGroup parentSG = FindOrCreateSG(engine, parentSGWebDav); Session newSession = new Session(engine.GetSession().User.Title); sg = new StructureGroup(newSession, parentSG.Id); string title = sgWebDav.Substring(lastSlash + 1); sg.Title = MakeSafeSGTitle(title); sg.Directory = MakeSafeDirectory(title); sg.Save(); newSession.Dispose(); log.Debug(string.Format("Created SG '{0}'", sgWebDav)); } else { log.Debug(string.Format("Found SG '{0}'", sgWebDav)); } return(sg); }
public void Transform(Engine engine, Package package) { //Initialize this.engine = engine; this.package = package; Page page = null; Item pageItem = package.GetByType(ContentType.Page); if (pageItem != null) { page = engine.GetObject(pageItem.GetAsSource().GetValue("ID")) as Page; } else { throw new InvalidOperationException("No Page found. Verify that this template is used with a Page."); } // Get the publication object Publication mainPub = page.ContextRepository as Publication; StructureGroup rootSg = mainPub.RootStructureGroup; XmlDocument sitemapDoc = GenerateSitemap(rootSg); // Put the translate lables component into the package package.PushItem(Package.OutputName, package.CreateXmlDocumentItem(ContentType.Xml, sitemapDoc)); }
private SitemapItem GenerateStructureGroupNavigation(StructureGroup startPoint) { SitemapItem root = GenerateFolderNode(startPoint); IEnumerable <XElement> orderedDocument = GetItemsInFolderAsAList(startPoint); foreach (XElement pgNode in orderedDocument) { Page page = Engine.GetObject(pgNode.Attribute("ID").Value) as Page; if (page != null) { if (IsPublished(page) && !IsSystem(pgNode.Attribute("Title").Value)) { root.Items.Add(GeneratePageNode(page)); } } else { if (!IsSystem(pgNode.Attribute("Title").Value)) { root.Items.Add(GenerateStructureGroupNavigation(Engine.GetObject(pgNode.Attribute("ID").Value) as StructureGroup)); } } } return(root); }
public void BuildPageModel(ref PageModelData pageModelData, Page page) { Logger.Debug("Adding structure group metadata to page model metadata."); StructureGroup structureGroup = (StructureGroup)page.OrganizationalItem; List <string> schemaIdList = new List <string>(); // Checking for Schema Metadata is very important because we need to stop adding metadata as soon as we found page without it while (structureGroup != null && structureGroup.MetadataSchema != null) { schemaIdList.Insert(0, new TcmUri(structureGroup.MetadataSchema.Id).ItemId.ToString()); if (structureGroup.Metadata != null) { ContentModelData metaData = BuildContentModel(structureGroup.Metadata, Pipeline.Settings.ExpandLinkDepth); string[] duplicateFieldNames; ContentModelData pmdMetadata = pageModelData.Metadata ?? new ContentModelData(); pageModelData.Metadata = MergeFields(pmdMetadata, metaData, out duplicateFieldNames); } structureGroup = structureGroup.OrganizationalItem as StructureGroup; } ViewModelData vm = pageModelData as ViewModelData; CreateSchemaIdListExtensionData(ref vm, schemaIdList); }
protected IList <Page> GetPagesInSG(ListItem sg) { CheckInitialized(); Filter filter = new Filter(); filter.Conditions["ItemType"] = ItemType.Page; filter.BaseColumns = ListBaseColumns.Extended; filter.AdditionalColumns.Add("url"); filter.AdditionalColumns.Add("path"); // TODO: find a way to avoid retrieving the SG StructureGroup structuregroup = MEngine.GetObject(sg.Id) as StructureGroup; OrganizationalItemItemsFilter pageFilter = new OrganizationalItemItemsFilter(filter, structuregroup.Session); IList <RepositoryLocalObject> rlos = (IList <RepositoryLocalObject>)structuregroup.GetItems(pageFilter); List <Page> pages = new List <Page>(rlos.Count); foreach (RepositoryLocalObject o in rlos) { pages.Add((Page)o); } return(pages); }
private string GetLinkToSgIndexPage(StructureGroup sg, Session session) { OrganizationalItemItemsFilter filter = new OrganizationalItemItemsFilter(session) { ItemTypes = new[] { ItemType.Page } }; string title = StripNumbersFromTitle(sg.Title); const string pageLinkFormat = "<a tridion:href=\"{0}\">{1}</a>"; string result = null; foreach (XmlElement page in sg.GetListItems(filter).ChildNodes) { if (!page.Attributes["Title"].Value.ToLower().Contains(IndexPagePattern)) { continue; } result = string.Format(pageLinkFormat, page.Attributes["ID"].Value, title); break; } if (string.IsNullOrEmpty(result)) { result = title; } return(result); }
public override void Transform(Engine engine, Package package) { Initialize(engine, package); // The input Component is used to relate some of the generated Binaries to (so they get unpublished if the Component is unpublished). Component inputComponent = GetComponent(); _configStructureGroup = GetSystemStructureGroup("config"); List<Binary> binaries = new List<Binary>() { PublishTaxonomyMappings(inputComponent) }; //For each active module, publish the config and add the filename(s) to the bootstrap list foreach (KeyValuePair<string, Component> module in GetActiveModules()) { string moduleName = module.Key; Component moduleConfigComponent = module.Value; Folder moduleFolder = GetModuleFolder(moduleConfigComponent); binaries.Add(PublishModuleConfig(moduleName, moduleConfigComponent)); binaries.Add(PublishModuleSchemasConfig(moduleName, moduleFolder, moduleConfigComponent)); binaries.Add(PublishModuleTemplatesConfig(moduleName, moduleFolder, moduleConfigComponent)); } // Remove empty/null entries binaries = binaries.Where(b => b != null).ToList(); //Publish the boostrap list, this is used by the web application to load in all other configuration files binaries.Add(PublishLocalizationData(binaries, inputComponent)); OutputSummary("Publish Configuration", binaries.Select(b => b.Url)); }
/// <summary> /// Overrides the TemplateBase method Transform. Implements actual logic -- identifies Root Structure Group /// of current Publication and kicks off recursive building of navigation XML. /// The generated XmlDocument is added to the Package as element "Output". /// </summary> /// <param name="engine"></param> /// <param name="package"></param> public override void Transform(Engine engine, Package package) { DateTime t = DateTime.Now; Initialize(engine, package); Publication publication = GetPublication(); StructureGroup rootSG = publication.RootStructureGroup; filter = new OrganizationalItemItemsFilter(rootSG.Session) { BaseColumns = ListBaseColumns.IdAndTitle, ItemTypes = new ItemType[] { ItemType.Page, ItemType.StructureGroup }, Recursive = true }; XmlElement navigationXml = BuildNavigationGetItems(rootSG); //record build navigation time string message = string.Format("Execution took {0:0.##}s", DateTime.Now.Subtract(t).TotalSeconds); navigationXml.AppendChild(navigationXml.OwnerDocument.CreateComment(message)); package.PushItem("Output", package.CreateXmlDocumentItem(ContentType.Xml, navigationXml.OwnerDocument)); }
/// <summary> /// Builds a Page Data Model from a given CM Page object. /// </summary> /// <param name="pageModelData">The Page Data Model to build. Is <c>null</c> for the first Model Builder in the pipeline.</param> /// <param name="page">The CM Page.</param> /// <remarks> /// This Model Builder is designed to be the first in the pipeline and hence ignores the <paramref name="pageModelData"/> input value. /// </remarks> public void BuildPageModel(ref PageModelData pageModelData, Page page) { Logger.Debug($"BuildPageModel({page})"); if (page == null) { pageModelData = null; return; } // We need Keyword XLinks for Keyword field expansion page.Load(LoadFlags.KeywordXlinks); StructureGroup structureGroup = (StructureGroup)page.OrganizationalItem; PageTemplate pt = page.PageTemplate; IDictionary <string, RegionModelData> regionModels = new Dictionary <string, RegionModelData>(); AddPredefinedRegions(regionModels, pt); AddComponentPresentationRegions(regionModels, page); if (Utility.IsNativeRegionsAvailable(page)) { var nativeRegionModels = GetNativeRegions(page.GetPropertyValue <IList <IRegion> >("Regions")); MergeNativeRegions(regionModels, nativeRegionModels); } AddIncludePageRegions(regionModels, pt); // Merge Page metadata and PT custom metadata ContentModelData ptCustomMetadata = ExtractCustomMetadata(pt.Metadata, excludeFields: _standardPageTemplateMetadataFields); ContentModelData pageMetadata = BuildContentModel(page.Metadata, Pipeline.Settings.ExpandLinkDepth); string[] duplicateFieldNames; ContentModelData pageModelMetadata = MergeFields(pageMetadata, ptCustomMetadata, out duplicateFieldNames); if (duplicateFieldNames.Length > 0) { string formattedDuplicateFieldNames = string.Join(", ", duplicateFieldNames); Logger.Debug($"Some custom metadata fields from {pt.FormatIdentifier()} are overridden by Page metadata: {formattedDuplicateFieldNames}"); } string sequencePrefix; pageModelData = new PageModelData { Id = GetDxaIdentifier(page), PageTemplate = GetPageTemplateData(pt), StructureGroupId = GetDxaIdentifier(structureGroup), SchemaId = GetDxaIdentifier(page.MetadataSchema), Meta = null, // Default Model builder does not set PageModel.Meta; see DefaultPageMetaModelBuilder. Title = StripSequencePrefix(page.Title, out sequencePrefix), // See DefaultPageMetaModelBuilder UrlPath = GetUrlPath(page), Regions = regionModels.Values.ToList(), Metadata = pageModelMetadata, MvcData = GetPageMvcData(pt), XpmMetadata = GetXpmMetadata(page) }; }
protected override void TransformPage(Dynamic.Page page) { Page tcmPage = this.GetTcmPage(); StructureGroup tcmSG = (StructureGroup)tcmPage.OrganizationalItem; String mergeActionStr = Package.GetValue("MergeAction"); Dynamic.MergeAction mergeAction; if (string.IsNullOrEmpty(mergeActionStr)) { mergeAction = defaultMergeAction; } else { mergeAction = (Dynamic.MergeAction)Enum.Parse(typeof(Dynamic.MergeAction), mergeActionStr); } while (tcmSG.OrganizationalItem != null) { if (tcmSG.MetadataSchema != null) { TCM.Fields.ItemFields tcmFields = new TCM.Fields.ItemFields(tcmSG.Metadata, tcmSG.MetadataSchema); // change Builder.FieldsBuilder.AddFields(page.Metadata, tcmFields, 1, false, mergeAction, manager); } tcmSG = (StructureGroup)tcmSG.OrganizationalItem; } }
private void AddNodes(XmlElement context, StructureGroup sg, string baseUrl) { XmlElement sgElmt = CreateElement(context, sg.Id, CreateUrl(baseUrl, sg.Directory), sg.Title, sg.Title); Logger.Debug("started AddNodes for sg " + sg.Title + ", with calculated url " + CreateUrl(baseUrl, sg.Directory)); foreach (RepositoryLocalObject item in sg.GetItems()) { string url; if (item is Page) { Page p = (Page)item; url = CreateUrl(baseUrl, sg.Directory, p.FileName + "." + p.PageTemplate.FileExtension); if (p.FileName.Equals("index")) { // this is the index page of the current structure group sgElmt.SetAttribute("url", url); sgElmt.SetAttribute("pageId", p.Id); } else { XmlElement pageElmt = CreateElement(sgElmt, p.Id, url, p.Title, p.Title); pageElmt.SetAttribute("pageId", p.Id); } } else if (item is StructureGroup) { AddNodes(sgElmt, (StructureGroup)item, CreateUrl(baseUrl, sg.Directory)); } } }
protected Binary AddJsonBinary(object objectToSerialize, Component relatedComponent, StructureGroup structureGroup, string name, string variantId = null) { //In unittest there may not be a PublishingContext if (Engine.PublishingContext == null) { return(null); } if (string.IsNullOrEmpty(variantId)) { variantId = name; } string json = JsonSerialize(objectToSerialize, IsPreview | IsXpmEnabled); Item jsonItem = Package.CreateStringItem(ContentType.Text, json); Binary jsonBinary = Engine.PublishingContext.RenderedItem.AddBinary(jsonItem.GetAsStream(), name + JsonExtension, structureGroup, variantId, relatedComponent, JsonMimetype); jsonItem.Properties[Item.ItemPropertyPublishedPath] = jsonBinary.Url; Package.PushItem(jsonBinary.Url, jsonItem); Logger.Info(string.Format("Added JSON Binary '{0}' related to Component '{1}' ({2}) with variant ID '{3}'", jsonBinary.Url, relatedComponent.Title, relatedComponent.Id, variantId)); return(jsonBinary); }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <returns></returns> protected override StructureGroup GetGroup(string name) { if (_group == null) { _group = new StructureGroup("GenericStructure"); } return(_group); }
/// <summary> /// Execute the transformation for the specified template /// </summary> /// <param name="Engine"><see cref="T:Tridion.ContentManager.Templating.Engine"/>.</param> /// <param name="Package"><see cref="T:Tridion.ContentManager.Templating.Package"/></param> public void Transform(Engine Engine, Package Package) { try { mTicksStart = Environment.TickCount; mEngine = Engine; mPackage = Package; // Actual template transformation PreTransform(); Transform(); PostTransform(); } catch (Exception ex) { String exceptionStack = LoggerExtensions.TraceException(ex); Logger.Error("TemplateBase.Transform Exception\n" + exceptionStack); StringBuilder sb = new StringBuilder(); sb.AppendLine(ex.Message); sb.AppendFormat("Publisher: {0}\n", Environment.MachineName); sb.Append(exceptionStack); // Re-throw to ensure Tridion knows what happened throw new Exception(sb.ToString(), ex); } // Ensure we always clean up, no matter what happens during the template transformation finally { Logger.Info("{0}: Render time {1:0.00000} seconds @ {2:dd/MM/yyyy hh:mm:ss tt} ", this.GetType().FullName, ProcessedTime / 1000.0, DateTime.Now); // Do not cache objects across template transformations ItemFieldsFactory.ClearCache(); // Clear published binaries list if it was used if (mPublishedBinaries.IsValueCreated) { mPublishedBinaries.Value.Clear(); } mPackage = null; mEngine = null; mLogger = null; mComponent = null; mComponentTemplate = null; mPage = null; mPageTemplate = null; mRootStructureGroup = null; mPublication = null; mPublishTransaction = null; mPublishingUser = null; mPublicationTarget = null; } }
protected string PublishJson(string json, Component relatedComponent, StructureGroup sg, string filename, string variantName) { Item jsonItem = Package.CreateStringItem(ContentType.Text, json); Binary binary = Engine.PublishingContext.RenderedItem.AddBinary(jsonItem.GetAsStream(), filename + JsonExtension, sg, variantName, relatedComponent, JsonMimetype); jsonItem.Properties[Item.ItemPropertyPublishedPath] = binary.Url; Package.PushItem(binary.Url, jsonItem); return(JsonEncode(binary.Url)); }
protected virtual void PublishItem(Item item, TcmUri itemUri) { Stream itemStream = null; // See if some template set itself as the applied template on this item TcmUri appliedTemplateUri = null; if (item.Properties.ContainsKey(Item.ItemPropertyTemplateUri)) { appliedTemplateUri = new TcmUri(item.Properties[Item.ItemPropertyTemplateUri]); } try { string publishedPath; if (targetStructureGroupUri == null) { log.Debug("no structure group defined, publishing binary with default settings"); Component mmComp = (Component)engine.GetObject(item.Properties[Item.ItemPropertyTcmUri]); // Note: it is dangerous to specify the CT URI as variant ID without a structure group, because it will fail if you publish the same MMC from two or more CTs! // So I removed the variant ID altogether (QS, 20-10-2011) log.Debug(string.Format("publishing mm component {0} without variant id", mmComp.Id)); Binary binary = engine.PublishingContext.RenderedItem.AddBinary(mmComp); publishedPath = binary.Url; log.Debug(string.Format("binary is published to url {0}", publishedPath)); } else { Component mmComp = (Component)engine.GetObject(item.Properties[Item.ItemPropertyTcmUri]); string fileName = ConstructFileName(mmComp, currentTemplate.Id); StructureGroup targetSG = (StructureGroup)engine.GetObject(targetStructureGroupUri); itemStream = item.GetAsStream(); if (itemStream == null) { // All items can be converted to a stream? log.Error(String.Format("Cannot get item '{0}' as stream", itemUri.ToString())); } //byte[] data = new byte[itemStream.Length]; //itemStream.Read(data, 0, data.Length); //itemStream.Close(); log.Debug(string.Format("publishing mm component {0} to structure group {1} with variant id {2} and filename {3}", mmComp.Id, targetStructureGroupUri.ToString(), currentTemplate.Id, fileName)); Binary b = engine.PublishingContext.RenderedItem.AddBinary(item.GetAsStream(), fileName, targetSG, currentTemplate.Id, mmComp, mmComp.BinaryContent.MultimediaType.MimeType); publishedPath = b.Url; //publishedPath = engine.AddBinary(itemUri, appliedTemplateUri, targetStructureGroupUri, data, fileName); log.Debug(string.Format("binary is published to url {0}", publishedPath)); } log.Debug("binary published, published path = " + publishedPath); item.Properties[Item.ItemPropertyPublishedPath] = publishedPath; } finally { if (itemStream != null) { itemStream.Close(); } } }
/// <summary> /// Enhance the XmlElement corresponding to a Structure Group with information such as DisplayTitle, URL, etc. /// </summary> /// <param name="item">XmlElement to be enhanced</param> /// <param name="structureGroup">StructureGroup to enhance from</param> private void EnhanceNode(XmlElement item, StructureGroup structureGroup) { string displayTitle = navigationItemRegex.Replace(structureGroup.Title, ""); item.SetAttribute(ATTRIBUTE_DISPLAY_TITLE, displayTitle); string url = structureGroup.PublishLocationUrl; item.SetAttribute(ATTRIBUTE_URL, url); }
protected virtual string ProcessModule(string moduleName, Component module, StructureGroup sg) { Dictionary<string, string> data = new Dictionary<string, string>(); ItemFields fields = new ItemFields(module.Content, module.Schema); foreach (var configComp in fields.GetComponentValues("furtherConfiguration")) { data = MergeData(data, ReadComponentData(configComp)); } return PublishJsonData(data, module, moduleName, "config", sg); }
private Page GetIndexPageFromStrucuteGroup(StructureGroup structureGroup) { string tcmidIndexPage = string.Empty; var items = GetStructureGroupItems(structureGroup, new[] { ItemType.Page }); var indexPage = items.OfType <Page>().FirstOrDefault(item => GetPageName(item.PublishLocationUrl).ToLower().Equals(DefaultPage)); //tcmidIndexPage = indexPage != null ? indexPage.Id : string.Empty; return(indexPage); }
public void StructureGroupRead() { StructureGroup structureGroup = mClient.GetStructureGroup("tcm:2-3-4"); // Structure group Loaded Assert.IsNotNull(structureGroup, "Structure Group is null"); // Structure Group Title is correct Assert.AreEqual("Website Root", structureGroup.Title); }
private IEnumerable <RepositoryLocalObject> GetStructureGroupItems(StructureGroup structureGroup, IEnumerable <ItemType> itemTypeFilter = null) { var filter = new OrganizationalItemItemsFilter(structureGroup.Session); filter.ItemTypes = itemTypeFilter ?? _itemTypeFilter; var items = structureGroup.GetItems(filter); return(items); }
protected StructureGroup GetSystemStructureGroup(string subStructureGroupTitle = null) { string webdavUrl = String.Format("{0}/_System{1}", GetPublication().RootStructureGroup.WebDavUrl, subStructureGroupTitle == null ? "" : "/" + subStructureGroupTitle); StructureGroup sg = Engine.GetObject(webdavUrl) as StructureGroup; if (sg == null) { throw new Exception(String.Format("Cannot find structure group with webdav URL: {0}", webdavUrl)); } return(sg); }
//private string _moduleRoot; public override void Transform(Engine engine, Package package) { Initialize(engine, package); //The core configuration component should be the one being processed by the template Component coreConfigComponent = GetComponent(); StructureGroup sg = GetSystemStructureGroup("resources"); //_moduleRoot = GetModulesRoot(coreConfigComponent); //Get all the active modules Dictionary <string, Component> moduleComponents = GetActiveModules(coreConfigComponent); List <string> filesCreated = new List <string>(); //For each active module, publish the config and add the filename(s) to the bootstrap list foreach (KeyValuePair <string, Component> module in moduleComponents) { filesCreated.Add(ProcessModule(module.Key, module.Value, sg)); } //Publish the boostrap list, this is used by the web application to load in all other resource files PublishBootstrapJson(filesCreated, coreConfigComponent, sg, "resource-"); StringBuilder publishedFiles = new StringBuilder(); foreach (string file in filesCreated) { if (!String.IsNullOrEmpty(file)) { publishedFiles.AppendCommaSeparated(file); Logger.Info("Published " + file); } } // append json result to output string json = String.Format(JsonOutputFormat, publishedFiles); Item outputItem = package.GetByName(Package.OutputName); if (outputItem != null) { package.Remove(outputItem); string output = outputItem.GetAsString(); if (output.StartsWith("[")) { // insert new json object json = String.Format("{0},{1}{2}]", output.TrimEnd(']'), Environment.NewLine, json); } else { // append new json object json = String.Format("[{0},{1}{2}]", output, Environment.NewLine, json); } } package.PushItem(Package.OutputName, package.CreateStringItem(ContentType.Text, json)); }
protected string ProcessModule(string moduleName, Component module, StructureGroup sg) { Dictionary <string, string> data = new Dictionary <string, string>(); ItemFields fields = new ItemFields(module.Content, module.Schema); foreach (Component configComp in fields.GetComponentValues("resource")) { data = MergeData(data, ReadComponentData(configComp)); } return(PublishJsonData(data, module, moduleName, "resource", sg)); }
public dynamic GetStructureGroup(string itemUriOrWebDavUrl) { StructureGroup sg = _engine.GetObject(itemUriOrWebDavUrl) as StructureGroup; if (sg == null) { Logger.Error(String.Format("Unable To GetStructureGroup With '{0}'", itemUriOrWebDavUrl)); return(null); } return(new StructureGroupModel(_engine, sg)); }
/// <summary> /// Build navigaton XML using rootSG.GetListItems() recursively to retrieve an XML list of nodes for all SGs and Pages. /// The flat list is iterated and each node is appended to its parent based on .OrganizationalItem information. /// Nodes that are not active navigation items are removed from XML. /// /// Execution time: 45 seconds for 221 SGs and 2173 Pages /// </summary> /// <param name="structureGroup">Structure Group to generate navigation for</param> /// <returns>Navigation XML root element</returns> private XmlElement BuildNavigationReorder(StructureGroup structureGroup) { XmlElement navigationXml = structureGroup.GetListItems(filter); List <XmlElement> itemList = new List <XmlElement>(navigationXml.ChildNodes.Cast <XmlElement>()); namespaceManager = new XmlNamespaceManager(navigationXml.OwnerDocument.NameTable); namespaceManager.AddNamespace("tcm", TCM_NAMESPACE_URI); foreach (XmlElement item in itemList) { string itemTitle = item.Attributes[ATTRIBUTE_TITLE].Value; if (IsNavigable(itemTitle)) { TcmUri itemId = new TcmUri(item.Attributes[ATTRIBUTE_ID].Value); ItemType itemType = itemId.ItemType; TcmUri parentId = null; // enhance item node if (itemType == ItemType.StructureGroup) { StructureGroup childSG = m_Engine.GetObject(itemId) as StructureGroup; parentId = childSG.OrganizationalItem.Id; EnhanceNode(item, childSG); } else if (itemType == ItemType.Page) { Page childPage = m_Engine.GetObject(itemId) as Page; parentId = childPage.OrganizationalItem.Id; EnhanceNode(item, childPage); } // reorder - apply hierarchy XmlNode parent = navigationXml.SelectSingleNode(String.Format("//tcm:Item[@ID='{0}']", parentId), namespaceManager); if (parent == null) { if (parentId != structureGroup.Id) { navigationXml.RemoveChild(item); } } else { parent.AppendChild(item); } } else { navigationXml.RemoveChild(item); } } return(navigationXml); }
private SitemapItem GenerateFolderNode(StructureGroup startPoint) { SitemapItem root = new SitemapItem(GetNavigationTitle(startPoint)) { Id = startPoint.Id, Url = GetUrl(startPoint), Type = ItemType.StructureGroup.ToString(), Visible = IsVisible(startPoint.Title) }; return(root); }
private Binary PublishModuleResources(string moduleName, Component moduleConfigComponent, StructureGroup structureGroup) { ItemFields moduleConfigComponentFields = new ItemFields(moduleConfigComponent.Content, moduleConfigComponent.Schema); Dictionary<string, string> resources = new Dictionary<string, string>(); foreach (Component resourcesComponent in moduleConfigComponentFields.GetComponentValues("resource")) { resources = MergeData(resources, ExtractKeyValuePairs(resourcesComponent)); } return resources.Count == 0 ? null : AddJsonBinary(resources, moduleConfigComponent, structureGroup, moduleName, variantId: "resources"); }
private Binary PublishSemanticSchemas(StructureGroup structureGroup, Component relatedComponent) { RepositoryItemsFilter schemasFilter = new RepositoryItemsFilter(Session) { Recursive = true, ItemTypes = new[] { ItemType.Schema }, SchemaPurposes = new[] { SchemaPurpose.Component, SchemaPurpose.Multimedia, SchemaPurpose.Metadata, SchemaPurpose.Region } }; IEnumerable <Schema> schemas = Publication.GetItems(schemasFilter).Cast <Schema>(); SemanticSchemaData[] semanticSchemas = schemas.Select(GetSemanticSchema).ToArray(); return(AddJsonBinary(semanticSchemas, relatedComponent, structureGroup, "schemas", variantId: "semantic-schemas")); }
public override void Transform(Engine engine, Package package) { Initialize(engine, package); // The input Component is used to relate some of the generated Binaries to (so they get unpublished if the Component is unpublished). Component inputComponent = GetComponent(); StructureGroup sg = GetSystemStructureGroup("resources"); //For each active module, publish the config and add the filename(s) to the bootstrap list List <Binary> binaries = GetActiveModules().Select(module => PublishModuleResources(module.Key, module.Value, sg)).Where(b => b != null).ToList(); AddBootstrapJsonBinary(binaries, inputComponent, sg, "resource"); OutputSummary("Publish Resources", binaries.Select(b => b.Url)); }
public override void Transform(tpl.Engine engine, tpl.Package package) { Initialize(engine, package); _config = LoadConfig(GetComponent()); _startPoint = GetPublication().RootStructureGroup; if (_startPoint != null) { string nav = GenerateNavigation(); if (!string.IsNullOrEmpty(GenerateNavigation())) { package.PushItem(tpl.Package.OutputName, package.CreateStringItem(tpl.ContentType.Text, nav)); } } }
/// <summary> /// Build navigation XML using rootSG.GetItems(). This gets the real TOM objects for all SGs and Pages under RootSG. /// SGs and Pages that are not active navigation items are discarded. The rest are placed in an XML as tcm:Item nodes /// and the hierarchical structure is created based on item.OrganizationalItem information. /// /// Execution time: 45 seconds for 221 SGs and 2173 Pages /// </summary> /// <param name="structureGroup">Structure Group to generate navigation for</param> /// <returns>Navigation XML root element</returns> private XmlElement BuildNavigationGetItems(StructureGroup structureGroup) { XmlDocument dom = new XmlDocument(); dom.AppendChild(dom.CreateXmlDeclaration("1.0", "UTF-8", null)); namespaceManager = new XmlNamespaceManager(dom.NameTable); namespaceManager.AddNamespace("tcm", TCM_NAMESPACE_URI); XmlElement navigationXml = dom.CreateElement("tcm:ListItems", TCM_NAMESPACE_URI); EnhanceNode(navigationXml, (RepositoryLocalObject)structureGroup); dom.AppendChild(navigationXml); foreach (RepositoryLocalObject item in structureGroup.GetItems(filter)) { if (IsNavigable(item.Title)) { XmlElement itemElement = dom.CreateElement("tcm:Item", TCM_NAMESPACE_URI); EnhanceNode(itemElement, item); // enhance item node TcmUri itemId = item.Id; ItemType itemType = itemId.ItemType; if (itemType == ItemType.StructureGroup) { EnhanceNode(itemElement, (StructureGroup)item); } else if (itemType == ItemType.Page) { EnhanceNode(itemElement, (Page)item); } // build hierarchy TcmUri parentId = item.OrganizationalItem.Id; XmlNode parent = dom.SelectSingleNode(String.Format("//tcm:Item[@{0}='{1}']", ATTRIBUTE_ID, parentId), namespaceManager); if (parent == null) { if (parentId != structureGroup.Id) { itemElement.SetAttribute(ATTRIBUTE_PARENT, parentId); } navigationXml.AppendChild(itemElement); } else { parent.AppendChild(itemElement); } } } // fix orphan items foreach (XmlNode item in dom.SelectNodes(string.Format("/tcm:ListItems/tcm:Item[@{0}]", ATTRIBUTE_PARENT), namespaceManager)) { string parentId = item.Attributes[ATTRIBUTE_PARENT].Value; item.Attributes.RemoveNamedItem(ATTRIBUTE_PARENT); XmlNode parent = dom.SelectSingleNode(String.Format("//tcm:Item[@{0}='{1}']", ATTRIBUTE_ID, parentId), namespaceManager); parent.AppendChild(item); } return navigationXml; }
private string GetLinkToSgIndexPage(StructureGroup sg, Session session) { OrganizationalItemItemsFilter filter = new OrganizationalItemItemsFilter(session) { ItemTypes = new[] { ItemType.Page } }; string title = StripNumbersFromTitle(sg.Title); const string pageLinkFormat = "<a tridion:href=\"{0}\">{1}</a>"; string result = null; foreach (XmlElement page in sg.GetListItems(filter).ChildNodes) { if (!page.Attributes["Title"].Value.ToLower().Contains(IndexPagePattern)) continue; result = string.Format(pageLinkFormat, page.Attributes["ID"].Value, title); break; } if (string.IsNullOrEmpty(result)) { result = title; } return result; }
/// <summary> /// Build navigaton XML using rootSG.GetListItems() recursively to retrieve an XML list of nodes for all SGs and Pages. /// The flat list is iterated and each node is appended to its parent based on .OrganizationalItem information. /// Nodes that are not active navigation items are removed from XML. /// /// Execution time: 45 seconds for 221 SGs and 2173 Pages /// </summary> /// <param name="structureGroup">Structure Group to generate navigation for</param> /// <returns>Navigation XML root element</returns> private XmlElement BuildNavigationReorder(StructureGroup structureGroup) { XmlElement navigationXml = structureGroup.GetListItems(filter); List<XmlElement> itemList = new List<XmlElement>(navigationXml.ChildNodes.Cast<XmlElement>()); namespaceManager = new XmlNamespaceManager(navigationXml.OwnerDocument.NameTable); namespaceManager.AddNamespace("tcm", TCM_NAMESPACE_URI); foreach (XmlElement item in itemList) { string itemTitle = item.Attributes[ATTRIBUTE_TITLE].Value; if (IsNavigable(itemTitle)) { TcmUri itemId = new TcmUri(item.Attributes[ATTRIBUTE_ID].Value); ItemType itemType = itemId.ItemType; TcmUri parentId = null; // enhance item node if (itemType == ItemType.StructureGroup) { StructureGroup childSG = m_Engine.GetObject(itemId) as StructureGroup; parentId = childSG.OrganizationalItem.Id; EnhanceNode(item, childSG); } else if (itemType == ItemType.Page) { Page childPage = m_Engine.GetObject(itemId) as Page; parentId = childPage.OrganizationalItem.Id; EnhanceNode(item, childPage); } // reorder - apply hierarchy XmlNode parent = navigationXml.SelectSingleNode(String.Format("//tcm:Item[@ID='{0}']", parentId), namespaceManager); if (parent == null) { if (parentId != structureGroup.Id) { navigationXml.RemoveChild(item); } } else { parent.AppendChild(item); } } else { navigationXml.RemoveChild(item); } } return navigationXml; }
private void AddNodes(XmlElement context, StructureGroup sg, string baseUrl) { XmlElement sgElmt = CreateElement(context, sg.Id, CreateUrl(baseUrl, sg.Directory), StripPrefix(sg.Title), sg.Title); Logger.Debug("started AddNodes for sg " + sg.Title + ", with calculated url " + CreateUrl(baseUrl, sg.Directory)); foreach (RepositoryLocalObject item in sg.GetItems()) { string url; if (item is Page) { Page p = (Page)item; url = CreateUrl(baseUrl, sg.Directory, p.FileName + "." + p.PageTemplate.FileExtension); if (p.FileName.Equals("index")) { // this is the index page of the current structure group sgElmt.SetAttribute("url", url); sgElmt.SetAttribute("uri", p.Id); } else { XmlElement pageElmt = CreateElement(sgElmt, p.Id, url, p.Title, p.Title); pageElmt.SetAttribute("id", p.Id); } } else { if (item is StructureGroup) { Logger.Debug("found child with title " + item.Title); if (!_reIsNavigationItem.IsMatch(item.Title)) // only include structure groups with a title starting with a number continue; AddNodes(sgElmt, (StructureGroup)item, CreateUrl(baseUrl, sg.Directory)); } } } }
/// <summary> /// Builds the XmlElement containing the navigation XML for the Pages and Structure Groups directly under the given Structure Group. /// For sub Structure Groups, the method calls itself recursively to generate the nested level navigation XML. /// On exiting the recursion, the identified XmlElement nodes are added to the parent node as children. /// Only active navigation items are considered (i.e. items whose title conform to a regular expression). /// SG and Page nodes are enhanced with additional information such as URL, Display Title, etc. /// /// Execution time: 43 seconds for 221 SGs and 2173 Pages /// </summary> /// <param name="structureGroup">Structure Group to generate navigation for</param> /// <returns>Navigation XmlElement for the given SG</returns> private XmlElement BuildNavigation(StructureGroup structureGroup) { List<XmlNode> toRemove = new List<XmlNode>(); XmlElement navigationXml = structureGroup.GetListItems(filter); foreach (XmlElement item in navigationXml.ChildNodes) { string itemTitle = item.Attributes["Title"].Value; if (IsNavigable(itemTitle)) { // enhance node TcmUri itemId = new TcmUri(item.Attributes[ATTRIBUTE_ID].Value); ItemType itemType = itemId.ItemType; if (itemType == ItemType.StructureGroup) { StructureGroup childSG = m_Engine.GetObject(itemId) as StructureGroup; EnhanceNode(item, childSG); // recursive step XmlElement childNavigation = BuildNavigation(childSG); foreach (XmlElement childItem in childNavigation.ChildNodes) { XmlNode importedNode = item.OwnerDocument.ImportNode(childItem, true); item.AppendChild(importedNode); } } else if (itemType == ItemType.Page) { Page childPage = m_Engine.GetObject(itemId) as Page; EnhanceNode(item, childPage); } } else { toRemove.Add(item); } } // remove non-navigation items foreach (XmlNode node in toRemove) { navigationXml.RemoveChild(node); } return navigationXml; }
/// <summary> /// Adds binary data as a Stream to the collection of binaries of the RenderedItem. /// It will be published to the specified location with the specified filename. /// The binary can be identified by the specified variantId and is related to a Component. /// </summary> /// <param name="stream">A Stream holding the content of the binary</param> /// <param name="variantId">A String holding an identifier for the binary</param> /// <param name="contentType">The MIME type of the content</param> /// <param name="filename">A String holding the file name of the binary</param> /// <param name="component">A Component that is related to this binary (e.g. the binary comes from a ECL stub Component)</param> /// <param name="targetStructureGroup">A optional StructureGroup holding the path to which the binary will be published</param> /// <returns>A Binary instance</returns> private Binary AddBinary(Stream stream, string variantId, string contentType, string filename, Component component, StructureGroup targetStructureGroup) { Binary publishedEclItem; if (targetStructureGroup == null) { Log.Info(string.Format("publishing ECL item of type {0}", contentType)); publishedEclItem = _engine.PublishingContext.RenderedItem.AddBinary(stream, filename, variantId, component, contentType); } else { Log.Info(string.Format("publishing ECL item of type {0} to Structure Group: {1}", contentType, targetStructureGroup.Id)); publishedEclItem = _engine.PublishingContext.RenderedItem.AddBinary(stream, filename, targetStructureGroup, variantId, component, contentType); } return publishedEclItem; }
private StructureGroup FindOrCreateSG(Engine engine, string sgWebDav) { log.Debug(string.Format("Find or Create SG '{0}'", sgWebDav)); StructureGroup sg = engine.GetObject(sgWebDav) as StructureGroup; if (sg == null) { int lastSlash = sgWebDav.LastIndexOf("/"); string parentSGWebDav = sgWebDav.Substring(0, lastSlash); StructureGroup parentSG = FindOrCreateSG(engine, parentSGWebDav); Session newSession = new Session(engine.GetSession().User.Title); sg = new StructureGroup(newSession, parentSG.Id); string title = sgWebDav.Substring(lastSlash + 1); sg.Title = MakeSafeSGTitle(title); sg.Directory = MakeSafeDirectory(title); sg.Save(); newSession.Dispose(); log.Debug(string.Format("Created SG '{0}'", sgWebDav)); } else { log.Debug(string.Format("Found SG '{0}'", sgWebDav)); } return sg; }
private Binary PublishSemanticVocabularies(StructureGroup structureGroup, Component relatedComponent) { ApplicationData vocabularyAppData = Session.SystemManager.LoadGlobalApplicationData(VocabulariesAppDataId); if (vocabularyAppData == null) { throw new DxaException("No Vocabularies are defined in Global Application Data: " + VocabulariesAppDataId); } XElement vocabulariesXml = XElement.Parse(Encoding.Unicode.GetString(vocabularyAppData.Data)); List<VocabularyData> vocabularies = vocabulariesXml.Elements() .Select(vocabElement => new VocabularyData { Prefix = vocabElement.Attribute("prefix").Value, Vocab = vocabElement.Attribute("name").Value }) .ToList(); if (_retrofitMode) { Logger.Info("Retrofit mode is enabled; generating semantic vocabularies for each (non-embedded) Schema."); RepositoryItemsFilter schemasFilter = new RepositoryItemsFilter(Session) { Recursive = true, ItemTypes = new[] { ItemType.Schema }, SchemaPurposes = new[] { SchemaPurpose.Component, SchemaPurpose.Multimedia, SchemaPurpose.Metadata } }; IEnumerable<Schema> schemas = Publication.GetItems(schemasFilter).Cast<Schema>(); vocabularies.AddRange(schemas.Select(schema => new VocabularyData { Prefix = GetDefaultVocabularyPrefix(schema), Vocab = schema.NamespaceUri })); } if (!vocabularies.Any(vocab => vocab.Prefix == CoreVocabularyPrefix)) { VocabularyData coreVocabulary = new VocabularyData { Prefix = CoreVocabularyPrefix, Vocab = CoreVocabulary }; vocabularies.Add(coreVocabulary); } return AddJsonBinary(vocabularies, relatedComponent, structureGroup, "vocabularies"); }
protected string GetStructureGroupTitle(StructureGroup sg) { return this.StripPrefix(sg.Title); }
private SitemapItem GenerateStructureGroupNavigation(StructureGroup structureGroup) { SitemapItem result = new SitemapItem { Id = structureGroup.Id, Title = GetNavigationTitle(structureGroup), Url = System.Web.HttpUtility.UrlDecode(structureGroup.PublishLocationUrl), Type = ItemType.StructureGroup.ToString(), Visible = IsVisible(structureGroup.Title) }; foreach (RepositoryLocalObject item in structureGroup.GetItems().Where(i => !i.Title.StartsWith("_")).OrderBy(i => i.Title)) { SitemapItem childSitemapItem; Page page = item as Page; if (page != null) { if (!IsPublished(page)) { continue; } childSitemapItem = new SitemapItem { Id = page.Id, Title = GetNavigationTitle(page), Url = GetUrl(page), Type = ItemType.Page.ToString(), PublishedDate = GetPublishedDate(page, Engine.PublishingContext.TargetType), Visible = IsVisible(page.Title) }; } else { childSitemapItem = GenerateStructureGroupNavigation((StructureGroup) item); } result.Items.Add(childSitemapItem); } return result; }
protected string GetNavigationTitle(StructureGroup sg) { return StripPrefix(sg.Title); }
/// <summary> /// Add a binary to the package and ensure it is published into the given structure group /// </summary> /// <param name="mmComp">The binary to add</param> /// <param name="sg">The target SG</param> protected void AddBinary(Component mmComp, StructureGroup sg) { Item packageItem = null; string filename = GetFilename(mmComp.BinaryContent.Filename); //Check if the binary is already in the package (for example, if the DWT already added it packageItem = m_Package.GetByName(filename); if (packageItem != null) { Logger.Debug("An item with the same name exists in the package"); KeyValuePair<string, string> pair = new KeyValuePair<string, string>("TCMURI", mmComp.Id.ToString()); if (!packageItem.Properties.Contains(pair)) { //its a different item so we should push our item in the package packageItem = null; } } //if its not in the package, add it if (packageItem == null) { Logger.Debug(String.Format("Pushing item {0} to the package", filename)); packageItem = m_Package.CreateMultimediaItem(mmComp.Id); m_Package.PushItem(filename, packageItem); } //Publish the binary into the appropriate SG using (Stream itemStream = packageItem.GetAsStream()) { try { byte[] data = new byte[itemStream.Length]; itemStream.Read(data, 0, data.Length); Logger.Info(String.Format("Adding binary component {0}({1}) ", mmComp.Title, mmComp.Id.ToString())); string publishedPath = m_Engine.AddBinary(mmComp.Id, null, sg.Id, data, filename); packageItem.Properties[Item.ItemPropertyPublishedPath] = publishedPath; } finally { itemStream.Close(); } } }
private Binary PublishXpmRegionConfiguration(StructureGroup structureGroup, Component relatedComponent) { IDictionary<string, XpmRegionData> xpmRegions = new Dictionary<string, XpmRegionData>(); foreach (ComponentTemplate ct in Publication.GetComponentTemplates()) { string regionName = GetRegionName(ct); XpmRegionData xpmRegion; if (!xpmRegions.TryGetValue(regionName, out xpmRegion)) { xpmRegion = new XpmRegionData { Region = regionName, ComponentTypes = new List<XpmComponentTypeData>() }; xpmRegions.Add(regionName, xpmRegion); } string templateId = ct.Id.GetVersionlessUri().ToString(); IEnumerable<XpmComponentTypeData> allowedComponentTypes = ct.RelatedSchemas.Select( schema => new XpmComponentTypeData { Schema = schema.Id.GetVersionlessUri().ToString(), Template = templateId } ); xpmRegion.ComponentTypes.AddRange(allowedComponentTypes); } return AddJsonBinary(xpmRegions.Values, relatedComponent, structureGroup, "regions"); }
private Binary PublishSemanticSchemas(StructureGroup structureGroup, Component relatedComponent) { RepositoryItemsFilter schemasFilter = new RepositoryItemsFilter(Session) { Recursive = true, ItemTypes = new [] { ItemType.Schema }, SchemaPurposes = new [] { SchemaPurpose.Component, SchemaPurpose.Multimedia, SchemaPurpose.Metadata } }; IEnumerable<Schema> schemas = Publication.GetItems(schemasFilter).Cast<Schema>(); SemanticSchemaData[] semanticSchemas = schemas.Select(GetSemanticSchema).ToArray(); return AddJsonBinary(semanticSchemas, relatedComponent, structureGroup, "schemas", variantId: "semantic-schemas"); }
private IEnumerable<XElement> GetItemsInFolderAsAList(StructureGroup startPoint) { OrganizationalItemItemsFilter filter = new OrganizationalItemItemsFilter(Engine.GetSession()) { ItemTypes = new List<ItemType> {ItemType.Page, ItemType.StructureGroup}, BaseColumns = ListBaseColumns.Extended }; //get pages first to see if they have to appear in nav XmlElement pagesXml = startPoint.GetListItems(filter); XmlDocument rootDocument = new XmlDocument(); rootDocument.LoadXml(pagesXml.OuterXml); XDocument pageDoc = XDocument.Parse(rootDocument.OuterXml); List<XElement> orderedDocument = (from XElement el in pageDoc.Root.Descendants() orderby el.Attribute("Title").Value select el).ToList(); return orderedDocument; }
/// <summary> /// Enhance the XmlElement corresponding to a Structure Group with information such as DisplayTitle, URL, etc. /// </summary> /// <param name="item">XmlElement to be enhanced</param> /// <param name="structureGroup">StructureGroup to enhance from</param> private void EnhanceNode(XmlElement item, StructureGroup structureGroup) { string displayTitle = navigationItemRegex.Replace(structureGroup.Title, string.Empty); item.SetAttribute(ATTRIBUTE_DISPLAY_TITLE, displayTitle); string url = structureGroup.PublishLocationUrl; item.SetAttribute(ATTRIBUTE_URL, url); }
private SitemapItem GenerateStructureGroupNavigation(StructureGroup startPoint) { SitemapItem root = GenerateFolderNode(startPoint); IEnumerable<XElement> orderedDocument = GetItemsInFolderAsAList(startPoint); foreach (XElement pgNode in orderedDocument) { Page page = Engine.GetObject(pgNode.Attribute("ID").Value) as Page; if (page != null) { if (IsPublished(page) && !IsSystem(pgNode.Attribute("Title").Value)) { root.Items.Add(GeneratePageNode(page)); } } else { if (!IsSystem(pgNode.Attribute("Title").Value)) { root.Items.Add(GenerateStructureGroupNavigation(Engine.GetObject(pgNode.Attribute("ID").Value) as StructureGroup)); } } } return root; }
private SitemapItem GenerateFolderNode(StructureGroup startPoint) { SitemapItem root = new SitemapItem(GetNavigationTitle(startPoint)) { Id = startPoint.Id, Url = GetUrl(startPoint), Type = ItemType.StructureGroup.ToString(), Visible = IsVisible(startPoint.Title) }; return root; }
private static string GetUrl(StructureGroup sg) { String url = sg.PublishLocationUrl; return System.Web.HttpUtility.UrlDecode(url); }
/// <summary> /// Resolve and possibly publish an ECL item /// </summary> /// <param name="eclItemInPackage">EclItemInPackage object</param> /// <param name="attributes">template atrributes</param> /// <param name="variantId">variant id</param> /// <param name="targetStructureGroup">target Structure Group to publish too (when null, Image Structure Group from Publication will be used</param> /// <returns>tridion publish path or external link</returns> private string ResolveEclItem(EclItemInPackage eclItemInPackage, IList<ITemplateAttribute> attributes, string variantId, StructureGroup targetStructureGroup) { // determine if item is already published or if we should get the content for it and let tridion publish it string publishedPath = eclItemInPackage.EclItem.GetDirectLinkToPublished(attributes); if (string.IsNullOrEmpty(publishedPath)) { // tridion must publish this ecl item as a variant Component component = (Component)_engine.GetSession().GetObject(eclItemInPackage.StubUri); // create a filename with size and a proper extension string filename = ConstructFileName(eclItemInPackage.EclItem.Filename, variantId, eclItemInPackage.EclUri.ToString()); Binary publishedEclItem; // get content as stream Stream contentStream = eclItemInPackage.PackageItem.GetAsStream(); string contentType = eclItemInPackage.EclItem.MimeType; using (contentStream) { // a provider (like the ADAM provider) can return an empty stream when requested without attributes // in that case we should resolve the item with its size taken into consideration // so here we ask for the content again passing width and height in attributes if (contentStream.Length == 0) { using (Stream stream = CreateTemporaryFileStream()) { IContentResult content = eclItemInPackage.EclItem.GetContent(attributes); content.Stream.CopyTo(stream); publishedEclItem = AddBinary(stream, variantId, contentType, filename, component, targetStructureGroup); } } else { publishedEclItem = AddBinary(contentStream, variantId, contentType, filename, component, targetStructureGroup); } } // we could consider updating the package item with the content and the file extension, but to change the content type, we have to recreate it // this won't be of much use other than getting the content stream twice (performance impact) as the package item will (or should) not be used after this anymore // set published path in package item and add to attributes eclItemInPackage.PackageItem.Properties[Item.ItemPropertyPublishedPath] = publishedEclItem.Url; return publishedEclItem.Url; } // ecl item is already published, lets set the uri that can be used from a public website to link directly to the item on the external system eclItemInPackage.PackageItem.Properties[Item.ItemPropertyPublishedPath] = publishedPath; Log.Info(string.Format("resolved ECL item with path {0}", publishedPath)); return publishedPath; }
/// <summary> /// Add a binary to the package and ensure it is published into the given structure group /// </summary> /// <param name="mmComp">The binary to add</param> /// <param name="sg">The target SG</param> protected Item AddBinary(Component mmComp, StructureGroup sg) { return AddBinary(mmComp, sg.Id); }
protected string GetNavigationTitle(StructureGroup sg) { string result = StripPrefix(sg.Title); return result; }
/// <summary> /// ITemplate.Transform implementation /// </summary> /// <param name="engine">The engine can be used to retrieve additional information or execute additional actions</param> /// <param name="package">The package provides the primary data for the template, and acts as the output</param> public void Transform(Engine engine, Package package) { _engine = engine; _package = package; _publicationId = GetPublicationId(); // determine (optional) structure group parameter Item targetStructureGroupItem = _package.GetByName(ParameterNameTargetStructureGroup); if (targetStructureGroupItem != null) { if (!TcmUri.IsValid(targetStructureGroupItem.GetAsString())) { throw new InvalidDataException(string.Format("Target location {0} is not a structure group", targetStructureGroupItem)); } TcmUri uri = new TcmUri(targetStructureGroupItem.GetAsString()); // get target structure group in context publication _targetStructureGroup = (StructureGroup)_engine.GetSession().GetObject(new TcmUri(uri.ItemId, uri.ItemType, _publicationId)); Log.Debug(string.Format("Target Structure Group {0} found", _targetStructureGroup.Id)); } // make sure eclSession is disposed at the end using (IEclSession eclSession = SessionFactory.CreateEclSession(engine.GetSession())) { // loop over all ecl items and store them in a dictionary _eclItemsInPackage = new Dictionary<TcmUri, EclItemInPackage>(); foreach (Item item in _package.GetAllByType(new ContentType(EclContentType))) { if (item.Properties.ContainsKey(Item.ItemPropertyTcmUri) && item.Properties.ContainsKey(Item.ItemPropertyFileName)) { // has the item already been published? if (!item.Properties.ContainsKey(Item.ItemPropertyPublishedPath)) { // find ecl items string uri; if (item.Properties.TryGetValue(Item.ItemPropertyTcmUri, out uri)) { TcmUri stubUri = new TcmUri(uri); IEclUri eclUri = eclSession.TryGetEclUriFromTcmUri(stubUri); if (eclUri != null) { // we have a valid ecl item, lets store it in the dictionary IContentLibraryMultimediaItem eclItem = (IContentLibraryMultimediaItem)eclSession.GetContentLibrary(eclUri).GetItem(eclUri); EclItemInPackage eclItemInPackage = new EclItemInPackage(item, eclItem); _eclItemsInPackage.Add(stubUri, eclItemInPackage); } } } else { // items have been published, we are probabaly called too late... Log.Warning("{0} has already been published, \"Resolve ECL items\" should be added before \"Publish Binaries in Package\""); } } } // end processing if there are no ecl items found in the package if (_eclItemsInPackage.Count == 0) return; // determine item name to operate on from a parameter or use default string itemName = _package.GetValue(ParameterNameItemName); if (string.IsNullOrEmpty(itemName)) { itemName = Package.OutputName; } Item selectedItem = _package.GetByName(itemName); // continue on the output by matching the found ecl items in there against the list of ecl items in the package if ((selectedItem.Type == PackageItemType.String) || (selectedItem.Type == PackageItemType.Stream)) { // Assume text content string inputToConvert = selectedItem.GetAsString(); string convertedOutput = ResolveEclLinks(eclSession, inputToConvert); if (convertedOutput != null) { Log.Debug("Changed Output item"); selectedItem.SetAsString(convertedOutput); } } else { // XML XmlDocument outputDocument = selectedItem.GetAsXmlDocument(); ResolveEclLinks(eclSession, outputDocument); selectedItem.SetAsXmlDocument(outputDocument); } } }
/// <summary> /// Return absolute path of a specified structure group item. /// </summary> /// <param name="page"></param> /// <returns></returns> protected String GetAbsolutePath(StructureGroup directory) { String path = directory.Directory + "/"; while (directory != null && directory.Directory != "") { directory = (StructureGroup)directory.OrganizationalItem; if (directory.Title == "") { path = "/" + path; } else { path = directory.Directory + "/" + path; } } return path; }
private Binary PublishPageIncludes(StructureGroup structureGroup, Component relatedComponent) { IDictionary<string, string[]> pageIncludes = new Dictionary<string, string[]>(); RepositoryItemsFilter pageTemplatesFilter = new RepositoryItemsFilter(Session) { ItemTypes = new [] { ItemType.PageTemplate }, Recursive = true }; IEnumerable<PageTemplate> pageTemplates = Publication.GetItems(pageTemplatesFilter).Cast<PageTemplate>(); foreach (PageTemplate pt in pageTemplates.Where(pt => pt.MetadataSchema != null && pt.Metadata != null)) { ItemFields ptMetadataFields = new ItemFields(pt.Metadata, pt.MetadataSchema); string[] includes = ptMetadataFields.GetTextValues("includes").ToArray(); pageIncludes.Add(pt.Id.ItemId.ToString(), includes); } return AddJsonBinary(pageIncludes, relatedComponent, structureGroup, "includes"); }