protected Dictionary <string, Component> GetActiveModules() { Schema moduleConfigSchema = GetSchema(ModuleConfigurationSchemaRootElementName); Session session = moduleConfigSchema.Session; UsingItemsFilter moduleConfigComponentsFilter = new UsingItemsFilter(session) { ItemTypes = new[] { ItemType.Component }, BaseColumns = ListBaseColumns.Id }; Dictionary <string, Component> results = new Dictionary <string, Component>(); foreach (Component comp in moduleConfigSchema.GetUsingItems(moduleConfigComponentsFilter).Cast <Component>()) { // GetUsingItems returns the items in their Owning Publication, which could be lower in the BluePrint than were we are (so don't exist in our context Repository). Component moduleConfigComponent = (Component)Publication.GetObject(comp.Id); if (!session.IsExistingObject(moduleConfigComponent.Id)) { continue; } ItemFields fields = new ItemFields(moduleConfigComponent.Content, moduleConfigComponent.Schema); string moduleName = fields.GetTextValue("name").Trim().ToLower(); if (fields.GetTextValue("isActive").ToLower() == "yes" && !results.ContainsKey(moduleName)) { results.Add(moduleName, moduleConfigComponent); } } return(results); }
protected static string GetRegionName(ComponentTemplate template) { // check CT metadata if (template.MetadataSchema != null && template.Metadata != null) { ItemFields meta = new ItemFields(template.Metadata, template.MetadataSchema); string regionName = meta.GetTextValue("regionName"); if (!string.IsNullOrEmpty(regionName)) { return(regionName); } string regionViewName = meta.GetTextValue("regionView"); if (!string.IsNullOrEmpty(regionViewName)) { // strip module from fully qualified name // since we need just the region name here as the web application can't deal with fully qualified region names yet return(StripModuleFromName(regionViewName)); } } // fallback use template title Match match = Regex.Match(template.Title, @".*?\[(.+?)\]"); if (match.Success) { // strip module from fully qualified name // since we need just the region name here as the web application can't deal with fully qualified region names yet return(StripModuleFromName(match.Groups[1].Value)); } // default region name return("Main"); }
protected void ProcessModule(string moduleName, Component moduleComponent, string tempFolder) { Component designConfig = GetDesignConfigComponent(moduleComponent); if (designConfig != null) { ItemFields fields = new ItemFields(designConfig.Content, designConfig.Schema); Component zip = fields.GetComponentValue("design"); Component variables = fields.GetComponentValue("variables"); string code = fields.GetTextValue("code"); string customLess = GetModuleCustomLess(variables, code); if (zip != null) { // write binary contents as zipfile to disk string zipfile = Path.Combine(tempFolder, moduleName + "-html-design.zip"); File.WriteAllBytes(zipfile, zip.BinaryContent.GetByteArray()); // unzip using (ZipArchive archive = ZipFile.OpenRead(zipfile)) { archive.ExtractToDirectory(tempFolder, true); } // add content from merge files if available List <string> files = _mergeFileLines.Keys.Select(s => s).ToList(); foreach (string mergeFile in files) { string path = Path.Combine(tempFolder, mergeFile); if (File.Exists(path)) { foreach (string line in File.ReadAllLines(path)) { if (!_mergeFileLines[mergeFile].Contains(line.Trim())) { _mergeFileLines[mergeFile].Add(line.Trim()); } } } } // add custom less code block if (!String.IsNullOrEmpty(customLess.Trim())) { _mergeFileLines["src\\system\\assets\\less\\_custom.less"].Add(customLess); } } if (moduleName.Equals("core")) { // unzip build files (nodejs, npm and grunt etc.) Component buildFiles = fields.GetComponentValue("build"); if (buildFiles != null) { ProcessBuildFiles(buildFiles, tempFolder); } } } }
private string GetSiteIdFromPublication(Publication startPublication) { if (startPublication.Metadata != null) { ItemFields meta = new ItemFields(startPublication.Metadata, startPublication.MetadataSchema); return(meta.GetTextValue("siteId")); } return(null); }
protected bool IsMasterWebPublication(Publication publication) { if (publication.Metadata == null) { return(false); } ItemFields publicationMetadataFields = new ItemFields(publication.Metadata, publication.MetadataSchema); return(!string.IsNullOrEmpty(publicationMetadataFields.GetTextValue("isMaster"))); }
protected bool IsMasterWebPublication(Publication publication) { if (publication.Metadata != null) { ItemFields meta = new ItemFields(publication.Metadata, publication.MetadataSchema); string isMaster = meta.GetTextValue("isMaster"); if (!String.IsNullOrEmpty(isMaster)) { return(true); } } return(false); }
protected Dictionary <string, Component> GetActiveModules(Component coreConfigComponent = null) { Schema moduleConfigSchema = coreConfigComponent != null ? coreConfigComponent.Schema : GetModuleConfigSchema(); Dictionary <string, Component> results = new Dictionary <string, Component>(); foreach (KeyValuePair <TcmUri, string> item in GetUsingItems(moduleConfigSchema, ItemType.Component)) { try { Component comp = (Component)Engine.GetObject(Engine.LocalizeUri(item.Key)); ItemFields fields = new ItemFields(comp.Content, comp.Schema); string moduleName = fields.GetTextValue("name").Trim().ToLower(); if (fields.GetTextValue("isActive").ToLower() == "yes" && !results.ContainsKey(moduleName)) { results.Add(moduleName, comp); } } catch (Exception) { //Do nothing, this module is not available in this publication } } return(results); }
private SitemapItem SetAdditionalMetadataFromStructureGroup(SitemapItem result, StructureGroup structureGroup) { //NavigationConfig navConfig = new NavigationConfig(); if (structureGroup.Metadata != null && structureGroup.MetadataSchema != null && structureGroup.MetadataSchema.Title == _config.MetaDataSchema) { var itemFields = new ItemFields(structureGroup.Metadata, structureGroup.MetadataSchema); Dictionary <string, string> fields = new Dictionary <string, string>(); foreach (var item in _config.MetaDataFields) { string fieldName = item; var fieldValueObj = itemFields.GetTextValue(item); string fieldValue = fieldValueObj != null?fieldValueObj.ToString() : String.Empty; result.AdditionalData.Add(fieldName, fieldValue); } } return(result); }
private string GetNavigationTitleFromComp(Component mainComp) { //TODO, make the field names used to extract the title configurable as TBB parameters string title = null; if (mainComp != null) { if (mainComp.Metadata != null) { ItemFields meta = new ItemFields(mainComp.Metadata, mainComp.MetadataSchema); ItemFields embedMeta = meta.GetEmbeddedField("standardMeta"); if (embedMeta != null) { title = embedMeta.GetTextValue("name"); } } if (String.IsNullOrEmpty(title)) { ItemFields content = new ItemFields(mainComp.Content, mainComp.Schema); title = content.GetTextValue("headline"); } } return(title); }
protected void ProcessModule(string moduleName, Component moduleComponent) { var designConfig = GetDesignConfigComponent(moduleComponent); if (designConfig!=null) { var fields = new ItemFields(designConfig.Content, designConfig.Schema); var zip = fields.GetComponentValue("design"); var variables = fields.GetComponentValue("variables"); var code = fields.GetTextValue("code"); var customLess = GetModuleCustomLess(variables, code); if (zip != null) { string zipfile = tempFolder + moduleName + "-html-design.zip"; File.WriteAllBytes(zipfile, zip.BinaryContent.GetByteArray()); using (var archive = ZipFile.OpenRead(zipfile)) { archive.ExtractToDirectory(tempFolder, true); } List<string> files = mergeFileLines.Keys.Select(s => s).ToList(); foreach (var mergeFile in files) { var path = tempFolder + mergeFile; if (File.Exists(path)) { foreach (var line in File.ReadAllLines(path)) { if (!mergeFileLines[mergeFile].Contains(line.Trim())) { mergeFileLines[mergeFile].Add(line.Trim()); } } } } if (!String.IsNullOrEmpty(customLess.Trim())) { mergeFileLines["src\\system\\assets\\less\\_custom.less"].Add(customLess); } } } }
private string GetNavigationTitleFromComp(Component mainComp) { //TODO, make the field names used to extract the title configurable as TBB parameters string title = null; if (mainComp != null) { if (mainComp.Metadata != null) { ItemFields meta = new ItemFields(mainComp.Metadata, mainComp.MetadataSchema); ItemFields embedMeta = meta.GetEmbeddedField("standardMeta"); if (embedMeta != null) { title = embedMeta.GetTextValue("name"); } } if (String.IsNullOrEmpty(title)) { ItemFields content = new ItemFields(mainComp.Content, mainComp.Schema); title = content.GetTextValue("headline"); } } return title; }
private string GetSiteIdFromPublication(Publication startPublication) { if (startPublication.Metadata!=null) { ItemFields meta = new ItemFields(startPublication.Metadata, startPublication.MetadataSchema); return meta.GetTextValue("siteId"); } return null; }
public override void Transform(Engine engine, Package package) { Initialize(engine, package); bool cleanup; // cleanup should be true by default (if not filled in) if (!package.TryGetParameter("cleanup", out cleanup, Logger)) { cleanup = true; } string drive; package.TryGetParameter("drive", out drive, Logger); List <Binary> binaries = new List <Binary>(); // Read values from HTML Design Configuration Component (which should be the Component used for this Component Presentation) Component inputComponent = GetComponent(); if (inputComponent.Schema.NamespaceUri != HtmlDesignConfigNamespace || inputComponent.Schema.RootElementName != HtmlDesignConfigRootElementName) { throw new DxaException( string.Format("Unexpected input Component {0} ('{1}'). Expecting HTML Design Configuration Component.", inputComponent.Id, inputComponent.Title) ); } ItemFields htmlDesignConfigFields = new ItemFields(inputComponent.Content, inputComponent.Schema); Component favIconComponent = htmlDesignConfigFields.GetMultimediaLink("favicon"); string htmlDesignVersion = htmlDesignConfigFields.GetTextValue("version"); // Publish version.json file IDictionary <string, string> versionData = new Dictionary <string, string> { { "version", htmlDesignVersion } }; Binary versionJsonBinary = AddJsonBinary(versionData, inputComponent, Publication.RootStructureGroup, "version", variantId: "version"); binaries.Add(versionJsonBinary); string tempFolder = GetTempFolder(drive); Directory.CreateDirectory(tempFolder); Logger.Debug("Created temp folder: " + tempFolder); try { // Unzip and merge files ProcessModules(tempFolder); string distFolder = BuildHtmlDesign(tempFolder); // Save favicon to disk (if available) if (favIconComponent != null) { string favIconFilePath = Path.Combine(distFolder, "favicon.ico"); File.WriteAllBytes(favIconFilePath, favIconComponent.BinaryContent.GetByteArray()); Logger.Debug("Saved " + favIconFilePath); } // Publish all files from dist folder Publication pub = (Publication)inputComponent.ContextRepository; string rootStructureGroupWebDavUrl = pub.RootStructureGroup.WebDavUrl; RenderedItem renderedItem = engine.PublishingContext.RenderedItem; string[] distFiles = Directory.GetFiles(distFolder, "*.*", SearchOption.AllDirectories); foreach (string file in distFiles) { Logger.Debug("Found " + file); // Map the file path to a Structure Group string relativeFolderPath = file.Substring(distFolder.Length, file.LastIndexOf('\\') - distFolder.Length); Logger.Debug(string.Format("Relative folder path: '{0}'", relativeFolderPath)); string sgWebDavUrl = rootStructureGroupWebDavUrl + relativeFolderPath.Replace("system", SystemSgName).Replace('\\', '/'); StructureGroup structureGroup = engine.GetObject(sgWebDavUrl) as StructureGroup; if (structureGroup == null) { throw new DxaException(string.Format("Cannot publish '{0}' because Structure Group '{1}' does not exist.", file, sgWebDavUrl)); } // Add binary to package and publish using (FileStream fs = File.OpenRead(file)) { string filename = Path.GetFileName(file); string extension = Path.GetExtension(file); string variantId = string.Format("dist-{0}-{1}", structureGroup.Id.ItemId, filename); Item binaryItem = Package.CreateStreamItem(GetContentType(extension), fs); Binary binary = renderedItem.AddBinary( binaryItem.GetAsStream(), filename, structureGroup, variantId, inputComponent, GetMimeType(extension) ); binaryItem.Properties[Item.ItemPropertyPublishedPath] = binary.Url; package.PushItem(filename, binaryItem); binaries.Add(binary); Logger.Info(string.Format("Added Binary '{0}' related to Component '{1}' ({2}) with variant ID '{3}'", binary.Url, inputComponent.Title, inputComponent.Id, variantId)); } } } finally { if (cleanup) { Directory.Delete(tempFolder, true); Logger.Debug("Removed temp folder " + tempFolder); } else { Logger.Debug("Did not cleanup temp folder " + tempFolder); } } OutputSummary("Publish HTML Design", binaries.Select(b => b.Url)); }
public override void Transform(Engine engine, Package package) { Initialize(engine, package); _mergeFileLines.Add("src\\system\\assets\\less\\_custom.less", new List <string>()); _mergeFileLines.Add("src\\system\\assets\\less\\_modules.less", new List <string>()); _mergeFileLines.Add("src\\templates\\partials\\module-scripts-header.hbs", new List <string>()); _mergeFileLines.Add("src\\templates\\partials\\module-scripts-footer.hbs", new List <string>()); _mergeFileLines.Add("src\\templates\\partials\\module-scripts-xpm.hbs", new List <string>()); StringBuilder publishedFiles = new StringBuilder(); string drive = package.GetValue("drive") ?? String.Empty; string cleanup = package.GetValue("cleanup") ?? String.Empty; // not using System.IO.Path.GetTempPath() because the paths in our zip are already quite long, // so we need a very short temp path for the extract of our zipfile to succeed // using current time and convert to hex (the date won't matter as this folder is cleaned up so time is unique enough) int timestamp = Convert.ToInt32(DateTime.Now.ToString("HHmmssfff")); if (!String.IsNullOrEmpty(drive) && Char.IsLetter(drive.First())) { _tempFolder = drive.First() + @":\_" + timestamp.ToString("x"); } else { // using drive from tridion cm homedir for temp folder _tempFolder = ConfigurationSettings.GetTcmHomeDirectory().Substring(0, 3) + "_" + timestamp.ToString("x"); } try { // read values from Component Component config = GetComponent(); ItemFields fields = new ItemFields(config.Content, config.Schema); Component favicon = fields.GetMultimediaLink("favicon"); string version = fields.GetTextValue("version"); string url = PublishJson(String.Format("{{\"version\":{0}}}", JsonEncode(version)), config, GetPublication().RootStructureGroup, "version", "version"); publishedFiles.AppendCommaSeparated(url); Logger.Info("Published " + url); // create temp folder Directory.CreateDirectory(_tempFolder); Logger.Debug("Created " + _tempFolder); // unzip and merge files ProcessModules(); // build html design string user = System.Security.Principal.WindowsIdentity.GetCurrent().Name; ProcessStartInfo info = new ProcessStartInfo { FileName = "cmd.exe", Arguments = "/c npm start --color=false", WorkingDirectory = _tempFolder, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, StandardErrorEncoding = Encoding.UTF8, StandardOutputEncoding = Encoding.UTF8 }; using (Process cmd = new Process { StartInfo = info }) { cmd.Start(); using (StreamReader reader = cmd.StandardOutput) { string output = reader.ReadToEnd(); if (!String.IsNullOrEmpty(output)) { Logger.Info(output); // TODO: check for errors in standard output and throw exception } } using (StreamReader reader = cmd.StandardError) { string error = reader.ReadToEnd(); if (!String.IsNullOrEmpty(error)) { Exception ex = new Exception(error); ex.Data.Add("Filename", info.FileName); ex.Data.Add("Arguments", info.Arguments); ex.Data.Add("User", user); // TODO: check for known errors and throw exception with a user friendly message //if (error.ToLower().Contains("something")) //{ // throw new Exception(String.Format("Something went wrong for user {0}.", user), ex); //} throw ex; } } cmd.WaitForExit(); } // publish all binaries from dist folder string dist = Path.Combine(_tempFolder, "dist"); if (Directory.Exists(dist)) { // save favicon to disk (if available) if (favicon != null) { string ico = Path.Combine(dist, "favicon.ico"); File.WriteAllBytes(ico, favicon.BinaryContent.GetByteArray()); Logger.Debug("Saved " + ico); } string[] files = Directory.GetFiles(dist, "*.*", SearchOption.AllDirectories); foreach (string file in files) { string filename = Path.GetFileName(file); string extension = Path.GetExtension(file); Logger.Debug("Found " + file); // determine correct structure group Publication pub = (Publication)config.ContextRepository; string relativeFolderPath = file.Substring(dist.Length, file.LastIndexOf('\\') - dist.Length); Logger.Debug("Relative path: " + relativeFolderPath); relativeFolderPath = relativeFolderPath.Replace("system", SystemSgName).Replace('\\', '/'); string pubSgWebDavUrl = pub.RootStructureGroup.WebDavUrl; string publishSgWebDavUrl = pubSgWebDavUrl + relativeFolderPath; Logger.Debug("Structure Group WebDAV URL: " + publishSgWebDavUrl); StructureGroup sg = engine.GetObject(publishSgWebDavUrl) as StructureGroup; if (sg == null) { throw new Exception("Missing Structure Group " + publishSgWebDavUrl); } // add binary to package and publish using (FileStream fs = File.OpenRead(file)) { Item binaryItem = Package.CreateStreamItem(GetContentType(extension), fs); Binary binary = engine.PublishingContext.RenderedItem.AddBinary(binaryItem.GetAsStream(), filename, sg, "dist-" + filename, config, GetMimeType(extension)); binaryItem.Properties[Item.ItemPropertyPublishedPath] = binary.Url; package.PushItem(filename, binaryItem); publishedFiles.AppendCommaSeparated("\"{0}\"", binary.Url); Logger.Info("Published " + binary.Url); } } } else { throw new Exception("Grunt build failed, dist folder is missing."); } } finally { if (String.IsNullOrEmpty(cleanup) || !cleanup.ToLower().Equals("false")) { // cleanup workfolder Directory.Delete(_tempFolder, true); Logger.Debug("Removed " + _tempFolder); } else { Logger.Debug("Did not cleanup " + _tempFolder); } } // output json result package.PushItem(Package.OutputName, package.CreateStringItem(ContentType.Text, String.Format(JsonOutputFormat, publishedFiles))); }
protected bool IsMasterWebPublication(Publication publication) { if (publication.Metadata != null) { ItemFields meta = new ItemFields(publication.Metadata, publication.MetadataSchema); string isMaster = meta.GetTextValue("isMaster"); if (!String.IsNullOrEmpty(isMaster)) { return true; } } return false; }
protected bool IsMasterWebPublication(Publication publication) { if (publication.Metadata == null) { return false; } ItemFields publicationMetadataFields = new ItemFields(publication.Metadata, publication.MetadataSchema); return !string.IsNullOrEmpty(publicationMetadataFields.GetTextValue("isMaster")); }
protected static string GetRegionName(ComponentTemplate template) { // check CT metadata if (template.MetadataSchema != null && template.Metadata != null) { ItemFields meta = new ItemFields(template.Metadata, template.MetadataSchema); string regionName = meta.GetTextValue("regionName"); if (!String.IsNullOrEmpty(regionName)) { return regionName; } string regionViewName = meta.GetTextValue("regionView"); if (!String.IsNullOrEmpty(regionViewName)) { // strip module from fully qualified name // since we need just the region name here as the web application can't deal with fully qualified region names yet return StripModuleFromName(regionViewName); } } // fallback use template title Match match = Regex.Match(template.Title, @".*?\[(.+?)\]"); if (match.Success) { // strip module from fully qualified name // since we need just the region name here as the web application can't deal with fully qualified region names yet return StripModuleFromName(match.Groups[1].Value); } // default region name return "Main"; }
protected void ProcessModule(string moduleName, Component moduleComponent) { Component designConfig = GetDesignConfigComponent(moduleComponent); if (designConfig != null) { ItemFields fields = new ItemFields(designConfig.Content, designConfig.Schema); Component zip = fields.GetComponentValue("design"); Component variables = fields.GetComponentValue("variables"); string code = fields.GetTextValue("code"); string customLess = GetModuleCustomLess(variables, code); if (zip != null) { // write binary contents as zipfile to disk string zipfile = Path.Combine(_tempFolder, moduleName + "-html-design.zip"); File.WriteAllBytes(zipfile, zip.BinaryContent.GetByteArray()); // unzip using (ZipArchive archive = ZipFile.OpenRead(zipfile)) { archive.ExtractToDirectory(_tempFolder, true); } // add content from merge files if available List<string> files = _mergeFileLines.Keys.Select(s => s).ToList(); foreach (string mergeFile in files) { string path = Path.Combine(_tempFolder, mergeFile); if (File.Exists(path)) { foreach (string line in File.ReadAllLines(path)) { if (!_mergeFileLines[mergeFile].Contains(line.Trim())) { _mergeFileLines[mergeFile].Add(line.Trim()); } } } } // add custom less code block if (!String.IsNullOrEmpty(customLess.Trim())) { _mergeFileLines["src\\system\\assets\\less\\_custom.less"].Add(customLess); } } if (moduleName.Equals("core")) { // unzip build files (nodejs, npm and grunt etc.) Component buildFiles = fields.GetComponentValue("build"); if (buildFiles != null) { ProcessBuildFiles(buildFiles); } } } }
public override void Transform(Engine engine, Package package) { Initialize(engine, package); bool cleanup; package.TryGetParameter("cleanup", out cleanup, Logger); string drive; package.TryGetParameter("drive", out drive, Logger); List<Binary> binaries = new List<Binary>(); // Read values from HTML Design Configuration Component (which should be the Component used for this Component Presentation) Component inputComponent = GetComponent(); if (inputComponent.Schema.NamespaceUri != HtmlDesignConfigNamespace || inputComponent.Schema.RootElementName != HtmlDesignConfigRootElementName) { throw new DxaException( string.Format("Unexpected input Component {0} ('{1}'). Expecting HTML Design Configuration Component.", inputComponent.Id, inputComponent.Title) ); } ItemFields htmlDesignConfigFields = new ItemFields(inputComponent.Content, inputComponent.Schema); Component favIconComponent = htmlDesignConfigFields.GetMultimediaLink("favicon"); string htmlDesignVersion = htmlDesignConfigFields.GetTextValue("version"); // Publish version.json file IDictionary<string, string> versionData = new Dictionary<string, string> { { "version", htmlDesignVersion } }; Binary versionJsonBinary = AddJsonBinary(versionData, inputComponent, Publication.RootStructureGroup, "version", variantId: "version"); binaries.Add(versionJsonBinary); string tempFolder = GetTempFolder(drive); Directory.CreateDirectory(tempFolder); Logger.Debug("Created temp folder: " + tempFolder); try { // Unzip and merge files ProcessModules(tempFolder); string distFolder = BuildHtmlDesign(tempFolder); // Save favicon to disk (if available) if (favIconComponent != null) { string favIconFilePath = Path.Combine(distFolder, "favicon.ico"); File.WriteAllBytes(favIconFilePath, favIconComponent.BinaryContent.GetByteArray()); Logger.Debug("Saved " + favIconFilePath); } // Publish all files from dist folder Publication pub = (Publication) inputComponent.ContextRepository; string rootStructureGroupWebDavUrl = pub.RootStructureGroup.WebDavUrl; RenderedItem renderedItem = engine.PublishingContext.RenderedItem; string[] distFiles = Directory.GetFiles(distFolder, "*.*", SearchOption.AllDirectories); foreach (string file in distFiles) { Logger.Debug("Found " + file); // Map the file path to a Structure Group string relativeFolderPath = file.Substring(distFolder.Length, file.LastIndexOf('\\') - distFolder.Length); Logger.Debug(string.Format("Relative folder path: '{0}'",relativeFolderPath)); string sgWebDavUrl = rootStructureGroupWebDavUrl + relativeFolderPath.Replace("system", SystemSgName).Replace('\\', '/'); StructureGroup structureGroup = engine.GetObject(sgWebDavUrl) as StructureGroup; if (structureGroup == null) { throw new DxaException(string.Format("Cannot publish '{0}' because Structure Group '{1}' does not exist.", file, sgWebDavUrl)); } // Add binary to package and publish using (FileStream fs = File.OpenRead(file)) { string filename = Path.GetFileName(file); string extension = Path.GetExtension(file); string variantId = string.Format("dist-{0}-{1}", structureGroup.Id.ItemId, filename); Item binaryItem = Package.CreateStreamItem(GetContentType(extension), fs); Binary binary = renderedItem.AddBinary( binaryItem.GetAsStream(), filename, structureGroup, variantId, inputComponent, GetMimeType(extension) ); binaryItem.Properties[Item.ItemPropertyPublishedPath] = binary.Url; package.PushItem(filename, binaryItem); binaries.Add(binary); Logger.Info(string.Format("Added Binary '{0}' related to Component '{1}' ({2}) with variant ID '{3}'", binary.Url, inputComponent.Title, inputComponent.Id, variantId)); } } } finally { if (cleanup) { Directory.Delete(tempFolder, true); Logger.Debug("Removed temp folder " + tempFolder); } else { Logger.Debug("Did not cleanup temp folder " + tempFolder); } } OutputSummary("Publish HTML Design", binaries.Select(b => b.Url)); }
public override void Transform(Engine engine, Package package) { Initialize(engine, package); mergeFileLines.Add("src\\system\\assets\\less\\_custom.less", new List<string>()); mergeFileLines.Add("src\\system\\assets\\less\\_modules.less", new List<string>()); mergeFileLines.Add("src\\templates\\partials\\module-scripts-header.hbs", new List<string>()); mergeFileLines.Add("src\\templates\\partials\\module-scripts-footer.hbs", new List<string>()); StringBuilder publishedFiles = new StringBuilder(); string cleanup = package.GetValue("cleanup") ?? String.Empty; // not using System.IO.Path.GetTempPath() because the paths in our zip are already quite long, // so we need a very short temp path for the extract of our zipfile to succeed // using drive from tridion cm homedir for temp folder tempFolder = ConfigurationSettings.GetTcmHomeDirectory().Substring(0, 3) + "t" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "\\"; try { // read values from Component var config = GetComponent(); var fields = new ItemFields(config.Content, config.Schema); var favicon = fields.GetMultimediaLink("favicon"); var version = fields.GetTextValue("version"); var nodeJs = fields.GetTextValue("nodeJs"); // set defaults if required if (String.IsNullOrEmpty(nodeJs)) { nodeJs = NodejsDefault; } PublishJson(String.Format("{{\"version\":{0}}}", JsonEncode(version)), config, GetPublication().RootStructureGroup, "version", "version"); // create temp folder Directory.CreateDirectory(tempFolder); Log.Debug("Created " + tempFolder); ProcessModules(); // build html design ProcessStartInfo info = new ProcessStartInfo { FileName = "cmd.exe", Arguments = String.Format("/c \"{0}\" start --color=false", nodeJs), WorkingDirectory = tempFolder, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, StandardErrorEncoding = Encoding.UTF8, StandardOutputEncoding = Encoding.UTF8 }; using (Process cmd = new Process {StartInfo = info}) { cmd.Start(); using (StreamReader reader = cmd.StandardOutput) { string output = reader.ReadToEnd(); if (!String.IsNullOrEmpty(output)) { Log.Info(output); // TODO: check for errors in standard output and throw exception } } using (StreamReader reader = cmd.StandardError) { string error = reader.ReadToEnd(); if (!String.IsNullOrEmpty(error)) { string user = System.Security.Principal.WindowsIdentity.GetCurrent().Name; Exception ex = new Exception(error); ex.Data.Add("Filename", info.FileName); ex.Data.Add("Arguments", info.Arguments); ex.Data.Add("User", user); if (error.ToLower().Contains("the system cannot find the path specified")) { throw new Exception(String.Format("Node.js not installed or missing from path for user {0}.", user), ex); } else if (error.ToLower().Contains("mkdir") && error.ToLower().Contains("appdata\\roaming\\npm")) { throw new Exception(String.Format("Node.js cannot access %APPDATA% for user {0}.", user), ex); } throw ex; } } cmd.WaitForExit(); } // publish all binaries from dist folder string dist = tempFolder + "dist\\"; if (Directory.Exists(dist)) { // save favicon to disk (if available) if (favicon != null) { File.WriteAllBytes(dist + "favicon.ico", favicon.BinaryContent.GetByteArray()); Log.Debug("Saved " + dist + "favicon.ico"); } string[] files = Directory.GetFiles(dist, "*.*", SearchOption.AllDirectories); foreach (var file in files) { string filename = file.Substring(file.LastIndexOf('\\') + 1); string extension = filename.Substring(filename.LastIndexOf('.') + 1); Log.Debug("Found " + file); // determine correct structure group (create if not exists) Publication pub = (Publication)config.ContextRepository; string relativeFolderPath = file.Substring(dist.Length - 1, file.LastIndexOf('\\') + 1 - dist.Length); relativeFolderPath = relativeFolderPath.Replace("system", SystemSgName).Replace('\\', '/'); string pubSgWebDavUrl = pub.RootStructureGroup.WebDavUrl; string publishSgWebDavUrl = pubSgWebDavUrl + relativeFolderPath; StructureGroup sg = engine.GetObject(publishSgWebDavUrl) as StructureGroup; if (sg == null) { throw new Exception("Missing Structure Group " + publishSgWebDavUrl); } // add binary to package and publish using (FileStream fs = File.OpenRead(file)) { Item binaryItem = Package.CreateStreamItem(GetContentType(extension), fs); var binary = engine.PublishingContext.RenderedItem.AddBinary(binaryItem.GetAsStream(), filename, sg, "dist-" + filename, config, GetMimeType(extension)); binaryItem.Properties[Item.ItemPropertyPublishedPath] = binary.Url; package.PushItem(filename, binaryItem); if (publishedFiles.Length > 0) { publishedFiles.Append(","); } publishedFiles.AppendFormat("\"{0}\"", binary.Url); Log.Info("Published " + binary.Url); } } } else { throw new Exception("Grunt build failed, dist folder is missing."); } } finally { if (String.IsNullOrEmpty(cleanup) || !cleanup.ToLower().Equals("false")) { // cleanup workfolder Directory.Delete(tempFolder, true); Log.Debug("Removed " + tempFolder); } else { Log.Debug("Did not cleanup " + tempFolder); } } // output json result package.PushItem(Package.OutputName, package.CreateStringItem(ContentType.Text, String.Format(JsonOutputFormat, publishedFiles))); }
protected Dictionary<string, Component> GetActiveModules() { Schema moduleConfigSchema = GetModuleConfigSchema(); Session session = moduleConfigSchema.Session; UsingItemsFilter moduleConfigComponentsFilter = new UsingItemsFilter(session) { ItemTypes = new[] {ItemType.Component}, BaseColumns = ListBaseColumns.Id }; Dictionary<string, Component> results = new Dictionary<string, Component>(); foreach (Component comp in moduleConfigSchema.GetUsingItems(moduleConfigComponentsFilter).Cast<Component>()) { // GetUsingItems returns the items in their Owning Publication, which could be lower in the BluePrint than were we are (so don't exist in our context Repository). Component moduleConfigComponent = (Component) Publication.GetObject(comp.Id); if (!session.IsExistingObject(moduleConfigComponent.Id)) { continue; } ItemFields fields = new ItemFields(moduleConfigComponent.Content, moduleConfigComponent.Schema); string moduleName = fields.GetTextValue("name").Trim().ToLower(); if (fields.GetTextValue("isActive").ToLower() == "yes" && !results.ContainsKey(moduleName)) { results.Add(moduleName, moduleConfigComponent); } } return results; }
public override void Transform(Engine engine, Package package) { Initialize(engine, package); _mergeFileLines.Add("src\\system\\assets\\less\\_custom.less", new List<string>()); _mergeFileLines.Add("src\\system\\assets\\less\\_modules.less", new List<string>()); _mergeFileLines.Add("src\\templates\\partials\\module-scripts-header.hbs", new List<string>()); _mergeFileLines.Add("src\\templates\\partials\\module-scripts-footer.hbs", new List<string>()); StringBuilder publishedFiles = new StringBuilder(); string drive = package.GetValue("drive") ?? String.Empty; string cleanup = package.GetValue("cleanup") ?? String.Empty; // not using System.IO.Path.GetTempPath() because the paths in our zip are already quite long, // so we need a very short temp path for the extract of our zipfile to succeed // using current time and convert to hex (the date won't matter as this folder is cleaned up so time is unique enough) int timestamp = Convert.ToInt32(DateTime.Now.ToString("HHmmssfff")); if (!String.IsNullOrEmpty(drive) && Char.IsLetter(drive.First())) { _tempFolder = drive.First() + @":\_" + timestamp.ToString("x"); } else { // using drive from tridion cm homedir for temp folder _tempFolder = ConfigurationSettings.GetTcmHomeDirectory().Substring(0, 3) + "_" + timestamp.ToString("x"); } try { // read values from Component Component config = GetComponent(); ItemFields fields = new ItemFields(config.Content, config.Schema); Component favicon = fields.GetMultimediaLink("favicon"); string version = fields.GetTextValue("version"); string url = PublishJson(String.Format("{{\"version\":{0}}}", JsonEncode(version)), config, GetPublication().RootStructureGroup, "version", "version"); publishedFiles.AppendCommaSeparated(url); Logger.Info("Published " + url); // create temp folder Directory.CreateDirectory(_tempFolder); Logger.Debug("Created " + _tempFolder); // unzip and merge files ProcessModules(); // build html design string user = System.Security.Principal.WindowsIdentity.GetCurrent().Name; ProcessStartInfo info = new ProcessStartInfo { FileName = "cmd.exe", Arguments = "/c npm start --color=false", WorkingDirectory = _tempFolder, CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, StandardErrorEncoding = Encoding.UTF8, StandardOutputEncoding = Encoding.UTF8 }; using (Process cmd = new Process { StartInfo = info }) { cmd.Start(); using (StreamReader reader = cmd.StandardOutput) { string output = reader.ReadToEnd(); if (!String.IsNullOrEmpty(output)) { Logger.Info(output); // TODO: check for errors in standard output and throw exception } } using (StreamReader reader = cmd.StandardError) { string error = reader.ReadToEnd(); if (!String.IsNullOrEmpty(error)) { Exception ex = new Exception(error); ex.Data.Add("Filename", info.FileName); ex.Data.Add("Arguments", info.Arguments); ex.Data.Add("User", user); // TODO: check for known errors and throw exception with a user friendly message //if (error.ToLower().Contains("something")) //{ // throw new Exception(String.Format("Something went wrong for user {0}.", user), ex); //} throw ex; } } cmd.WaitForExit(); } // publish all binaries from dist folder string dist = Path.Combine(_tempFolder, "dist"); if (Directory.Exists(dist)) { // save favicon to disk (if available) if (favicon != null) { string ico = Path.Combine(dist, "favicon.ico"); File.WriteAllBytes(ico, favicon.BinaryContent.GetByteArray()); Logger.Debug("Saved " + ico); } string[] files = Directory.GetFiles(dist, "*.*", SearchOption.AllDirectories); foreach (string file in files) { string filename = Path.GetFileName(file); string extension = Path.GetExtension(file); Logger.Debug("Found " + file); // determine correct structure group Publication pub = (Publication)config.ContextRepository; string relativeFolderPath = file.Substring(dist.Length, file.LastIndexOf('\\') - dist.Length); Logger.Debug("Relative path: " + relativeFolderPath); relativeFolderPath = relativeFolderPath.Replace("system", SystemSgName).Replace('\\', '/'); string pubSgWebDavUrl = pub.RootStructureGroup.WebDavUrl; string publishSgWebDavUrl = pubSgWebDavUrl + relativeFolderPath; Logger.Debug("Structure Group WebDAV URL: " + publishSgWebDavUrl); StructureGroup sg = engine.GetObject(publishSgWebDavUrl) as StructureGroup; if (sg == null) { throw new Exception("Missing Structure Group " + publishSgWebDavUrl); } // add binary to package and publish using (FileStream fs = File.OpenRead(file)) { Item binaryItem = Package.CreateStreamItem(GetContentType(extension), fs); Binary binary = engine.PublishingContext.RenderedItem.AddBinary(binaryItem.GetAsStream(), filename, sg, "dist-" + filename, config, GetMimeType(extension)); binaryItem.Properties[Item.ItemPropertyPublishedPath] = binary.Url; package.PushItem(filename, binaryItem); publishedFiles.AppendCommaSeparated("\"{0}\"", binary.Url); Logger.Info("Published " + binary.Url); } } } else { throw new Exception("Grunt build failed, dist folder is missing."); } } finally { if (String.IsNullOrEmpty(cleanup) || !cleanup.ToLower().Equals("false")) { // cleanup workfolder Directory.Delete(_tempFolder, true); Logger.Debug("Removed " + _tempFolder); } else { Logger.Debug("Did not cleanup " + _tempFolder); } } // output json result package.PushItem(Package.OutputName, package.CreateStringItem(ContentType.Text, String.Format(JsonOutputFormat, publishedFiles))); }
protected Dictionary<string, Component> GetActiveModules(Component coreConfigComponent = null) { Schema moduleConfigSchema = coreConfigComponent != null ? coreConfigComponent.Schema : GetModuleConfigSchema(); Dictionary<string, Component> results = new Dictionary<string, Component>(); foreach (KeyValuePair<TcmUri, string> item in GetUsingItems(moduleConfigSchema, ItemType.Component)) { try { Component comp = (Component)Engine.GetObject(Engine.LocalizeUri(item.Key)); ItemFields fields = new ItemFields(comp.Content, comp.Schema); string moduleName = GetModuleNameFromConfig(comp).ToLower(); if (fields.GetTextValue("isActive").ToLower() == "yes" && !results.ContainsKey(moduleName)) { results.Add(moduleName, comp); } } catch (Exception) { //Do nothing, this module is not available in this publication } } return results; }