packages partial views associated with macros.
This commit is contained in:
@@ -14,6 +14,7 @@ namespace Umbraco.Cms.Core.Models.Packaging
|
||||
public string Name { get; set; }
|
||||
public InstallWarnings Warnings { get; set; } = new InstallWarnings();
|
||||
public IEnumerable<XElement> Macros { get; set; } // TODO: make strongly typed
|
||||
public IEnumerable<XElement> MacroPartialViews { get; set; } // TODO: make strongly typed
|
||||
public IEnumerable<XElement> Templates { get; set; } // TODO: make strongly typed
|
||||
public IEnumerable<XElement> Stylesheets { get; set; } // TODO: make strongly typed
|
||||
public IEnumerable<XElement> DataTypes { get; set; } // TODO: make strongly typed
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace Umbraco.Cms.Core.Packaging
|
||||
PackageFile = null,
|
||||
Name = package.Element("name")?.Value,
|
||||
Macros = xml.Root.Element("Macros")?.Elements("macro") ?? Enumerable.Empty<XElement>(),
|
||||
MacroPartialViews = xml.Root.Element("MacroPartialViews")?.Elements("view") ?? Enumerable.Empty<XElement>(),
|
||||
Templates = xml.Root.Element("Templates")?.Elements("Template") ?? Enumerable.Empty<XElement>(),
|
||||
Stylesheets = xml.Root.Element("Stylesheets")?.Elements("styleSheet") ?? Enumerable.Empty<XElement>(),
|
||||
DataTypes = xml.Root.Element("DataTypes")?.Elements("DataType") ?? Enumerable.Empty<XElement>(),
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -372,18 +373,30 @@ namespace Umbraco.Cms.Core.Packaging
|
||||
|
||||
private void PackageMacros(PackageDefinition definition, XContainer root)
|
||||
{
|
||||
var packagedMacros = new List<IMacro>();
|
||||
var macros = new XElement("Macros");
|
||||
foreach (var macroId in definition.Macros)
|
||||
{
|
||||
if (!int.TryParse(macroId, out var outInt))
|
||||
if (!int.TryParse(macroId, out int outInt))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var macroXml = GetMacroXml(outInt, out var macro);
|
||||
XElement macroXml = GetMacroXml(outInt, out IMacro macro);
|
||||
if (macroXml == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
macros.Add(macroXml);
|
||||
packagedMacros.Add(macro);
|
||||
}
|
||||
|
||||
root.Add(macros);
|
||||
|
||||
// get the partial views for macros and package those
|
||||
IEnumerable<string> views = packagedMacros.Select(x => x.MacroSource).Where(x => x.EndsWith(".cshtml"));
|
||||
PackagePartialViews(views, root, "MacroPartialViews");
|
||||
}
|
||||
|
||||
private void PackageStylesheets(PackageDefinition definition, XContainer root)
|
||||
@@ -415,6 +428,33 @@ namespace Umbraco.Cms.Core.Packaging
|
||||
root.Add(templatesXml);
|
||||
}
|
||||
|
||||
private void PackagePartialViews(IEnumerable<string> viewPaths, XContainer root, string elementName)
|
||||
{
|
||||
var viewsXml = new XElement(elementName);
|
||||
foreach (var viewPath in viewPaths)
|
||||
{
|
||||
// TODO: See TODO note in MacrosController about the inconsistencies of usages of partial views
|
||||
// and how paths are saved. We have no choice currently but to assume that all views are 100% always
|
||||
// on the content path.
|
||||
|
||||
var physicalPath = _hostingEnvironment.MapPathContentRoot(viewPath);
|
||||
if (!File.Exists(physicalPath))
|
||||
{
|
||||
throw new InvalidOperationException("Could not find partial view at path " + viewPath);
|
||||
}
|
||||
|
||||
var fileContents = File.ReadAllText(physicalPath, Encoding.UTF8);
|
||||
|
||||
viewsXml.Add(
|
||||
new XElement(
|
||||
"view",
|
||||
new XAttribute("path", viewPath),
|
||||
new XCData(fileContents)));
|
||||
}
|
||||
|
||||
root.Add(viewsXml);
|
||||
}
|
||||
|
||||
private void PackageDocumentTypes(PackageDefinition definition, XContainer root)
|
||||
{
|
||||
var contentTypes = new HashSet<IContentType>();
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -39,6 +40,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
private readonly IConfigurationEditorJsonSerializer _serializer;
|
||||
private readonly IMediaService _mediaService;
|
||||
private readonly IMediaTypeService _mediaTypeService;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly IContentTypeService _contentTypeService;
|
||||
private readonly IContentService _contentService;
|
||||
@@ -59,7 +61,8 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
IOptions<GlobalSettings> globalSettings,
|
||||
IConfigurationEditorJsonSerializer serializer,
|
||||
IMediaService mediaService,
|
||||
IMediaTypeService mediaTypeService)
|
||||
IMediaTypeService mediaTypeService,
|
||||
IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
_dataValueEditorFactory = dataValueEditorFactory;
|
||||
_logger = logger;
|
||||
@@ -74,6 +77,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
_serializer = serializer;
|
||||
_mediaService = mediaService;
|
||||
_mediaTypeService = mediaTypeService;
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
_entityService = entityService;
|
||||
_contentTypeService = contentTypeService;
|
||||
_contentService = contentService;
|
||||
@@ -91,7 +95,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
DataTypesInstalled = ImportDataTypes(compiledPackage.DataTypes.ToList(), userId),
|
||||
LanguagesInstalled = ImportLanguages(compiledPackage.Languages, userId),
|
||||
DictionaryItemsInstalled = ImportDictionaryItems(compiledPackage.DictionaryItems, userId),
|
||||
MacrosInstalled = ImportMacros(compiledPackage.Macros, userId),
|
||||
MacrosInstalled = ImportMacros(compiledPackage.Macros, compiledPackage.MacroPartialViews, userId),
|
||||
TemplatesInstalled = ImportTemplates(compiledPackage.Templates.ToList(), userId),
|
||||
DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId),
|
||||
MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId),
|
||||
@@ -1235,6 +1239,30 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
|
||||
#endregion
|
||||
|
||||
private void ImportPartialViews(IEnumerable<XElement> viewElements)
|
||||
{
|
||||
foreach(XElement element in viewElements)
|
||||
{
|
||||
var path = element.AttributeValue<string>("path");
|
||||
if (path == null)
|
||||
{
|
||||
throw new InvalidOperationException("No path attribute found");
|
||||
}
|
||||
var contents = element.Value;
|
||||
if (contents.IsNullOrWhiteSpace())
|
||||
{
|
||||
throw new InvalidOperationException("No content found for partial view");
|
||||
}
|
||||
|
||||
var physicalPath = _hostingEnvironment.MapPathContentRoot(path);
|
||||
// TODO: Do we overwrite? IMO I don't think so since these will be views a user will change.
|
||||
if (!System.IO.File.Exists(physicalPath))
|
||||
{
|
||||
System.IO.File.WriteAllText(physicalPath, contents, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Macros
|
||||
|
||||
/// <summary>
|
||||
@@ -1243,15 +1271,20 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
/// <param name="macroElements">Xml to import</param>
|
||||
/// <param name="userId">Optional id of the User performing the operation</param>
|
||||
/// <returns></returns>
|
||||
public IReadOnlyList<IMacro> ImportMacros(IEnumerable<XElement> macroElements, int userId)
|
||||
public IReadOnlyList<IMacro> ImportMacros(
|
||||
IEnumerable<XElement> macroElements,
|
||||
IEnumerable<XElement> macroPartialViewsElements,
|
||||
int userId)
|
||||
{
|
||||
var macros = macroElements.Select(ParseMacroElement).ToList();
|
||||
|
||||
foreach (var macro in macros)
|
||||
foreach (IMacro macro in macros)
|
||||
{
|
||||
_macroService.Save(macro, userId);
|
||||
}
|
||||
|
||||
ImportPartialViews(macroPartialViewsElements);
|
||||
|
||||
return macros;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
ILogger<MacrosController> logger,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IUmbracoMapper umbracoMapper
|
||||
)
|
||||
IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_parameterEditorCollection = parameterEditorCollection ?? throw new ArgumentNullException(nameof(parameterEditorCollection));
|
||||
_macroService = macroService ?? throw new ArgumentNullException(nameof(macroService));
|
||||
@@ -315,6 +314,12 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
/// </returns>
|
||||
private IEnumerable<string> FindPartialViewFilesInViewsFolder()
|
||||
{
|
||||
// TODO: This is inconsistent. We have FileSystems.MacroPartialsFileSystem but we basically don't use
|
||||
// that at all except to render the tree. In the future we may want to use it. This also means that
|
||||
// we are storing the virtual path of the macro like ~/Views/MacroPartials/Login.cshtml instead of the
|
||||
// relative path which would work with the FileSystems.MacroPartialsFileSystem, but these are incompatible.
|
||||
// At some point this should all be made consistent and probably just use FileSystems.MacroPartialsFileSystem.
|
||||
|
||||
var partialsDir = _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.MacroPartials);
|
||||
|
||||
return this.FindPartialViewFilesInFolder(
|
||||
|
||||
Reference in New Issue
Block a user