diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js new file mode 100644 index 0000000000..c90bb1766d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js @@ -0,0 +1,172 @@ +/** + * @ngdoc service + * @name umbraco.resources.templateResource + * @description Loads in data for templates + **/ +function templateResource($q, $http, umbDataFormatter, umbRequestHelper) { + + return { + + /** + * @ngdoc method + * @name umbraco.resources.templateResource#getById + * @methodOf umbraco.resources.templateResource + * + * @description + * Gets a template item with a given id + * + * ##usage + *
+         * templateResource.getById(1234)
+         *    .then(function(template) {
+         *        alert('its here!');
+         *    });
+         * 
+ * + * @param {Int} id id of template to retrieve + * @returns {Promise} resourcePromise object. + * + */ + getById: function (id) { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "templateApiBaseUrl", + "GetById", + [{ id: id }])), + "Failed to retrieve data for template id " + id); + }, + + /** + * @ngdoc method + * @name umbraco.resources.templateResource#getByName + * @methodOf umbraco.resources.templateResource + * + * @description + * Gets a template item with a given name + * + * ##usage + *
+         * templateResource.getByName("upload")
+         *    .then(function(datatype) {
+         *        alert('its here!');
+         *    });
+         * 
+ * + * @param {String} name Name of template to retrieve + * @returns {Promise} resourcePromise object. + * + */ + getByAlias: function (alias) { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "templateApiBaseUrl", + "GetByAlias", + [{ alias: alias }])), + "Failed to retrieve data for template with alias: " + alias); + }, + + getAll: function () { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "templateApiBaseUrl", + "GetAll")), + "Failed to retrieve data"); + }, + + + /** + * @ngdoc method + * @name umbraco.resources.contentResource#getScaffold + * @methodOf umbraco.resources.contentResource + * + * @description + * Returns a scaffold of an empty template item + * + * The scaffold is used to build editors for templates that has not yet been populated with data. + * + * ##usage + *
+         * templateResource.getScaffold()
+         *    .then(function(scaffold) {
+         *        var myType = scaffold;
+         *        myType.name = "My new template";
+         *
+         *        templateResource.save(myType, myType.preValues, true)
+         *            .then(function(type){
+         *                alert("Retrieved, updated and saved again");
+         *            });
+         *    });
+         * 
+ * + * @returns {Promise} resourcePromise object containing the template scaffold. + * + */ + getScaffold: function () { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "templateApiBaseUrl", + "GetEmpty")), + "Failed to retrieve data for empty template"); + }, + + /** + * @ngdoc method + * @name umbraco.resources.templateResource#deleteById + * @methodOf umbraco.resources.templateResource + * + * @description + * Deletes a template with a given id + * + * ##usage + *
+         * templateResource.deleteById(1234)
+         *    .then(function() {
+         *        alert('its gone!');
+         *    });
+         * 
+ * + * @param {Int} id id of content item to delete + * @returns {Promise} resourcePromise object. + * + */ + deleteById: function(id) { + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "templateApiBaseUrl", + "DeleteById", + [{ id: id }])), + "Failed to delete item " + id); + }, + + + /** + * @ngdoc method + * @name umbraco.resources.templateResource#save + * @methodOf umbraco.resources.templateResource + * + * @description + * Saves or update a template + * + * @param {Object} template object to create/update + * @returns {Promise} resourcePromise object. + * + */ + save: function (template) { + + return umbRequestHelper.resourcePromise( + $http.post(umbRequestHelper.getApiUrl("templateApiBaseUrl", "PostSave"), template), + "Failed to save data for template id " + template.id); + } + }; +} + +angular.module("umbraco.resources").factory("templateResource", templateResource); diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 95e1f7803e..968a047fba 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -327,6 +327,10 @@ namespace Umbraco.Web.Editors "tagApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetAllTags(null)) }, + { + "templateApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( + controller => controller.GetById(0)) + }, { "memberTreeBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetNodes("-1", null)) diff --git a/src/Umbraco.Web/Editors/TemplateController.cs b/src/Umbraco.Web/Editors/TemplateController.cs new file mode 100644 index 0000000000..27b7c67e11 --- /dev/null +++ b/src/Umbraco.Web/Editors/TemplateController.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Web.Http; +using AutoMapper; +using Umbraco.Core.Models; +using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.Mvc; +using Umbraco.Web.WebApi.Filters; +using Constants = Umbraco.Core.Constants; + +namespace Umbraco.Web.Editors +{ + [PluginController("UmbracoApi")] + [UmbracoTreeAuthorize(Constants.Trees.Templates)] + public class TemplateController : UmbracoAuthorizedJsonController + { + /// + /// Gets data type by alias + /// + /// + /// + public TemplateDisplay GetByAlias(string alias) + { + var template = Services.FileService.GetTemplate(alias); + return template == null ? null : Mapper.Map(template); + } + + /// + /// Get all templates + /// + /// + public IEnumerable GetAll() + { + return Services.FileService.GetTemplates().Select(Mapper.Map); + } + + /// + /// Gets the content json for the content id + /// + /// + /// + public TemplateDisplay GetById(int id) + { + var template = Services.FileService.GetTemplate(id); + + if (template == null) + { + throw new HttpResponseException(HttpStatusCode.NotFound); + } + return Mapper.Map(template); + } + + /// + /// Deletes a template wth a given ID + /// + /// + /// + [HttpDelete] + [HttpPost] + public HttpResponseMessage DeleteById(int id) + { + var template = Services.FileService.GetTemplate(id); + if (template == null) + { + throw new HttpResponseException(HttpStatusCode.NotFound); + } + + Services.FileService.DeleteTemplate(template.Alias); + return Request.CreateResponse(HttpStatusCode.OK); + } + + public TemplateDisplay GetEmpty() + { + var dt = new Template("", ""); + return Mapper.Map((ITemplate)dt); + } + + /// + /// Saves the data type + /// + /// + /// + public TemplateDisplay PostSave(TemplateDisplay display) + { + if(display.Id > 0) + { + var template = Services.FileService.GetTemplate(display.Id); + Mapper.Map(display, template); + Services.FileService.SaveTemplate(template); + return display; + } + else + { + //create + ITemplate master = null; + if (string.IsNullOrEmpty(display.MasterTemplateAlias) == false) + master = Services.FileService.GetTemplate(display.MasterTemplateAlias); + + var template = Services.FileService.CreateTemplateWithIdentity(display.Name, display.Content, master); + Mapper.Map(template, display); + return display; + } + } + } +} diff --git a/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs new file mode 100644 index 0000000000..dacccb8ceb --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace Umbraco.Web.Models.ContentEditing +{ + [DataContract(Name = "template", Namespace = "")] + public class TemplateDisplay + { + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(Name = "name")] + public string Name { get; set; } + + [DataMember(Name = "alias")] + public string Alias { get; set; } + + [DataMember(Name = "content")] + public string Content { get; set; } + + [DataMember(Name = "path")] + public string Path { get; set; } + + [DataMember(Name = "virtualPath")] + public string VirtualPath { get; set; } + + [DataMember(Name = "masterTemplateAlias")] + public string MasterTemplateAlias { get; set; } + } +} diff --git a/src/Umbraco.Web/Models/Mapping/TemplateModelMapping.cs b/src/Umbraco.Web/Models/Mapping/TemplateModelMapping.cs new file mode 100644 index 0000000000..c4f96b7def --- /dev/null +++ b/src/Umbraco.Web/Models/Mapping/TemplateModelMapping.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AutoMapper; +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Core.Models.Mapping; +using Umbraco.Web.Models.ContentEditing; + +namespace Umbraco.Web.Models.Mapping +{ + internal class TemplateModelMapper : MapperConfiguration + { + public override void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext) + { + config.CreateMap(); + + config.CreateMap() + .ForMember(x => x.Key, exp => exp.Ignore()) + .ForMember(x => x.Path, exp => exp.Ignore()) + .ForMember(x => x.CreateDate, exp => exp.Ignore()) + .ForMember(x => x.UpdateDate, exp => exp.Ignore()) + .ForMember(x => x.VirtualPath, exp => exp.Ignore()) + .ForMember(x => x.Path, exp => exp.Ignore()); + } + } +}