Removing uncommented code from the Media class as well as from the ContentExtension class. Added saving of Media Xml to MediaService upon saving. Removing referenced media test from csproj as cs file was missing.
881 lines
31 KiB
C#
881 lines
31 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Collections;
|
|
using System.Xml;
|
|
using Umbraco.Core;
|
|
using Umbraco.Core.Logging;
|
|
using umbraco.DataLayer;
|
|
using System.Text.RegularExpressions;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using umbraco.cms.businesslogic.cache;
|
|
using umbraco.BusinessLogic;
|
|
using umbraco.IO;
|
|
using umbraco.cms.businesslogic.web;
|
|
|
|
namespace umbraco.cms.businesslogic.template
|
|
{
|
|
/// <summary>
|
|
/// Summary description for Template.
|
|
/// </summary>
|
|
//[Obsolete("Obsolete, This class will eventually be phased out - Use Umbraco.Core.Models.Template", false)]
|
|
public class Template : CMSNode
|
|
{
|
|
|
|
#region Private members
|
|
|
|
private string _OutputContentType;
|
|
private string _design;
|
|
private string _alias;
|
|
private string _oldAlias;
|
|
private int _mastertemplate;
|
|
private bool _hasChildrenInitialized = false;
|
|
private bool _hasChildren;
|
|
|
|
#endregion
|
|
|
|
#region Static members
|
|
|
|
public static readonly string UmbracoMasterTemplate = SystemDirectories.Umbraco + "/masterpages/default.master";
|
|
private static Hashtable _templateAliases = new Hashtable();
|
|
private static volatile bool _templateAliasesInitialized = false;
|
|
private static object templateCacheSyncLock = new object();
|
|
private static readonly string UmbracoTemplateCacheKey = "UmbracoTemplateCache";
|
|
private static object _templateLoaderLocker = new object();
|
|
private static Guid _objectType = new Guid("6fbde604-4178-42ce-a10b-8a2600a2f07d");
|
|
private static readonly char[] NewLineChars = Environment.NewLine.ToCharArray();
|
|
|
|
#endregion
|
|
|
|
[Obsolete("Use TemplateFilePath instead")]
|
|
public string MasterPageFile
|
|
{
|
|
get { return TemplateFilePath; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the file path for the current template
|
|
/// </summary>
|
|
public string TemplateFilePath
|
|
{
|
|
get
|
|
{
|
|
switch (DetermineRenderingEngine(this))
|
|
{
|
|
case RenderingEngine.Mvc:
|
|
return ViewHelper.GetFilePath(this);
|
|
case RenderingEngine.WebForms:
|
|
return MasterPageHelper.GetFilePath(this);
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Hashtable TemplateAliases
|
|
{
|
|
get { return _templateAliases; }
|
|
set { _templateAliases = value; }
|
|
}
|
|
|
|
#region Constructors
|
|
public Template(int id) : base(id) { }
|
|
|
|
public Template(Guid id) : base(id) { }
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility
|
|
/// </summary>
|
|
public override void Save()
|
|
{
|
|
SaveEventArgs e = new SaveEventArgs();
|
|
FireBeforeSave(e);
|
|
|
|
if (!e.Cancel)
|
|
{
|
|
FlushCache();
|
|
base.Save();
|
|
FireAfterSave(e);
|
|
}
|
|
}
|
|
|
|
public string GetRawText()
|
|
{
|
|
return base.Text;
|
|
}
|
|
|
|
public override string Text
|
|
{
|
|
get
|
|
{
|
|
string tempText = base.Text;
|
|
if (!tempText.StartsWith("#"))
|
|
return tempText;
|
|
else
|
|
{
|
|
language.Language lang = language.Language.GetByCultureCode(System.Threading.Thread.CurrentThread.CurrentCulture.Name);
|
|
if (lang != null)
|
|
{
|
|
if (Dictionary.DictionaryItem.hasKey(tempText.Substring(1, tempText.Length - 1)))
|
|
{
|
|
Dictionary.DictionaryItem di = new Dictionary.DictionaryItem(tempText.Substring(1, tempText.Length - 1));
|
|
if (di != null)
|
|
return di.Value(lang.id);
|
|
}
|
|
}
|
|
|
|
return "[" + tempText + "]";
|
|
}
|
|
}
|
|
set
|
|
{
|
|
FlushCache();
|
|
base.Text = value;
|
|
}
|
|
}
|
|
|
|
public string OutputContentType
|
|
{
|
|
get { return _OutputContentType; }
|
|
set { _OutputContentType = value; }
|
|
}
|
|
|
|
protected override void setupNode()
|
|
{
|
|
base.setupNode();
|
|
|
|
IRecordsReader dr = SqlHelper.ExecuteReader("Select alias,design,master from cmsTemplate where nodeId = " + this.Id);
|
|
bool hasRows = dr.Read();
|
|
if (hasRows)
|
|
{
|
|
_alias = dr.GetString("alias");
|
|
_design = dr.GetString("design");
|
|
//set the master template to zero if it's null
|
|
_mastertemplate = dr.IsNull("master") ? 0 : dr.GetInt("master");
|
|
}
|
|
dr.Close();
|
|
|
|
if (Umbraco.Core.Configuration.UmbracoSettings.DefaultRenderingEngine == RenderingEngine.Mvc && ViewHelper.ViewExists(this))
|
|
_design = ViewHelper.GetFileContents(this);
|
|
else
|
|
_design = MasterPageHelper.GetFileContents(this);
|
|
|
|
}
|
|
|
|
public new string Path
|
|
{
|
|
get
|
|
{
|
|
List<int> path = new List<int>();
|
|
Template working = this;
|
|
while (working != null)
|
|
{
|
|
path.Add(working.Id);
|
|
try
|
|
{
|
|
if (working.MasterTemplate != 0)
|
|
{
|
|
working = new Template(working.MasterTemplate);
|
|
}
|
|
else
|
|
{
|
|
working = null;
|
|
}
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
working = null;
|
|
}
|
|
}
|
|
path.Add(-1);
|
|
path.Reverse();
|
|
string sPath = string.Join(",", path.ConvertAll(item => item.ToString()).ToArray());
|
|
return sPath;
|
|
}
|
|
set
|
|
{
|
|
base.Path = value;
|
|
}
|
|
}
|
|
|
|
public string Alias
|
|
{
|
|
get { return _alias; }
|
|
set
|
|
{
|
|
FlushCache();
|
|
_oldAlias = _alias;
|
|
_alias = value;
|
|
|
|
SqlHelper.ExecuteNonQuery("Update cmsTemplate set alias = @alias where NodeId = " + this.Id, SqlHelper.CreateParameter("@alias", _alias));
|
|
_templateAliasesInitialized = false;
|
|
|
|
initTemplateAliases();
|
|
}
|
|
|
|
}
|
|
|
|
public bool HasMasterTemplate
|
|
{
|
|
get { return (_mastertemplate > 0); }
|
|
}
|
|
|
|
|
|
public override bool HasChildren
|
|
{
|
|
get
|
|
{
|
|
if (!_hasChildrenInitialized)
|
|
{
|
|
_hasChildren = SqlHelper.ExecuteScalar<int>("select count(NodeId) as tmp from cmsTemplate where master = " + Id) > 0;
|
|
}
|
|
return _hasChildren;
|
|
}
|
|
set
|
|
{
|
|
_hasChildrenInitialized = true;
|
|
_hasChildren = value;
|
|
}
|
|
}
|
|
|
|
public int MasterTemplate
|
|
{
|
|
get { return _mastertemplate; }
|
|
set
|
|
{
|
|
FlushCache();
|
|
_mastertemplate = value;
|
|
|
|
//set to null if it's zero
|
|
object masterVal = value;
|
|
if (value == 0) masterVal = DBNull.Value;
|
|
|
|
SqlHelper.ExecuteNonQuery("Update cmsTemplate set master = @master where NodeId = @nodeId",
|
|
SqlHelper.CreateParameter("@master", masterVal),
|
|
SqlHelper.CreateParameter("@nodeId", this.Id));
|
|
}
|
|
}
|
|
|
|
public string Design
|
|
{
|
|
get { return _design; }
|
|
set
|
|
{
|
|
FlushCache();
|
|
|
|
_design = value.Trim(NewLineChars);
|
|
|
|
//we only switch to MVC View editing if the template has a view file, and MVC editing is enabled
|
|
if (Umbraco.Core.Configuration.UmbracoSettings.DefaultRenderingEngine == RenderingEngine.Mvc && !MasterPageHelper.IsMasterPageSyntax(_design))
|
|
{
|
|
MasterPageHelper.RemoveMasterPageFile(this.Alias);
|
|
MasterPageHelper.RemoveMasterPageFile(_oldAlias);
|
|
_design = ViewHelper.UpdateViewFile(this, _oldAlias);
|
|
}
|
|
else if (UmbracoSettings.UseAspNetMasterPages)
|
|
{
|
|
ViewHelper.RemoveViewFile(this.Alias);
|
|
ViewHelper.RemoveViewFile(_oldAlias);
|
|
_design = MasterPageHelper.UpdateMasterPageFile(this, _oldAlias);
|
|
}
|
|
|
|
|
|
SqlHelper.ExecuteNonQuery("Update cmsTemplate set design = @design where NodeId = @id",
|
|
SqlHelper.CreateParameter("@design", _design),
|
|
SqlHelper.CreateParameter("@id", Id));
|
|
}
|
|
}
|
|
|
|
public XmlNode ToXml(XmlDocument doc)
|
|
{
|
|
XmlNode template = doc.CreateElement("Template");
|
|
template.AppendChild(xmlHelper.addTextNode(doc, "Name", this.Text));
|
|
template.AppendChild(xmlHelper.addTextNode(doc, "Alias", this.Alias));
|
|
|
|
if (this.MasterTemplate != 0)
|
|
{
|
|
template.AppendChild(xmlHelper.addTextNode(doc, "Master", new Template(this.MasterTemplate).Alias));
|
|
}
|
|
|
|
template.AppendChild(xmlHelper.addCDataNode(doc, "Design", this.Design));
|
|
|
|
return template;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes any references to this templates from child templates, documenttypes and documents
|
|
/// </summary>
|
|
public void RemoveAllReferences()
|
|
{
|
|
if (HasChildren)
|
|
{
|
|
foreach (Template t in Template.GetAllAsList().FindAll(delegate(Template t) { return t.MasterTemplate == this.Id; }))
|
|
{
|
|
t.MasterTemplate = 0;
|
|
}
|
|
}
|
|
|
|
RemoveFromDocumentTypes();
|
|
|
|
// remove from documents
|
|
Document.RemoveTemplateFromDocument(this.Id);
|
|
}
|
|
|
|
public void RemoveFromDocumentTypes()
|
|
{
|
|
foreach (DocumentType dt in DocumentType.GetAllAsList().Where(x => x.allowedTemplates.Select(t => t.Id).Contains(this.Id)))
|
|
{
|
|
dt.RemoveTemplate(this.Id);
|
|
dt.Save();
|
|
}
|
|
}
|
|
|
|
public IEnumerable<DocumentType> GetDocumentTypes()
|
|
{
|
|
return DocumentType.GetAllAsList().Where(x => x.allowedTemplates.Select(t => t.Id).Contains(this.Id));
|
|
}
|
|
|
|
/// <summary>
|
|
/// This checks what the default rendering engine is set in config but then also ensures that there isn't already
|
|
/// a template that exists in the opposite rendering engine's template folder, then returns the appropriate
|
|
/// rendering engine to use.
|
|
/// </summary>
|
|
/// <param name="t"></param>
|
|
/// <param name="design">If a template body is specified we'll check if it contains master page markup, if it does we'll auto assume its webforms </param>
|
|
/// <returns></returns>
|
|
/// <remarks>
|
|
/// The reason this is required is because for example, if you have a master page file already existing under ~/masterpages/Blah.aspx
|
|
/// and then you go to create a template in the tree called Blah and the default rendering engine is MVC, it will create a Blah.cshtml
|
|
/// empty template in ~/Views. This means every page that is using Blah will go to MVC and render an empty page.
|
|
/// This is mostly related to installing packages since packages install file templates to the file system and then create the
|
|
/// templates in business logic. Without this, it could cause the wrong rendering engine to be used for a package.
|
|
/// </remarks>
|
|
private static RenderingEngine DetermineRenderingEngine(Template t, string design = null)
|
|
{
|
|
var engine = Umbraco.Core.Configuration.UmbracoSettings.DefaultRenderingEngine;
|
|
|
|
if (!design.IsNullOrWhiteSpace() && MasterPageHelper.IsMasterPageSyntax(design))
|
|
{
|
|
//there is a design but its definitely a webforms design
|
|
return RenderingEngine.WebForms;
|
|
}
|
|
|
|
switch (engine)
|
|
{
|
|
case RenderingEngine.Mvc:
|
|
//check if there's a view in ~/masterpages
|
|
if (MasterPageHelper.MasterPageExists(t) && !ViewHelper.ViewExists(t))
|
|
{
|
|
//change this to webforms since there's already a file there for this template alias
|
|
engine = RenderingEngine.WebForms;
|
|
}
|
|
break;
|
|
case RenderingEngine.WebForms:
|
|
//check if there's a view in ~/views
|
|
if (ViewHelper.ViewExists(t) && !MasterPageHelper.MasterPageExists(t))
|
|
{
|
|
//change this to mvc since there's already a file there for this template alias
|
|
engine = RenderingEngine.Mvc;
|
|
}
|
|
break;
|
|
}
|
|
return engine;
|
|
}
|
|
|
|
public static Template MakeNew(string Name, BusinessLogic.User u, Template master)
|
|
{
|
|
return MakeNew(Name, u, master, null);
|
|
}
|
|
|
|
private static Template MakeNew(string name, BusinessLogic.User u, string design)
|
|
{
|
|
return MakeNew(name, u, null, design);
|
|
}
|
|
|
|
public static Template MakeNew(string name, BusinessLogic.User u)
|
|
{
|
|
return MakeNew(name, u, design: null);
|
|
}
|
|
|
|
private static Template MakeNew(string name, BusinessLogic.User u, Template master, string design)
|
|
{
|
|
|
|
// CMSNode MakeNew(int parentId, Guid objectType, int userId, int level, string text, Guid uniqueID)
|
|
CMSNode n = CMSNode.MakeNew(-1, _objectType, u.Id, 1, name, Guid.NewGuid());
|
|
|
|
//ensure unique alias
|
|
name = helpers.Casing.SafeAlias(name);
|
|
if (GetByAlias(name) != null)
|
|
name = EnsureUniqueAlias(name, 1);
|
|
name = name.Replace("/", ".").Replace("\\", "");
|
|
|
|
if (name.Length > 100)
|
|
name = name.Substring(0, 95) + "...";
|
|
|
|
|
|
SqlHelper.ExecuteNonQuery("INSERT INTO cmsTemplate (NodeId, Alias, design, master) VALUES (@nodeId, @alias, @design, @master)",
|
|
SqlHelper.CreateParameter("@nodeId", n.Id),
|
|
SqlHelper.CreateParameter("@alias", name),
|
|
SqlHelper.CreateParameter("@design", ' '),
|
|
SqlHelper.CreateParameter("@master", DBNull.Value));
|
|
|
|
Template t = new Template(n.Id);
|
|
NewEventArgs e = new NewEventArgs();
|
|
t.OnNew(e);
|
|
|
|
if (master != null)
|
|
t.MasterTemplate = master.Id;
|
|
|
|
switch (DetermineRenderingEngine(t, design))
|
|
{
|
|
case RenderingEngine.Mvc:
|
|
ViewHelper.CreateViewFile(t, true);
|
|
break;
|
|
case RenderingEngine.WebForms:
|
|
MasterPageHelper.CreateMasterPage(t, true);
|
|
break;
|
|
}
|
|
|
|
//if a design is supplied ensure it is updated.
|
|
if (!design.IsNullOrWhiteSpace())
|
|
{
|
|
t.ImportDesign(design);
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
private static string EnsureUniqueAlias(string alias, int attempts)
|
|
{
|
|
if (GetByAlias(alias + attempts.ToString()) == null)
|
|
return alias + attempts.ToString();
|
|
else
|
|
{
|
|
attempts++;
|
|
return EnsureUniqueAlias(alias, attempts);
|
|
}
|
|
}
|
|
|
|
public static Template GetByAlias(string Alias)
|
|
{
|
|
return GetByAlias(Alias, false);
|
|
}
|
|
|
|
public static Template GetByAlias(string Alias, bool useCache)
|
|
{
|
|
if (!useCache)
|
|
{
|
|
try
|
|
{
|
|
return new Template(SqlHelper.ExecuteScalar<int>("select nodeId from cmsTemplate where alias = @alias", SqlHelper.CreateParameter("@alias", Alias)));
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
//return from cache instead
|
|
var id = GetTemplateIdFromAlias(Alias);
|
|
return id == 0 ? null : GetTemplate(id);
|
|
}
|
|
|
|
[Obsolete("Obsolete, please use GetAllAsList() method instead", true)]
|
|
public static Template[] getAll()
|
|
{
|
|
return GetAllAsList().ToArray();
|
|
}
|
|
|
|
public static List<Template> GetAllAsList()
|
|
{
|
|
Guid[] ids = CMSNode.TopMostNodeIds(_objectType);
|
|
List<Template> retVal = new List<Template>();
|
|
foreach (Guid id in ids)
|
|
{
|
|
retVal.Add(new Template(id));
|
|
}
|
|
retVal.Sort(delegate(Template t1, Template t2) { return t1.Text.CompareTo(t2.Text); });
|
|
return retVal;
|
|
}
|
|
|
|
public static int GetTemplateIdFromAlias(string alias)
|
|
{
|
|
alias = alias.ToLower();
|
|
|
|
initTemplateAliases();
|
|
if (TemplateAliases.ContainsKey(alias))
|
|
return (int)TemplateAliases[alias];
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
private static void initTemplateAliases()
|
|
{
|
|
if (!_templateAliasesInitialized)
|
|
{
|
|
lock (_templateLoaderLocker)
|
|
{
|
|
//double check
|
|
if (!_templateAliasesInitialized)
|
|
{
|
|
_templateAliases.Clear();
|
|
foreach (Template t in GetAllAsList())
|
|
TemplateAliases.Add(t.Alias.ToLower(), t.Id);
|
|
|
|
_templateAliasesInitialized = true;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void delete()
|
|
{
|
|
// don't allow template deletion if it has child templates
|
|
if (this.HasChildren)
|
|
{
|
|
var ex = new InvalidOperationException("Can't delete a master template. Remove any bindings from child templates first.");
|
|
LogHelper.Error<Template>("Can't delete a master template. Remove any bindings from child templates first.", ex);
|
|
throw ex;
|
|
}
|
|
|
|
// NH: Changed this; if you delete a template we'll remove all references instead of
|
|
// throwing an exception
|
|
if (DocumentType.GetAllAsList().Where(x => x.allowedTemplates.Select(t => t.Id).Contains(this.Id)).Count() > 0)
|
|
RemoveAllReferences();
|
|
|
|
DeleteEventArgs e = new DeleteEventArgs();
|
|
FireBeforeDelete(e);
|
|
|
|
if (!e.Cancel)
|
|
{
|
|
//re-set the template aliases
|
|
_templateAliasesInitialized = false;
|
|
initTemplateAliases();
|
|
|
|
//delete the template
|
|
SqlHelper.ExecuteNonQuery("delete from cmsTemplate where NodeId =" + this.Id);
|
|
|
|
base.delete();
|
|
|
|
// remove masterpages
|
|
if (System.IO.File.Exists(MasterPageFile))
|
|
System.IO.File.Delete(MasterPageFile);
|
|
|
|
if (System.IO.File.Exists(Umbraco.Core.IO.IOHelper.MapPath(ViewHelper.ViewPath(this.Alias))))
|
|
System.IO.File.Delete(Umbraco.Core.IO.IOHelper.MapPath(ViewHelper.ViewPath(this.Alias)));
|
|
|
|
FireAfterDelete(e);
|
|
}
|
|
}
|
|
|
|
[Obsolete("This method, doesnt actually do anything, as the file is created when the design is set", false)]
|
|
public void _SaveAsMasterPage()
|
|
{
|
|
//SaveMasterPageFile(ConvertToMasterPageSyntax(Design));
|
|
}
|
|
|
|
public string GetMasterContentElement(int masterTemplateId)
|
|
{
|
|
if (masterTemplateId != 0)
|
|
{
|
|
string masterAlias = new Template(masterTemplateId).Alias.Replace(" ", "");
|
|
return
|
|
String.Format("<asp:Content ContentPlaceHolderID=\"{1}ContentPlaceHolder\" runat=\"server\">",
|
|
Alias.Replace(" ", ""), masterAlias);
|
|
}
|
|
else
|
|
return
|
|
String.Format("<asp:Content ContentPlaceHolderID=\"ContentPlaceHolderDefault\" runat=\"server\">",
|
|
Alias.Replace(" ", ""));
|
|
}
|
|
|
|
public List<string> contentPlaceholderIds()
|
|
{
|
|
List<string> retVal = new List<string>();
|
|
|
|
string masterPageFile = this.MasterPageFile;
|
|
string mp = System.IO.File.ReadAllText(masterPageFile);
|
|
string pat = "<asp:ContentPlaceHolder+(\\s+[a-zA-Z]+\\s*=\\s*(\"([^\"]*)\"|'([^']*)'))*\\s*/?>";
|
|
Regex r = new Regex(pat, RegexOptions.IgnoreCase);
|
|
Match m = r.Match(mp);
|
|
|
|
while (m.Success)
|
|
{
|
|
CaptureCollection cc = m.Groups[3].Captures;
|
|
foreach (Capture c in cc)
|
|
{
|
|
if (c.Value != "server")
|
|
retVal.Add(c.Value);
|
|
}
|
|
|
|
m = m.NextMatch();
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
|
|
public string ConvertToMasterPageSyntax(string templateDesign)
|
|
{
|
|
string masterPageContent = GetMasterContentElement(MasterTemplate) + Environment.NewLine;
|
|
|
|
masterPageContent += templateDesign;
|
|
|
|
// Parse the design for getitems
|
|
masterPageContent = EnsureMasterPageSyntax(masterPageContent);
|
|
|
|
// append ending asp:content element
|
|
masterPageContent += Environment.NewLine
|
|
+ "</asp:Content>"
|
|
+ Environment.NewLine;
|
|
|
|
return masterPageContent;
|
|
}
|
|
|
|
public string EnsureMasterPageSyntax(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("<?UMBRACO_TEMPLATE_LOAD_CHILD/>", GetAspNetMasterPageContentContainer()).Replace("<?UMBRACO_TEMPLATE_LOAD_CHILD />", GetAspNetMasterPageContentContainer());
|
|
// Parse the design for aspnet forms
|
|
GetAspNetMasterPageForm(ref masterPageContent);
|
|
masterPageContent = masterPageContent.Replace("</?ASPNET_FORM>", "</form>");
|
|
// Parse the design for aspnet heads
|
|
masterPageContent = masterPageContent.Replace("</ASPNET_HEAD>", String.Format("<head id=\"{0}Head\" runat=\"server\">", Alias.Replace(" ", "")));
|
|
masterPageContent = masterPageContent.Replace("</?ASPNET_HEAD>", "</head>");
|
|
return masterPageContent;
|
|
}
|
|
|
|
|
|
|
|
public void ImportDesign(string design)
|
|
{
|
|
Design = design;
|
|
}
|
|
|
|
public void SaveMasterPageFile(string masterPageContent)
|
|
{
|
|
//this will trigger the helper and store everything
|
|
this.Design = masterPageContent;
|
|
}
|
|
|
|
private void GetAspNetMasterPageForm(ref string design)
|
|
{
|
|
Match formElement = Regex.Match(design, GetElementRegExp("?ASPNET_FORM", false), RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
|
if (formElement != null && formElement.Value != "")
|
|
{
|
|
string formReplace = String.Format("<form id=\"{0}Form\" runat=\"server\">", Alias.Replace(" ", ""));
|
|
if (formElement.Groups.Count == 0)
|
|
{
|
|
formReplace += "<asp:scriptmanager runat=\"server\"></asp:scriptmanager>";
|
|
}
|
|
design = design.Replace(formElement.Value, formReplace);
|
|
}
|
|
}
|
|
|
|
private string GetAspNetMasterPageContentContainer()
|
|
{
|
|
return String.Format(
|
|
"<asp:ContentPlaceHolder ID=\"{0}ContentPlaceHolder\" runat=\"server\"></asp:ContentPlaceHolder>",
|
|
Alias.Replace(" ", ""));
|
|
}
|
|
|
|
private 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("</"))
|
|
// It's a closing element, so generate that instead of a starting element
|
|
newElement = "</" + newElementName + ">";
|
|
|
|
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 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);
|
|
|
|
}
|
|
|
|
|
|
protected virtual void FlushCache()
|
|
{
|
|
// clear local cache
|
|
cache.Cache.ClearCacheItem(GetCacheKey(Id));
|
|
}
|
|
|
|
public static Template GetTemplate(int id)
|
|
{
|
|
return Cache.GetCacheItem<Template>(GetCacheKey(id), templateCacheSyncLock,
|
|
TimeSpan.FromMinutes(30),
|
|
delegate
|
|
{
|
|
try
|
|
{
|
|
return new Template(id);
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
private static string GetCacheKey(int id)
|
|
{
|
|
return UmbracoTemplateCacheKey + id;
|
|
}
|
|
|
|
public static Template Import(XmlNode n, User u)
|
|
{
|
|
string alias = xmlHelper.GetNodeValue(n.SelectSingleNode("Alias"));
|
|
|
|
Template t = Template.GetByAlias(alias);
|
|
var design = xmlHelper.GetNodeValue(n.SelectSingleNode("Design"));
|
|
|
|
if (t == null)
|
|
{
|
|
//create the template with the design if one is specified
|
|
t = MakeNew(xmlHelper.GetNodeValue(n.SelectSingleNode("Name")), u,
|
|
design.IsNullOrWhiteSpace() ? null : design);
|
|
}
|
|
|
|
t.Alias = alias;
|
|
|
|
return t;
|
|
}
|
|
|
|
|
|
#region Events
|
|
//EVENTS
|
|
/// <summary>
|
|
/// The save event handler
|
|
/// </summary>
|
|
public delegate void SaveEventHandler(Template sender, SaveEventArgs e);
|
|
/// <summary>
|
|
/// The new event handler
|
|
/// </summary>
|
|
public delegate void NewEventHandler(Template sender, NewEventArgs e);
|
|
/// <summary>
|
|
/// The delete event handler
|
|
/// </summary>
|
|
public delegate void DeleteEventHandler(Template sender, DeleteEventArgs e);
|
|
|
|
|
|
/// <summary>
|
|
/// Occurs when [before save].
|
|
/// </summary>
|
|
public static event SaveEventHandler BeforeSave;
|
|
/// <summary>
|
|
/// Raises the <see cref="E:BeforeSave"/> event.
|
|
/// </summary>
|
|
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
|
protected virtual void FireBeforeSave(SaveEventArgs e)
|
|
{
|
|
if (BeforeSave != null)
|
|
BeforeSave(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Occurs when [after save].
|
|
/// </summary>
|
|
public static event SaveEventHandler AfterSave;
|
|
/// <summary>
|
|
/// Raises the <see cref="E:AfterSave"/> event.
|
|
/// </summary>
|
|
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
|
protected virtual void FireAfterSave(SaveEventArgs e)
|
|
{
|
|
if (AfterSave != null)
|
|
AfterSave(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Occurs when [new].
|
|
/// </summary>
|
|
public static event NewEventHandler New;
|
|
/// <summary>
|
|
/// Raises the <see cref="E:New"/> event.
|
|
/// </summary>
|
|
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
|
protected virtual void OnNew(NewEventArgs e)
|
|
{
|
|
if (New != null)
|
|
New(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Occurs when [before delete].
|
|
/// </summary>
|
|
public static event DeleteEventHandler BeforeDelete;
|
|
/// <summary>
|
|
/// Raises the <see cref="E:BeforeDelete"/> event.
|
|
/// </summary>
|
|
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
|
protected virtual void FireBeforeDelete(DeleteEventArgs e)
|
|
{
|
|
if (BeforeDelete != null)
|
|
BeforeDelete(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Occurs when [after delete].
|
|
/// </summary>
|
|
public static event DeleteEventHandler AfterDelete;
|
|
/// <summary>
|
|
/// Raises the <see cref="E:AfterDelete"/> event.
|
|
/// </summary>
|
|
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
|
protected virtual void FireAfterDelete(DeleteEventArgs e)
|
|
{
|
|
if (AfterDelete != null)
|
|
AfterDelete(this, e);
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|