From 520955a8db0217349a1e27cc7fe0ed3b364bda30 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 1 Dec 2014 12:59:36 +1100 Subject: [PATCH] WIP - ported over viewhelper and MasterpageHelper to the Core lib, still wrapping new file service from old template class. --- src/Umbraco.Core/Models/Template.cs | 12 +- src/Umbraco.Core/Services/FileService.cs | 1 - .../Services/MasterPageHelper.cs} | 805 +++++++++--------- src/Umbraco.Core/Services/ViewHelper.cs | 120 +++ src/Umbraco.Core/Umbraco.Core.csproj | 2 + .../Templates/MasterPageHelperTests.cs | 1 + .../umbraco/Trees/loadTemplates.cs | 12 +- .../businesslogic/template/Template.cs | 91 +- .../businesslogic/template/ViewHelper.cs | 120 --- src/umbraco.cms/umbraco.cms.csproj | 2 - 10 files changed, 593 insertions(+), 573 deletions(-) rename src/{umbraco.cms/businesslogic/template/MasterpageHelper.cs => Umbraco.Core/Services/MasterPageHelper.cs} (54%) create mode 100644 src/Umbraco.Core/Services/ViewHelper.cs delete mode 100644 src/umbraco.cms/businesslogic/template/ViewHelper.cs diff --git a/src/Umbraco.Core/Models/Template.cs b/src/Umbraco.Core/Models/Template.cs index 4659595049..a8860fdf09 100644 --- a/src/Umbraco.Core/Models/Template.cs +++ b/src/Umbraco.Core/Models/Template.cs @@ -67,10 +67,18 @@ namespace Umbraco.Core.Models } [DataMember] - string ITemplate.Name { get; set; } + string ITemplate.Name + { + get { return _name; } + set { _name = value; } + } [DataMember] - string ITemplate.Alias { get; set; } + string ITemplate.Alias + { + get { return _alias; } + set { _alias = value; } + } public override string Alias { diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index a5685756c4..6cac0cc808 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Remoting.Messaging; -using System.Text; using System.Text.RegularExpressions; using System.Web; using Umbraco.Core.Auditing; diff --git a/src/umbraco.cms/businesslogic/template/MasterpageHelper.cs b/src/Umbraco.Core/Services/MasterPageHelper.cs similarity index 54% rename from src/umbraco.cms/businesslogic/template/MasterpageHelper.cs rename to src/Umbraco.Core/Services/MasterPageHelper.cs index c72bba8fb1..652887d212 100644 --- a/src/umbraco.cms/businesslogic/template/MasterpageHelper.cs +++ b/src/Umbraco.Core/Services/MasterPageHelper.cs @@ -1,390 +1,415 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using Umbraco.Core; -using Umbraco.Core.IO; - -namespace umbraco.cms.businesslogic.template -{ - internal class MasterPageHelper - { - internal static readonly string DefaultMasterTemplate = SystemDirectories.Umbraco + "/masterpages/default.master"; - private static readonly char[] NewLineChars = Environment.NewLine.ToCharArray(); - - internal static bool MasterPageExists(Template t) - { - return File.Exists(GetFilePath(t)); - } - - internal static string GetFilePath(Template t) - { - return IOHelper.MapPath(SystemDirectories.Masterpages + "/" + t.Alias.Replace(" ", "") + ".master"); - } - - internal static string CreateMasterPage(Template t, bool overWrite = false) - { - string masterpageContent = ""; - - if (!File.Exists(GetFilePath(t)) || overWrite) - { - masterpageContent = CreateDefaultMasterPageContent(t, t.Alias); - SaveDesignToFile(t, null, masterpageContent); - } - else - { - System.IO.TextReader tr = new StreamReader(GetFilePath(t)); - masterpageContent = tr.ReadToEnd(); - tr.Close(); - } - - return masterpageContent; - } - - internal static string GetFileContents(Template t) - { - string masterpageContent = ""; - if (File.Exists(GetFilePath(t))) - { - System.IO.TextReader tr = new StreamReader(GetFilePath(t)); - masterpageContent = tr.ReadToEnd(); - tr.Close(); - } - - return masterpageContent; - } - - internal static string UpdateMasterPageFile(Template t, string currentAlias) - { - var template = UpdateMasterPageContent(t, currentAlias); - UpdateChildTemplates(t, currentAlias); - SaveDesignToFile(t, currentAlias, template); - - return template; - } - - internal static string CreateDefaultMasterPageContent(Template template, string currentAlias) - { - StringBuilder design = new StringBuilder(); - design.Append(GetMasterPageHeader(template) + Environment.NewLine); - - if (template.HasMasterTemplate) - { - var master = new Template(template.MasterTemplate); - - foreach (string cpId in master.contentPlaceholderIds()) - { - design.Append("" + - Environment.NewLine + - Environment.NewLine + - "" + - Environment.NewLine + - Environment.NewLine); - } - } - else - { - design.Append(GetMasterContentElement(template) + Environment.NewLine); - design.Append(template.Design + Environment.NewLine); - design.Append("" + Environment.NewLine); - } - - return design.ToString(); - } - - internal static string UpdateMasterPageContent(Template template, string currentAlias) - { - var masterPageContent = template.Design; - - if (!string.IsNullOrEmpty(currentAlias) && currentAlias != template.Alias) - { - string masterHeader = - masterPageContent.Substring(0, masterPageContent.IndexOf("%>") + 2).Trim( - Environment.NewLine.ToCharArray()); - - // find the masterpagefile attribute - MatchCollection m = Regex.Matches(masterHeader, "(?\\S*)=\"(?[^\"]*)\"", - RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - - foreach (Match attributeSet in m) - { - if (attributeSet.Groups["attributeName"].Value.ToLower() == "masterpagefile") - { - // validate the masterpagefile - string currentMasterPageFile = attributeSet.Groups["attributeValue"].Value; - string currentMasterTemplateFile = ParentTemplatePath(template); - - if (currentMasterPageFile != currentMasterTemplateFile) - { - masterPageContent = - masterPageContent.Replace( - attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterPageFile + "\"", - attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterTemplateFile + - "\""); - } - } - } - } - - return masterPageContent; - } - - private static void UpdateChildTemplates(Template t, string currentAlias) - { - //if we have a Old Alias if the alias and therefor the masterpage file name has changed... - //so before we save the new masterfile, we'll clear the old one, so we don't up with - //Unused masterpage files - if (!string.IsNullOrEmpty(currentAlias) && currentAlias != t.Alias) - { - //Ensure that child templates have the right master masterpage file name - if (t.HasChildren) - { - var c = t.Children; - foreach (CMSNode cmn in c) - UpdateMasterPageFile(new Template(cmn.Id), null); - } - } - } - - - private static void SaveDesignToFile(Template t, string currentAlias, string design) - { - //kill the old file.. - if (!string.IsNullOrEmpty(currentAlias) && currentAlias != t.Alias) - { - string _oldFile = - IOHelper.MapPath(SystemDirectories.Masterpages + "/" + currentAlias.Replace(" ", "") + ".master"); - if (System.IO.File.Exists(_oldFile)) - System.IO.File.Delete(_oldFile); - } - - // save the file in UTF-8 - System.IO.File.WriteAllText(GetFilePath(t), design, System.Text.Encoding.UTF8); - } - - internal static void RemoveMasterPageFile(string alias) - { - if (!string.IsNullOrWhiteSpace(alias)) - { - string file = IOHelper.MapPath(SystemDirectories.Masterpages + "/" + alias.Replace(" ", "") + ".master"); - if (System.IO.File.Exists(file)) - System.IO.File.Delete(file); - } - } - - internal static string SaveTemplateToFile(Template template, string currentAlias) - { - var masterPageContent = template.Design; - if (!IsMasterPageSyntax(masterPageContent)) - masterPageContent = ConvertToMasterPageSyntax(template); - - // Add header to master page if it doesn't exist - if (!masterPageContent.TrimStart().StartsWith("<%@")) - { - masterPageContent = GetMasterPageHeader(template) + Environment.NewLine + masterPageContent; - } - else - { - // verify that the masterpage attribute is the same as the masterpage - string masterHeader = - masterPageContent.Substring(0, masterPageContent.IndexOf("%>") + 2).Trim(NewLineChars); - - // find the masterpagefile attribute - MatchCollection m = Regex.Matches(masterHeader, "(?\\S*)=\"(?[^\"]*)\"", - RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - - foreach (Match attributeSet in m) - { - if (attributeSet.Groups["attributeName"].Value.ToLower() == "masterpagefile") - { - // validate the masterpagefile - string currentMasterPageFile = attributeSet.Groups["attributeValue"].Value; - string currentMasterTemplateFile = ParentTemplatePath(template); - - if (currentMasterPageFile != currentMasterTemplateFile) - { - masterPageContent = - masterPageContent.Replace( - attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterPageFile + "\"", - attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterTemplateFile + - "\""); - - } - } - } - - } - - //we have a Old Alias if the alias and therefor the masterpage file name has changed... - //so before we save the new masterfile, we'll clear the old one, so we don't up with - //Unused masterpage files - if (!string.IsNullOrEmpty(currentAlias) && currentAlias != template.Alias) - { - - //Ensure that child templates have the right master masterpage file name - if (template.HasChildren) - { - var c = template.Children; - foreach (CMSNode cmn in c) - UpdateMasterPageFile(new Template(cmn.Id), null); - } - - //then kill the old file.. - string _oldFile = IOHelper.MapPath(SystemDirectories.Masterpages + "/" + currentAlias.Replace(" ", "") + ".master"); - if (System.IO.File.Exists(_oldFile)) - System.IO.File.Delete(_oldFile); - } - - // save the file in UTF-8 - System.IO.File.WriteAllText(GetFilePath(template), masterPageContent, System.Text.Encoding.UTF8); - - return masterPageContent; - } - - internal static string ConvertToMasterPageSyntax(Template template) - { - string masterPageContent = GetMasterContentElement(template) + Environment.NewLine; - - masterPageContent += template.Design; - - // Parse the design for getitems - masterPageContent = EnsureMasterPageSyntax(template.Alias, masterPageContent); - - // append ending asp:content element - masterPageContent += Environment.NewLine + "" + Environment.NewLine; - - return masterPageContent; - } - - internal static bool IsMasterPageSyntax(string code) - { - return Regex.IsMatch(code, @"<%@\s*Master", RegexOptions.IgnoreCase) || - code.InvariantContains("", ParentTemplatePath(template)) + Environment.NewLine; - } - - private static string ParentTemplatePath(Template template) - { - var masterTemplate = DefaultMasterTemplate; - if (template.MasterTemplate != 0) - masterTemplate = SystemDirectories.Masterpages + "/" + new Template(template.MasterTemplate).Alias.Replace(" ", "") + ".master"; - - return masterTemplate; - } - - private static string GetMasterContentElement(Template template) - { - if (template.MasterTemplate != 0) - { - string masterAlias = new Template(template.MasterTemplate).Alias.Replace(" ", ""); - return - String.Format("", - template.Alias.Replace(" ", ""), masterAlias); - } - else - return - String.Format("", - template.Alias.Replace(" ", "")); - - } - - internal static string EnsureMasterPageSyntax(string templateAlias, string masterPageContent) - { - ReplaceElement(ref masterPageContent, "?UMBRACO_GETITEM", "umbraco:Item", true); - ReplaceElement(ref masterPageContent, "?UMBRACO_GETITEM", "umbraco:Item", false); - - // Parse the design for macros - ReplaceElement(ref masterPageContent, "?UMBRACO_MACRO", "umbraco:Macro", true); - ReplaceElement(ref masterPageContent, "?UMBRACO_MACRO", "umbraco:Macro", false); - - // Parse the design for load childs - masterPageContent = masterPageContent.Replace("", CreateDefaultPlaceHolder(templateAlias)) - .Replace("", CreateDefaultPlaceHolder(templateAlias)); - // Parse the design for aspnet forms - GetAspNetMasterPageForm(ref masterPageContent, templateAlias); - masterPageContent = masterPageContent.Replace("", ""); - // Parse the design for aspnet heads - masterPageContent = masterPageContent.Replace("", String.Format("", templateAlias.Replace(" ", ""))); - masterPageContent = masterPageContent.Replace("", ""); - return masterPageContent; - } - - - private static void GetAspNetMasterPageForm(ref string design, string templateAlias) - { - Match formElement = Regex.Match(design, GetElementRegExp("?ASPNET_FORM", false), RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - - if (formElement != null && formElement.Value != "") - { - string formReplace = String.Format("
", templateAlias.Replace(" ", "")); - if (formElement.Groups.Count == 0) - { - formReplace += ""; - } - design = design.Replace(formElement.Value, formReplace); - } - } - - private static string CreateDefaultPlaceHolder(string templateAlias) - { - return String.Format("", templateAlias.Replace(" ", "")); - } - - private static void ReplaceElement(ref string design, string elementName, string newElementName, bool checkForQuotes) - { - MatchCollection m = - Regex.Matches(design, GetElementRegExp(elementName, checkForQuotes), - RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - - foreach (Match match in m) - { - GroupCollection groups = match.Groups; - - // generate new element (compensate for a closing trail on single elements ("/")) - string elementAttributes = groups[1].Value; - // test for macro alias - if (elementName == "?UMBRACO_MACRO") - { - Hashtable tags = helpers.xhtml.ReturnAttributes(match.Value); - if (tags["macroAlias"] != null) - elementAttributes = String.Format(" Alias=\"{0}\"", tags["macroAlias"].ToString()) + elementAttributes; - else if (tags["macroalias"] != null) - elementAttributes = String.Format(" Alias=\"{0}\"", tags["macroalias"].ToString()) + elementAttributes; - } - string newElement = "<" + newElementName + " runat=\"server\" " + elementAttributes.Trim() + ">"; - if (elementAttributes.EndsWith("/")) - { - elementAttributes = elementAttributes.Substring(0, elementAttributes.Length - 1); - } - else if (groups[0].Value.StartsWith(""; - - if (checkForQuotes) - { - // if it's inside quotes, we'll change element attribute quotes to single quotes - newElement = newElement.Replace("\"", "'"); - newElement = String.Format("\"{0}\"", newElement); - } - design = design.Replace(match.Value, newElement); - } - } - - private static string GetElementRegExp(string elementName, bool checkForQuotes) - { - if (checkForQuotes) - return String.Format("\"<[^>\\s]*\\b{0}(\\b[^>]*)>\"", elementName); - else - return String.Format("<[^>\\s]*\\b{0}(\\b[^>]*)>", elementName); - - } - - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Umbraco.Core.IO; +using Umbraco.Core.Models; + +namespace Umbraco.Core.Services +{ + internal class MasterPageHelper + { + internal static readonly string DefaultMasterTemplate = SystemDirectories.Umbraco + "/masterpages/default.master"; + private static readonly char[] NewLineChars = Environment.NewLine.ToCharArray(); + + internal static bool MasterPageExists(ITemplate t) + { + return System.IO.File.Exists(GetFilePath(t)); + } + + internal static string GetFilePath(ITemplate t) + { + return IOHelper.MapPath(SystemDirectories.Masterpages + "/" + t.Alias.Replace(" ", "") + ".master"); + } + + internal static string CreateMasterPage(ITemplate t, IFileService fileService, bool overWrite = false) + { + string masterpageContent = ""; + + if (System.IO.File.Exists(GetFilePath(t)) == false || overWrite) + { + masterpageContent = CreateDefaultMasterPageContent(t, t.Alias, fileService); + SaveDesignToFile(t, null, masterpageContent); + } + else + { + using (var tr = new StreamReader(GetFilePath(t))) + { + masterpageContent = tr.ReadToEnd(); + tr.Close(); + } + } + + return masterpageContent; + } + + internal static string GetFileContents(ITemplate t) + { + string masterpageContent = ""; + if (System.IO.File.Exists(GetFilePath(t))) + { + using (var tr = new StreamReader(GetFilePath(t))) + { + masterpageContent = tr.ReadToEnd(); + tr.Close(); + } + } + + return masterpageContent; + } + + internal static string UpdateMasterPageFile(ITemplate t, string currentAlias, IFileService fileService) + { + var template = UpdateMasterPageContent(t, currentAlias); + UpdateChildTemplates(t, currentAlias, fileService); + SaveDesignToFile(t, currentAlias, template); + + return template; + } + + internal static string CreateDefaultMasterPageContent(ITemplate template, string currentAlias, IFileService fileService) + { + var design = new StringBuilder(); + design.Append(GetMasterPageHeader(template) + Environment.NewLine); + + if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false) + { + var master = fileService.GetTemplate(template.MasterTemplateAlias); + if (master != null) + { + foreach (var cpId in GetContentPlaceholderIds(master)) + { + design.Append("" + + Environment.NewLine + + Environment.NewLine + + "" + + Environment.NewLine + + Environment.NewLine); + } + + return design.ToString(); + } + } + + design.Append(GetMasterContentElement(template) + Environment.NewLine); + design.Append(template.Content + Environment.NewLine); + design.Append("" + Environment.NewLine); + + return design.ToString(); + } + + internal static IEnumerable GetContentPlaceholderIds(ITemplate template) + { + var retVal = new List(); + + var mp = template.Content; + var path = ""; + var r = new Regex(path, RegexOptions.IgnoreCase); + var m = r.Match(mp); + + while (m.Success) + { + var cc = m.Groups[3].Captures; + retVal.AddRange(cc.Cast().Where(c => c.Value != "server").Select(c => c.Value)); + + m = m.NextMatch(); + } + + return retVal; + } + + internal static string UpdateMasterPageContent(ITemplate template, string currentAlias) + { + var masterPageContent = template.Content; + + if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != template.Alias) + { + var masterHeader = + masterPageContent.Substring(0, masterPageContent.IndexOf("%>", StringComparison.Ordinal) + 2).Trim( + Environment.NewLine.ToCharArray()); + + // find the masterpagefile attribute + var m = Regex.Matches(masterHeader, "(?\\S*)=\"(?[^\"]*)\"", + RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + + foreach (Match attributeSet in m) + { + if (attributeSet.Groups["attributeName"].Value.ToLower() == "masterpagefile") + { + // validate the masterpagefile + var currentMasterPageFile = attributeSet.Groups["attributeValue"].Value; + var currentMasterTemplateFile = ParentTemplatePath(template); + + if (currentMasterPageFile != currentMasterTemplateFile) + { + masterPageContent = + masterPageContent.Replace( + attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterPageFile + "\"", + attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterTemplateFile + + "\""); + } + } + } + } + + return masterPageContent; + } + + private static void UpdateChildTemplates(ITemplate template, string currentAlias, IFileService fileService) + { + //if we have a Old Alias if the alias and therefor the masterpage file name has changed... + //so before we save the new masterfile, we'll clear the old one, so we don't up with + //Unused masterpage files + if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != template.Alias) + { + //Ensure that child templates have the right master masterpage file name + if (template.IsMasterTemplate) + { + var children = fileService.GetTemplates(template.Id); + foreach (var t in children) + UpdateMasterPageFile(t, null, fileService); + } + } + } + + + private static void SaveDesignToFile(ITemplate t, string currentAlias, string design) + { + //kill the old file.. + if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != t.Alias) + { + var oldFile = + IOHelper.MapPath(SystemDirectories.Masterpages + "/" + currentAlias.Replace(" ", "") + ".master"); + if (System.IO.File.Exists(oldFile)) + System.IO.File.Delete(oldFile); + } + + // save the file in UTF-8 + System.IO.File.WriteAllText(GetFilePath(t), design, Encoding.UTF8); + } + + internal static void RemoveMasterPageFile(string alias) + { + if (string.IsNullOrWhiteSpace(alias) == false) + { + string file = IOHelper.MapPath(SystemDirectories.Masterpages + "/" + alias.Replace(" ", "") + ".master"); + if (System.IO.File.Exists(file)) + System.IO.File.Delete(file); + } + } + + internal static string SaveTemplateToFile(ITemplate template, string currentAlias, IFileService fileService) + { + var masterPageContent = template.Content; + if (IsMasterPageSyntax(masterPageContent) == false) + masterPageContent = ConvertToMasterPageSyntax(template); + + // Add header to master page if it doesn't exist + if (masterPageContent.TrimStart().StartsWith("<%@") == false) + { + masterPageContent = GetMasterPageHeader(template) + Environment.NewLine + masterPageContent; + } + else + { + // verify that the masterpage attribute is the same as the masterpage + var masterHeader = + masterPageContent.Substring(0, masterPageContent.IndexOf("%>", StringComparison.Ordinal) + 2).Trim(NewLineChars); + + // find the masterpagefile attribute + var m = Regex.Matches(masterHeader, "(?\\S*)=\"(?[^\"]*)\"", + RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + + foreach (Match attributeSet in m) + { + if (attributeSet.Groups["attributeName"].Value.ToLower() == "masterpagefile") + { + // validate the masterpagefile + var currentMasterPageFile = attributeSet.Groups["attributeValue"].Value; + var currentMasterTemplateFile = ParentTemplatePath(template); + + if (currentMasterPageFile != currentMasterTemplateFile) + { + masterPageContent = + masterPageContent.Replace( + attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterPageFile + "\"", + attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterTemplateFile + + "\""); + + } + } + } + + } + + //we have a Old Alias if the alias and therefor the masterpage file name has changed... + //so before we save the new masterfile, we'll clear the old one, so we don't up with + //Unused masterpage files + if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != template.Alias) + { + + //Ensure that child templates have the right master masterpage file name + if (template.IsMasterTemplate) + { + var children = fileService.GetTemplates(template.Id); + + foreach (var t in children) + UpdateMasterPageFile(t, null, fileService); + } + + //then kill the old file.. + var oldFile = IOHelper.MapPath(SystemDirectories.Masterpages + "/" + currentAlias.Replace(" ", "") + ".master"); + if (System.IO.File.Exists(oldFile)) + System.IO.File.Delete(oldFile); + } + + // save the file in UTF-8 + System.IO.File.WriteAllText(GetFilePath(template), masterPageContent, Encoding.UTF8); + + return masterPageContent; + } + + internal static string ConvertToMasterPageSyntax(ITemplate template) + { + string masterPageContent = GetMasterContentElement(template) + Environment.NewLine; + + masterPageContent += template.Content; + + // Parse the design for getitems + masterPageContent = EnsureMasterPageSyntax(template.Alias, masterPageContent); + + // append ending asp:content element + masterPageContent += Environment.NewLine + "" + Environment.NewLine; + + return masterPageContent; + } + + internal static bool IsMasterPageSyntax(string code) + { + return Regex.IsMatch(code, @"<%@\s*Master", RegexOptions.IgnoreCase) || + code.InvariantContains("", ParentTemplatePath(template)) + Environment.NewLine; + } + + private static string ParentTemplatePath(ITemplate template) + { + var masterTemplate = DefaultMasterTemplate; + if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false) + masterTemplate = SystemDirectories.Masterpages + "/" + template.MasterTemplateAlias + ".master"; + + return masterTemplate; + } + + private static string GetMasterContentElement(ITemplate template) + { + if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false) + { + string masterAlias = template.MasterTemplateAlias; + return + String.Format("", masterAlias); + } + else + return + String.Format(""); + + } + + internal static string EnsureMasterPageSyntax(string templateAlias, string masterPageContent) + { + ReplaceElement(ref masterPageContent, "?UMBRACO_GETITEM", "umbraco:Item", true); + ReplaceElement(ref masterPageContent, "?UMBRACO_GETITEM", "umbraco:Item", false); + + // Parse the design for macros + ReplaceElement(ref masterPageContent, "?UMBRACO_MACRO", "umbraco:Macro", true); + ReplaceElement(ref masterPageContent, "?UMBRACO_MACRO", "umbraco:Macro", false); + + // Parse the design for load childs + masterPageContent = masterPageContent.Replace("", CreateDefaultPlaceHolder(templateAlias)) + .Replace("", CreateDefaultPlaceHolder(templateAlias)); + // Parse the design for aspnet forms + GetAspNetMasterPageForm(ref masterPageContent, templateAlias); + masterPageContent = masterPageContent.Replace("", ""); + // Parse the design for aspnet heads + masterPageContent = masterPageContent.Replace("", String.Format("", templateAlias.Replace(" ", ""))); + masterPageContent = masterPageContent.Replace("", ""); + return masterPageContent; + } + + + private static void GetAspNetMasterPageForm(ref string design, string templateAlias) + { + var formElement = Regex.Match(design, GetElementRegExp("?ASPNET_FORM", false), RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + + if (string.IsNullOrEmpty(formElement.Value) == false) + { + string formReplace = String.Format("
", templateAlias.Replace(" ", "")); + if (formElement.Groups.Count == 0) + { + formReplace += ""; + } + design = design.Replace(formElement.Value, formReplace); + } + } + + private static string CreateDefaultPlaceHolder(string templateAlias) + { + return String.Format("", templateAlias.Replace(" ", "")); + } + + private static void ReplaceElement(ref string design, string elementName, string newElementName, bool checkForQuotes) + { + var m = + Regex.Matches(design, GetElementRegExp(elementName, checkForQuotes), + RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + + foreach (Match match in m) + { + GroupCollection groups = match.Groups; + + // generate new element (compensate for a closing trail on single elements ("/")) + string elementAttributes = groups[1].Value; + // test for macro alias + if (elementName == "?UMBRACO_MACRO") + { + var tags = XmlHelper.GetAttributesFromElement(match.Value); + if (tags["macroAlias"] != null) + elementAttributes = String.Format(" Alias=\"{0}\"", tags["macroAlias"]) + elementAttributes; + else if (tags["macroalias"] != null) + elementAttributes = String.Format(" Alias=\"{0}\"", tags["macroalias"]) + elementAttributes; + } + string newElement = "<" + newElementName + " runat=\"server\" " + elementAttributes.Trim() + ">"; + if (elementAttributes.EndsWith("/")) + { + elementAttributes = elementAttributes.Substring(0, elementAttributes.Length - 1); + } + else if (groups[0].Value.StartsWith(""; + + if (checkForQuotes) + { + // if it's inside quotes, we'll change element attribute quotes to single quotes + newElement = newElement.Replace("\"", "'"); + newElement = String.Format("\"{0}\"", newElement); + } + design = design.Replace(match.Value, newElement); + } + } + + private static string GetElementRegExp(string elementName, bool checkForQuotes) + { + if (checkForQuotes) + return String.Format("\"<[^>\\s]*\\b{0}(\\b[^>]*)>\"", elementName); + else + return String.Format("<[^>\\s]*\\b{0}(\\b[^>]*)>", elementName); + + } + + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Services/ViewHelper.cs b/src/Umbraco.Core/Services/ViewHelper.cs new file mode 100644 index 0000000000..c456352f7d --- /dev/null +++ b/src/Umbraco.Core/Services/ViewHelper.cs @@ -0,0 +1,120 @@ +using System.IO; +using System.Text; +using Umbraco.Core.IO; +using Umbraco.Core.Models; + +namespace Umbraco.Core.Services +{ + internal class ViewHelper + { + internal static bool ViewExists(ITemplate t) + { + string path = GetFilePath(t); + return System.IO.File.Exists(path); + } + + internal static string GetFilePath(ITemplate t) + { + return IOHelper.MapPath(ViewPath(t.Alias)); + } + + internal static string GetFileContents(ITemplate t) + { + string viewContent = ""; + string path = IOHelper.MapPath(ViewPath(t.Alias)); + + if (System.IO.File.Exists(path)) + { + TextReader tr = new StreamReader(path); + viewContent = tr.ReadToEnd(); + tr.Close(); + } + + return viewContent; + } + + internal static string CreateViewFile(ITemplate t, bool overWrite = false) + { + string viewContent; + string path = IOHelper.MapPath(ViewPath(t.Alias)); + + if (System.IO.File.Exists(path) == false || overWrite) + viewContent = SaveTemplateToFile(t, t.Alias); + else + { + TextReader tr = new StreamReader(path); + viewContent = tr.ReadToEnd(); + tr.Close(); + } + + return viewContent; + } + + internal static string SaveTemplateToFile(ITemplate template, string currentAlias) + { + var design = EnsureInheritedLayout(template); + System.IO.File.WriteAllText(IOHelper.MapPath(ViewPath(template.Alias)), design, Encoding.UTF8); + + return template.Content; + } + + internal static string UpdateViewFile(ITemplate t, string currentAlias = null) + { + var path = IOHelper.MapPath(ViewPath(t.Alias)); + + if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != t.Alias) + { + //NOTE: I don't think this is needed for MVC, this was ported over from the + // masterpages helper but I think only relates to when templates are stored in the db. + ////Ensure that child templates have the right master masterpage file name + //if (t.HasChildren) + //{ + // var c = t.Children; + // foreach (CMSNode cmn in c) + // UpdateViewFile(new Template(cmn.Id), null); + //} + + //then kill the old file.. + var oldFile = IOHelper.MapPath(ViewPath(currentAlias)); + if (System.IO.File.Exists(oldFile)) + System.IO.File.Delete(oldFile); + } + + System.IO.File.WriteAllText(path, t.Content, Encoding.UTF8); + return t.Content; + } + + internal static void RemoveViewFile(string alias) + { + if (string.IsNullOrWhiteSpace(alias) == false) + { + var file = IOHelper.MapPath(ViewPath(alias)); + if (System.IO.File.Exists(file)) + System.IO.File.Delete(file); + } + } + + public static string ViewPath(string alias) + { + return SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml"; + } + + private static string EnsureInheritedLayout(ITemplate template) + { + string design = template.Content; + + if (string.IsNullOrEmpty(design)) + { + design = @"@inherits Umbraco.Web.Mvc.UmbracoTemplatePage +@{ + Layout = null; +}"; + + if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false) + design = design.Replace("null", string.Format("\"{0}.cshtml\"", template.MasterTemplateAlias)); + } + + return design; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 1bb6293a51..32b035d02a 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1070,6 +1070,7 @@ + @@ -1086,6 +1087,7 @@ + diff --git a/src/Umbraco.Tests/Templates/MasterPageHelperTests.cs b/src/Umbraco.Tests/Templates/MasterPageHelperTests.cs index f52b7b68d9..292948713a 100644 --- a/src/Umbraco.Tests/Templates/MasterPageHelperTests.cs +++ b/src/Umbraco.Tests/Templates/MasterPageHelperTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using NUnit.Framework; using umbraco.cms.businesslogic.template; +using Umbraco.Core.Services; namespace Umbraco.Tests.Templates { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadTemplates.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadTemplates.cs index f251e2499d..031d64009a 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadTemplates.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadTemplates.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Data; +using System.Globalization; using System.IO; using System.Text; using System.Web; @@ -22,6 +23,7 @@ using umbraco.cms.businesslogic.media; using umbraco.cms.businesslogic.member; using umbraco.cms.businesslogic.property; using umbraco.cms.businesslogic.web; +using Umbraco.Core.Services; using umbraco.interfaces; using umbraco.DataLayer; using umbraco.cms.businesslogic.template; @@ -184,20 +186,20 @@ namespace umbraco private void RenderTemplates(ref XmlTree tree) { List