コード例 #1
0
        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);
        }
コード例 #2
0
        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");
        }
コード例 #3
0
        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);
                    }
                }
            }
        }
コード例 #4
0
 private string GetSiteIdFromPublication(Publication startPublication)
 {
     if (startPublication.Metadata != null)
     {
         ItemFields meta = new ItemFields(startPublication.Metadata, startPublication.MetadataSchema);
         return(meta.GetTextValue("siteId"));
     }
     return(null);
 }
コード例 #5
0
        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")));
        }
コード例 #6
0
 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);
 }
コード例 #7
0
        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);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
ファイル: PublishHtmlDesign.cs プロジェクト: MrSnowflake/tri
 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);
             }
         }
     }
 }
コード例 #11
0
 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;
 }
コード例 #12
0
 private string GetSiteIdFromPublication(Publication startPublication)
 {
     if (startPublication.Metadata!=null)
     {
         ItemFields meta = new ItemFields(startPublication.Metadata, startPublication.MetadataSchema);
         return meta.GetTextValue("siteId");
     }
     return null;
 }
コード例 #13
0
        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));
        }
コード例 #14
0
        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)));
        }
コード例 #15
0
 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;
 }
コード例 #16
0
        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"));
        }
コード例 #17
0
        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";
        }
コード例 #18
0
        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);
                    }
                }
            }
        }
コード例 #19
0
        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));
        }
コード例 #20
0
ファイル: PublishHtmlDesign.cs プロジェクト: MrSnowflake/tri
        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)));
        }
コード例 #21
0
        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;
        }
コード例 #22
0
        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)));
        }
コード例 #23
0
 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;
 }