mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-20 02:37:55 +08:00
Refactored ImportExport to support extensible, configurable export steps.
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Orchard.Commands;
|
using Orchard.Commands;
|
||||||
using Orchard.ContentManagement.MetaData;
|
using Orchard.ContentManagement.MetaData;
|
||||||
using Orchard.ImportExport.Models;
|
using Orchard.ImportExport.Models;
|
||||||
|
using Orchard.ImportExport.Providers;
|
||||||
using Orchard.ImportExport.Services;
|
using Orchard.ImportExport.Services;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
using Orchard.Settings;
|
using Orchard.Settings;
|
||||||
@@ -15,18 +17,22 @@ namespace Orchard.ImportExport.Commands {
|
|||||||
private readonly ISiteService _siteService;
|
private readonly ISiteService _siteService;
|
||||||
private readonly IMembershipService _membershipService;
|
private readonly IMembershipService _membershipService;
|
||||||
private readonly IAuthenticationService _authenticationService;
|
private readonly IAuthenticationService _authenticationService;
|
||||||
|
private readonly IOrchardServices _orchardServices;
|
||||||
|
|
||||||
public ImportExportCommands(
|
public ImportExportCommands(
|
||||||
IImportExportService importExportService,
|
IImportExportService importExportService,
|
||||||
IContentDefinitionManager contentDefinitionManager,
|
IContentDefinitionManager contentDefinitionManager,
|
||||||
ISiteService siteService,
|
ISiteService siteService,
|
||||||
IMembershipService membershipService,
|
IMembershipService membershipService,
|
||||||
IAuthenticationService authenticationService) {
|
IAuthenticationService authenticationService,
|
||||||
|
IOrchardServices orchardServices) {
|
||||||
|
|
||||||
_importExportService = importExportService;
|
_importExportService = importExportService;
|
||||||
_contentDefinitionManager = contentDefinitionManager;
|
_contentDefinitionManager = contentDefinitionManager;
|
||||||
_siteService = siteService;
|
_siteService = siteService;
|
||||||
_membershipService = membershipService;
|
_membershipService = membershipService;
|
||||||
_authenticationService = authenticationService;
|
_authenticationService = authenticationService;
|
||||||
|
_orchardServices = orchardServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
[OrchardSwitch]
|
[OrchardSwitch]
|
||||||
@@ -65,10 +71,10 @@ namespace Orchard.ImportExport.Commands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[CommandName("export file")]
|
[CommandName("export file")]
|
||||||
[CommandHelp("export file [/Types:<type-name-1>, ... ,<type-name-n>] [/Metadata:true|false] [/Data:true|false] [/Version:Published|Draft] [/SiteSettings:true|false] [/Steps:<custom-step-1>, ... ,<custom-step-n>]\r\n\t" + "Create an export file according to the specified options.")]
|
[CommandHelp("export file [/Types:<type-name-1>, ... ,<type-name-n>] [/Metadata:true|false] [/Data:true|false] [/Version:Published|Draft|Latest] [/SiteSettings:true|false] [/Steps:<custom-step-1>, ... ,<custom-step-n>]\r\n\t" + "Create an export file according to the specified options.")]
|
||||||
[OrchardSwitches("Types,Metadata,Data,Version,SiteSettings,Steps")]
|
[OrchardSwitches("Types,Metadata,Data,Version,SiteSettings,Steps")]
|
||||||
public void ExportFile() {
|
public void ExportFile() {
|
||||||
// impersonate the Site owner
|
// Impersonate the Site owner.
|
||||||
var superUser = _siteService.GetSiteSettings().SuperUser;
|
var superUser = _siteService.GetSiteSettings().SuperUser;
|
||||||
var owner = _membershipService.GetUser(superUser);
|
var owner = _membershipService.GetUser(superUser);
|
||||||
_authenticationService.SetAuthenticatedUserForRequest(owner);
|
_authenticationService.SetAuthenticatedUserForRequest(owner);
|
||||||
@@ -82,23 +88,39 @@ namespace Orchard.ImportExport.Commands {
|
|||||||
|
|
||||||
var enteredTypes = (Types ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
var enteredTypes = (Types ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
var exportTypes = _contentDefinitionManager.ListTypeDefinitions()
|
var exportTypes = _contentDefinitionManager
|
||||||
.Where(contentType => enteredTypes.Contains(contentType.Name))
|
.ListTypeDefinitions()
|
||||||
.Select(contentType => contentType.Name);
|
.Where(contentType => enteredTypes.Contains(contentType.Name))
|
||||||
|
.Select(contentType => contentType.Name)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
var enteredSteps = (Steps ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
var enteredSteps = (Steps ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
var exportSteps = new List<IExportStepProvider>();
|
||||||
var exportOptions = new ExportOptions {
|
var exportOptions = new ExportOptions {
|
||||||
ExportMetadata = Metadata,
|
|
||||||
ExportData = Data,
|
|
||||||
VersionHistoryOptions = versionOption,
|
|
||||||
ExportSiteSettings = SiteSettings,
|
|
||||||
CustomSteps = enteredSteps
|
CustomSteps = enteredSteps
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (Metadata || Data) {
|
||||||
|
var dataStep = _orchardServices.WorkContext.Resolve<DataExportStep>();
|
||||||
|
|
||||||
|
if(Data)
|
||||||
|
dataStep.DataContentTypes = exportTypes;
|
||||||
|
|
||||||
|
if(Metadata)
|
||||||
|
dataStep.SchemaContentTypes = exportTypes;
|
||||||
|
|
||||||
|
dataStep.VersionHistoryOptions = versionOption;
|
||||||
|
exportSteps.Add(dataStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SiteSettings) {
|
||||||
|
var siteSettingsStep = _orchardServices.WorkContext.Resolve<SiteSettingsExportStep>();
|
||||||
|
exportSteps.Add(siteSettingsStep);
|
||||||
|
}
|
||||||
|
|
||||||
Context.Output.WriteLine(T("Export starting..."));
|
Context.Output.WriteLine(T("Export starting..."));
|
||||||
|
|
||||||
var exportFilePath = _importExportService.Export(exportTypes, exportOptions);
|
var exportFilePath = _importExportService.Export(exportSteps, exportOptions);
|
||||||
|
|
||||||
Context.Output.WriteLine(T("Export completed at {0}", exportFilePath));
|
Context.Output.WriteLine(T("Export completed at {0}", exportFilePath));
|
||||||
}
|
}
|
||||||
|
@@ -3,18 +3,17 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.MetaData;
|
using Orchard.ContentManagement.MetaData;
|
||||||
using Orchard.DisplayManagement;
|
using Orchard.ImportExport.Models;
|
||||||
using Orchard.ImportExport.Services;
|
using Orchard.ImportExport.Services;
|
||||||
using Orchard.ImportExport.ViewModels;
|
using Orchard.ImportExport.ViewModels;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Recipes.Services;
|
using Orchard.Recipes.Services;
|
||||||
using Orchard.UI.Notify;
|
using Orchard.UI.Notify;
|
||||||
using Orchard.ImportExport.Models;
|
|
||||||
using Orchard.Utility.Extensions;
|
|
||||||
|
|
||||||
namespace Orchard.ImportExport.Controllers {
|
namespace Orchard.ImportExport.Controllers {
|
||||||
public class AdminController : Controller {
|
public class AdminController : Controller, IUpdateModel {
|
||||||
private readonly IImportExportService _importExportService;
|
private readonly IImportExportService _importExportService;
|
||||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||||
private readonly ICustomExportStep _customExportStep;
|
private readonly ICustomExportStep _customExportStep;
|
||||||
@@ -79,25 +78,18 @@ namespace Orchard.ImportExport.Controllers {
|
|||||||
var customSteps = new List<string>();
|
var customSteps = new List<string>();
|
||||||
_customExportStep.Register(customSteps);
|
_customExportStep.Register(customSteps);
|
||||||
|
|
||||||
var exportSteps = _exportStepProviders.Select(x => {
|
var exportSteps = _exportStepProviders.OrderBy(x => x.Position).Select(x => new ExportStepViewModel {
|
||||||
var editor = x.BuildEditor(Services.New);
|
Name = x.Name,
|
||||||
editor.Provider = x;
|
DisplayName = x.DisplayName,
|
||||||
editor.Name = x.Name;
|
Description = x.Description,
|
||||||
editor.DisplayName = x.DisplayName;
|
Editor = x.BuildEditor(Services.New)
|
||||||
return editor;
|
|
||||||
}).Where(x => x != null);
|
}).Where(x => x != null);
|
||||||
|
|
||||||
var viewModel = new ExportViewModel {
|
var viewModel = new ExportViewModel {
|
||||||
RecipeVersion = "1.0",
|
|
||||||
ContentTypes = new List<ContentTypeEntry>(),
|
|
||||||
CustomSteps = customSteps.Select(x => new CustomStepEntry { CustomStep = x }).ToList(),
|
CustomSteps = customSteps.Select(x => new CustomStepEntry { CustomStep = x }).ToList(),
|
||||||
ExportSteps = exportSteps.ToList()
|
ExportSteps = exportSteps.ToList()
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var contentType in _contentDefinitionManager.ListTypeDefinitions().OrderBy(c => c.Name)) {
|
|
||||||
viewModel.ContentTypes.Add(new ContentTypeEntry { ContentTypeName = contentType.Name });
|
|
||||||
}
|
|
||||||
|
|
||||||
return View(viewModel);
|
return View(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,37 +99,39 @@ namespace Orchard.ImportExport.Controllers {
|
|||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
var viewModel = new ExportViewModel {
|
var viewModel = new ExportViewModel {
|
||||||
ContentTypes = new List<ContentTypeEntry>(),
|
CustomSteps = new List<CustomStepEntry>(),
|
||||||
CustomSteps = new List<CustomStepEntry>()
|
ExportSteps = new List<ExportStepViewModel>()
|
||||||
};
|
};
|
||||||
|
|
||||||
UpdateModel(viewModel);
|
UpdateModel(viewModel);
|
||||||
var contentTypesToExport = viewModel.ContentTypes.Where(c => c.IsChecked).Select(c => c.ContentTypeName).ToList();
|
var exportStepNames = viewModel.ExportSteps.Where(x => x.IsSelected).Select(x => x.Name);
|
||||||
|
var exportStepsQuery = from name in exportStepNames
|
||||||
|
let provider = _exportStepProviders.SingleOrDefault(x => x.Name == name)
|
||||||
|
where provider != null
|
||||||
|
select provider;
|
||||||
|
var exportSteps = exportStepsQuery.ToArray();
|
||||||
var customSteps = viewModel.CustomSteps.Where(c => c.IsChecked).Select(c => c.CustomStep);
|
var customSteps = viewModel.CustomSteps.Where(c => c.IsChecked).Select(c => c.CustomStep);
|
||||||
|
|
||||||
var exportOptions = new ExportOptions {
|
var exportOptions = new ExportOptions {
|
||||||
ExportMetadata = viewModel.Metadata,
|
|
||||||
ExportSiteSettings = viewModel.SiteSettings,
|
|
||||||
SetupRecipe = viewModel.SetupRecipe,
|
|
||||||
RecipeName = viewModel.RecipeName,
|
|
||||||
RecipeDescription = viewModel.RecipeDescription,
|
|
||||||
RecipeWebsite = viewModel.RecipeWebsite,
|
|
||||||
RecipeTags = viewModel.RecipeTags,
|
|
||||||
RecipeVersion = viewModel.RecipeVersion,
|
|
||||||
CustomSteps = customSteps
|
CustomSteps = customSteps
|
||||||
};
|
};
|
||||||
|
|
||||||
if (viewModel.Data) {
|
foreach (var exportStep in exportSteps) {
|
||||||
exportOptions.ExportData = true;
|
exportStep.UpdateEditor(Services.New, this);
|
||||||
exportOptions.VersionHistoryOptions = (VersionHistoryOptions)Enum.Parse(typeof(VersionHistoryOptions), viewModel.DataImportChoice, true);
|
|
||||||
exportOptions.ImportBatchSize = viewModel.ImportBatchSize;
|
|
||||||
}
|
}
|
||||||
var exportFilePath = _importExportService.Export(contentTypesToExport, exportOptions);
|
|
||||||
var exportFileName = exportOptions.SetupRecipe && !String.IsNullOrWhiteSpace(exportOptions.RecipeName)
|
var exportFilePath = _importExportService.Export(exportSteps, exportOptions);
|
||||||
? String.Format("{0}.recipe.xml", exportOptions.RecipeName.HtmlClassify())
|
var exportFileName = "export.xml";
|
||||||
: "export.xml";
|
|
||||||
|
|
||||||
return File(exportFilePath, "text/xml", exportFileName);
|
return File(exportFilePath, "text/xml", exportFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
||||||
|
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {
|
||||||
|
ModelState.AddModelError(key, errorMessage.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -2,22 +2,12 @@
|
|||||||
|
|
||||||
namespace Orchard.ImportExport.Models {
|
namespace Orchard.ImportExport.Models {
|
||||||
public class ExportOptions {
|
public class ExportOptions {
|
||||||
public bool ExportMetadata { get; set; }
|
|
||||||
public bool ExportData { get; set; }
|
|
||||||
public int? ImportBatchSize { get; set; }
|
|
||||||
public VersionHistoryOptions VersionHistoryOptions { get; set; }
|
|
||||||
public bool ExportSiteSettings { get; set; }
|
|
||||||
public IEnumerable<string> CustomSteps { get; set; }
|
public IEnumerable<string> CustomSteps { get; set; }
|
||||||
public bool SetupRecipe { get; set; }
|
|
||||||
public string RecipeName { get; set; }
|
|
||||||
public string RecipeDescription { get; set; }
|
|
||||||
public string RecipeWebsite { get; set; }
|
|
||||||
public string RecipeTags { get; set; }
|
|
||||||
public string RecipeVersion { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VersionHistoryOptions {
|
public enum VersionHistoryOptions {
|
||||||
Published,
|
Published,
|
||||||
Draft,
|
Draft,
|
||||||
|
Latest
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -71,7 +71,15 @@
|
|||||||
<Compile Include="Models\ExportOptions.cs" />
|
<Compile Include="Models\ExportOptions.cs" />
|
||||||
<Compile Include="Permissions.cs" />
|
<Compile Include="Permissions.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Providers\SetupRecipeExportStep.cs" />
|
||||||
|
<Compile Include="Providers\SiteSettingsExportStep.cs" />
|
||||||
<Compile Include="Providers\DataExportStep.cs" />
|
<Compile Include="Providers\DataExportStep.cs" />
|
||||||
|
<Compile Include="ViewModels\ContentTypeEntry.cs" />
|
||||||
|
<Compile Include="ViewModels\CustomStepEntry.cs" />
|
||||||
|
<Compile Include="ViewModels\ExportStepViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\SetupRecipeStepViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\SiteSettingsStepViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\DataExportStepViewModel.cs" />
|
||||||
<Compile Include="Services\ICustomExportStep.cs" />
|
<Compile Include="Services\ICustomExportStep.cs" />
|
||||||
<Compile Include="Services\IExportEventHandler.cs" />
|
<Compile Include="Services\IExportEventHandler.cs" />
|
||||||
<Compile Include="Services\IImportExportService.cs" />
|
<Compile Include="Services\IImportExportService.cs" />
|
||||||
@@ -101,6 +109,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Styles\images\menu.importexport.png" />
|
<Content Include="Styles\images\menu.importexport.png" />
|
||||||
|
<Content Include="Styles\exportstep-data.css" />
|
||||||
<Content Include="Styles\menu.importexport-admin.css" />
|
<Content Include="Styles\menu.importexport-admin.css" />
|
||||||
<Content Include="Web.config" />
|
<Content Include="Web.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -121,6 +130,12 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Views\EditorTemplates\ExportSteps\Data.cshtml" />
|
<Content Include="Views\EditorTemplates\ExportSteps\Data.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Views\EditorTemplates\ExportSteps\SiteSettings.cshtml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Views\EditorTemplates\ExportSteps\SetupRecipe.cshtml" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
@@ -1,27 +1,153 @@
|
|||||||
using Orchard.ContentManagement;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.ContentManagement.MetaData;
|
||||||
|
using Orchard.ContentManagement.MetaData.Models;
|
||||||
|
using Orchard.ImportExport.Models;
|
||||||
using Orchard.ImportExport.Services;
|
using Orchard.ImportExport.Services;
|
||||||
|
using Orchard.ImportExport.ViewModels;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
|
|
||||||
namespace Orchard.ImportExport.Providers {
|
namespace Orchard.ImportExport.Providers {
|
||||||
public class DataExportStep : ExportStepProvider {
|
public class DataExportStep : ExportStepProvider {
|
||||||
|
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||||
|
private readonly IOrchardServices _orchardServices;
|
||||||
|
private readonly IContentDefinitionWriter _contentDefinitionWriter;
|
||||||
|
|
||||||
|
public DataExportStep(
|
||||||
|
IContentDefinitionManager contentDefinitionManager,
|
||||||
|
IOrchardServices orchardServices,
|
||||||
|
IContentDefinitionWriter contentDefinitionWriter) {
|
||||||
|
|
||||||
|
_contentDefinitionManager = contentDefinitionManager;
|
||||||
|
_orchardServices = orchardServices;
|
||||||
|
_contentDefinitionWriter = contentDefinitionWriter;
|
||||||
|
}
|
||||||
|
|
||||||
public override string Name {
|
public override string Name {
|
||||||
get { return "Data"; }
|
get { return "Data"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override LocalizedString DisplayName {
|
public override LocalizedString DisplayName {
|
||||||
get { return T("Data"); }
|
get { return T("Content Items and Definitions"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override LocalizedString Description {
|
||||||
|
get { return T("Exports content items and content item definitions."); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Position { get { return 10; } }
|
||||||
|
|
||||||
|
public IList<string> SchemaContentTypes { get; set; }
|
||||||
|
public IList<string> DataContentTypes { get; set; }
|
||||||
|
public int? ImportBatchSize { get; set; }
|
||||||
|
public VersionHistoryOptions VersionHistoryOptions { get; set; }
|
||||||
|
|
||||||
public override dynamic BuildEditor(dynamic shapeFactory) {
|
public override dynamic BuildEditor(dynamic shapeFactory) {
|
||||||
return UpdateEditor(shapeFactory, null);
|
return UpdateEditor(shapeFactory, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
|
public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
|
||||||
if (updater != null) {
|
var contentTypeViewModels = _contentDefinitionManager.ListTypeDefinitions()
|
||||||
|
.OrderBy(x => x.Name)
|
||||||
|
.Select(x => new ContentTypeEntry { Name = x.Name, DisplayName = x.DisplayName })
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var viewModel = new DataExportStepViewModel {
|
||||||
|
ContentTypes = contentTypeViewModels
|
||||||
|
};
|
||||||
|
|
||||||
|
if (updater != null && updater.TryUpdateModel(viewModel, Prefix, null, null)) {
|
||||||
|
DataContentTypes = viewModel.ContentTypes.Where(x => x.ExportData).Select(x => x.Name).ToList();
|
||||||
|
SchemaContentTypes = viewModel.ContentTypes.Where(x => x.ExportSchema).Select(x => x.Name).ToList();
|
||||||
|
VersionHistoryOptions = viewModel.VersionHistoryOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/Data");
|
return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/Data", Model: viewModel, Prefix: Prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Export(ExportContext context) {
|
||||||
|
var dataContentTypes = DataContentTypes;
|
||||||
|
var schemaContentTypes = SchemaContentTypes;
|
||||||
|
var exportVersionOptions = GetContentExportVersionOptions(VersionHistoryOptions);
|
||||||
|
var contentItems = dataContentTypes.Any()
|
||||||
|
? _orchardServices.ContentManager.Query(exportVersionOptions, dataContentTypes.ToArray()).List().ToArray()
|
||||||
|
: Enumerable.Empty<ContentItem>();
|
||||||
|
|
||||||
|
if(schemaContentTypes.Any())
|
||||||
|
context.Document.Element("Orchard").Add(ExportMetadata(schemaContentTypes));
|
||||||
|
|
||||||
|
if(contentItems.Any())
|
||||||
|
context.Document.Element("Orchard").Add(ExportData(dataContentTypes, contentItems, ImportBatchSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
private XElement ExportMetadata(IEnumerable<string> contentTypes) {
|
||||||
|
var typesElement = new XElement("Types");
|
||||||
|
var partsElement = new XElement("Parts");
|
||||||
|
var typesToExport = _contentDefinitionManager.ListTypeDefinitions()
|
||||||
|
.Where(typeDefinition => contentTypes.Contains(typeDefinition.Name))
|
||||||
|
.ToList();
|
||||||
|
var partsToExport = new Dictionary<string, ContentPartDefinition>();
|
||||||
|
|
||||||
|
foreach (var contentTypeDefinition in typesToExport.OrderBy(x => x.Name)) {
|
||||||
|
foreach (var contentPartDefinition in contentTypeDefinition.Parts) {
|
||||||
|
if (partsToExport.ContainsKey(contentPartDefinition.PartDefinition.Name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
partsToExport.Add(contentPartDefinition.PartDefinition.Name, contentPartDefinition.PartDefinition);
|
||||||
|
}
|
||||||
|
typesElement.Add(_contentDefinitionWriter.Export(contentTypeDefinition));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var part in partsToExport.Values.OrderBy(x => x.Name)) {
|
||||||
|
partsElement.Add(_contentDefinitionWriter.Export(part));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new XElement("Metadata", typesElement, partsElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
private XElement ExportData(IEnumerable<string> contentTypes, IEnumerable<ContentItem> contentItems, int? batchSize) {
|
||||||
|
var data = new XElement("Data");
|
||||||
|
|
||||||
|
if (batchSize.HasValue && batchSize.Value > 0)
|
||||||
|
data.SetAttributeValue("BatchSize", batchSize);
|
||||||
|
|
||||||
|
var orderedContentItemsQuery =
|
||||||
|
from contentItem in contentItems
|
||||||
|
let identity = _orchardServices.ContentManager.GetItemMetadata(contentItem).Identity.ToString()
|
||||||
|
orderby identity
|
||||||
|
select contentItem;
|
||||||
|
|
||||||
|
var orderedContentItems = orderedContentItemsQuery.ToList();
|
||||||
|
|
||||||
|
foreach (var contentType in contentTypes.OrderBy(x => x)) {
|
||||||
|
var type = contentType;
|
||||||
|
var items = orderedContentItems.Where(i => i.ContentType == type);
|
||||||
|
foreach (var contentItem in items) {
|
||||||
|
var contentItemElement = ExportContentItem(contentItem);
|
||||||
|
if (contentItemElement != null)
|
||||||
|
data.Add(contentItemElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private VersionOptions GetContentExportVersionOptions(VersionHistoryOptions versionHistoryOptions) {
|
||||||
|
switch (versionHistoryOptions) {
|
||||||
|
case VersionHistoryOptions.Draft:
|
||||||
|
return VersionOptions.Draft;
|
||||||
|
case VersionHistoryOptions.Latest:
|
||||||
|
return VersionOptions.Latest;
|
||||||
|
case VersionHistoryOptions.Published:
|
||||||
|
default:
|
||||||
|
return VersionOptions.Published;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private XElement ExportContentItem(ContentItem contentItem) {
|
||||||
|
return _orchardServices.ContentManager.Export(contentItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,69 @@
|
|||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.ImportExport.Services;
|
||||||
|
using Orchard.ImportExport.ViewModels;
|
||||||
|
using Orchard.Localization;
|
||||||
|
|
||||||
|
namespace Orchard.ImportExport.Providers {
|
||||||
|
public class SetupRecipeExportStep : ExportStepProvider {
|
||||||
|
private readonly IOrchardServices _orchardServices;
|
||||||
|
public SetupRecipeExportStep(IOrchardServices orchardServices) {
|
||||||
|
_orchardServices = orchardServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name {
|
||||||
|
get { return "SetupRecipe"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LocalizedString DisplayName {
|
||||||
|
get { return T("Setup Recipe"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LocalizedString Description {
|
||||||
|
get { return T("Turns the export file into a Setup recipe."); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Position { get { return -10; } }
|
||||||
|
|
||||||
|
public string RecipeName { get; set; }
|
||||||
|
public string RecipeDescription { get; set; }
|
||||||
|
public string RecipeAuthor { get; set; }
|
||||||
|
public string RecipeWebsite { get; set; }
|
||||||
|
public string RecipeTags { get; set; }
|
||||||
|
public string RecipeVersion { get; set; }
|
||||||
|
public bool IsSetupRecipe { get; set; }
|
||||||
|
|
||||||
|
public override dynamic BuildEditor(dynamic shapeFactory) {
|
||||||
|
return UpdateEditor(shapeFactory, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
|
||||||
|
var viewModel = new SetupRecipeStepViewModel {
|
||||||
|
RecipeAuthor = _orchardServices.WorkContext.CurrentUser.UserName
|
||||||
|
};
|
||||||
|
|
||||||
|
if (updater != null && updater.TryUpdateModel(viewModel, Prefix, null, null)) {
|
||||||
|
RecipeName = viewModel.RecipeName;
|
||||||
|
RecipeDescription = viewModel.RecipeDescription;
|
||||||
|
RecipeAuthor = viewModel.RecipeAuthor;
|
||||||
|
RecipeWebsite = viewModel.RecipeWebsite;
|
||||||
|
RecipeTags = viewModel.RecipeTags;
|
||||||
|
RecipeVersion = viewModel.RecipeVersion;
|
||||||
|
IsSetupRecipe = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/SetupRecipe", Model: viewModel, Prefix: Prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Export(ExportContext context) {
|
||||||
|
var recipeElement = context.Document.Element("Orchard").Element("Recipe");
|
||||||
|
|
||||||
|
recipeElement.SetElementValue("Name", RecipeName);
|
||||||
|
recipeElement.SetElementValue("Description", RecipeDescription);
|
||||||
|
recipeElement.SetElementValue("Author", RecipeAuthor);
|
||||||
|
recipeElement.SetElementValue("WebSite", RecipeWebsite);
|
||||||
|
recipeElement.SetElementValue("Tags", RecipeTags);
|
||||||
|
recipeElement.SetElementValue("Version", RecipeVersion);
|
||||||
|
recipeElement.SetElementValue("IsSetupRecipe", IsSetupRecipe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,95 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.ImportExport.Services;
|
||||||
|
using Orchard.ImportExport.ViewModels;
|
||||||
|
using Orchard.Localization;
|
||||||
|
|
||||||
|
namespace Orchard.ImportExport.Providers {
|
||||||
|
public class SiteSettingsExportStep : ExportStepProvider {
|
||||||
|
private readonly IOrchardServices _orchardServices;
|
||||||
|
|
||||||
|
public SiteSettingsExportStep(IOrchardServices orchardServices) {
|
||||||
|
_orchardServices = orchardServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name {
|
||||||
|
get { return "SiteSettings"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LocalizedString DisplayName {
|
||||||
|
get { return T("Site Settings"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LocalizedString Description {
|
||||||
|
get { return T("Exports site settings."); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Position { get { return 20; } }
|
||||||
|
|
||||||
|
public override dynamic BuildEditor(dynamic shapeFactory) {
|
||||||
|
return UpdateEditor(shapeFactory, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
|
||||||
|
var viewModel = new SiteSettingsStepViewModel();
|
||||||
|
return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/SiteSettings", Model: viewModel, Prefix: Prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Export(ExportContext context) {
|
||||||
|
context.Document.Element("Orchard").Add(ExportSiteSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
private XElement ExportSiteSettings() {
|
||||||
|
var siteContentItem = _orchardServices.WorkContext.CurrentSite.ContentItem;
|
||||||
|
var exportedElements = ExportContentItem(siteContentItem).Elements().ToList();
|
||||||
|
|
||||||
|
foreach (var contentPart in siteContentItem.Parts.OrderBy(x => x.PartDefinition.Name)) {
|
||||||
|
var exportedElement = exportedElements.FirstOrDefault(element => element.Name == contentPart.PartDefinition.Name);
|
||||||
|
|
||||||
|
// Get all simple attributes if exported element is null.
|
||||||
|
// Get exclude the simple attributes that already exist if element is not null.
|
||||||
|
var simpleAttributes =
|
||||||
|
ExportSettingsPartAttributes(contentPart)
|
||||||
|
.Where(attribute => exportedElement == null || exportedElement.Attributes().All(xAttribute => xAttribute.Name != attribute.Name))
|
||||||
|
.OrderBy(x => x.Name.LocalName)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (simpleAttributes.Any()) {
|
||||||
|
if (exportedElement == null) {
|
||||||
|
exportedElement = new XElement(contentPart.PartDefinition.Name);
|
||||||
|
exportedElements.Add(exportedElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
exportedElement.Add(simpleAttributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exportedElements = exportedElements.OrderBy(x => x.Name.LocalName).ToList();
|
||||||
|
return new XElement("Settings", exportedElements);
|
||||||
|
}
|
||||||
|
|
||||||
|
private XElement ExportContentItem(ContentItem contentItem) {
|
||||||
|
return _orchardServices.ContentManager.Export(contentItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<XAttribute> ExportSettingsPartAttributes(ContentPart sitePart) {
|
||||||
|
foreach (var property in sitePart.GetType().GetProperties().OrderBy(x => x.Name)) {
|
||||||
|
var propertyType = property.PropertyType;
|
||||||
|
|
||||||
|
// Supported types (we also know they are not indexed properties).
|
||||||
|
if (propertyType == typeof(string) || propertyType == typeof(bool) || propertyType == typeof(int)) {
|
||||||
|
// Exclude read-only properties.
|
||||||
|
if (property.GetSetMethod() != null) {
|
||||||
|
var value = property.GetValue(sitePart, null);
|
||||||
|
if (value == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
yield return new XAttribute(property.Name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -5,6 +5,8 @@ namespace Orchard.ImportExport.Services {
|
|||||||
public abstract class ExportStepProvider : Component, IExportStepProvider {
|
public abstract class ExportStepProvider : Component, IExportStepProvider {
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
public abstract LocalizedString DisplayName { get; }
|
public abstract LocalizedString DisplayName { get; }
|
||||||
|
public abstract LocalizedString Description { get; }
|
||||||
|
public virtual int Position { get { return 0; } }
|
||||||
|
|
||||||
protected virtual string Prefix {
|
protected virtual string Prefix {
|
||||||
get { return GetType().Name; }
|
get { return GetType().Name; }
|
||||||
@@ -17,5 +19,7 @@ namespace Orchard.ImportExport.Services {
|
|||||||
public virtual dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
|
public virtual dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void Export(ExportContext context) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,12 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Xml.Linq;
|
||||||
using System.Xml.Linq;
|
|
||||||
using Orchard.Events;
|
using Orchard.Events;
|
||||||
using Orchard.ImportExport.Models;
|
using Orchard.ImportExport.Models;
|
||||||
|
|
||||||
namespace Orchard.ImportExport.Services {
|
namespace Orchard.ImportExport.Services {
|
||||||
public class ExportContext {
|
public class ExportContext {
|
||||||
public XDocument Document { get; set; }
|
public XDocument Document { get; set; }
|
||||||
public IEnumerable<string> ContentTypes { get; set; }
|
|
||||||
public ExportOptions ExportOptions { get; set; }
|
public ExportOptions ExportOptions { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,7 +5,10 @@ namespace Orchard.ImportExport.Services {
|
|||||||
public interface IExportStepProvider : IDependency {
|
public interface IExportStepProvider : IDependency {
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
LocalizedString DisplayName { get; }
|
LocalizedString DisplayName { get; }
|
||||||
|
LocalizedString Description { get; }
|
||||||
|
int Position { get; }
|
||||||
dynamic BuildEditor(dynamic shapeFactory);
|
dynamic BuildEditor(dynamic shapeFactory);
|
||||||
dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater);
|
dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater);
|
||||||
|
void Export(ExportContext context);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,12 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ImportExport.Models;
|
using Orchard.ImportExport.Models;
|
||||||
|
|
||||||
namespace Orchard.ImportExport.Services {
|
namespace Orchard.ImportExport.Services {
|
||||||
public interface IImportExportService : IDependency {
|
public interface IImportExportService : IDependency {
|
||||||
string Import(string recipeText);
|
string Import(string recipeText);
|
||||||
string Export(IEnumerable<string> contentTypes, IEnumerable<ContentItem> contentItems, ExportOptions exportOptions);
|
string Export(IEnumerable<IExportStepProvider> steps, ExportOptions exportOptions);
|
||||||
string Export(IEnumerable<string> contentTypes, ExportOptions exportOptions);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,11 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.MetaData;
|
|
||||||
using Orchard.ContentManagement.MetaData.Models;
|
|
||||||
using Orchard.Environment.Descriptor;
|
using Orchard.Environment.Descriptor;
|
||||||
using Orchard.FileSystems.AppData;
|
using Orchard.FileSystems.AppData;
|
||||||
using Orchard.ImportExport.Models;
|
using Orchard.ImportExport.Models;
|
||||||
@@ -17,8 +14,6 @@ using Orchard.Services;
|
|||||||
namespace Orchard.ImportExport.Services {
|
namespace Orchard.ImportExport.Services {
|
||||||
public class ImportExportService : IImportExportService {
|
public class ImportExportService : IImportExportService {
|
||||||
private readonly IOrchardServices _orchardServices;
|
private readonly IOrchardServices _orchardServices;
|
||||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
|
||||||
private readonly IContentDefinitionWriter _contentDefinitionWriter;
|
|
||||||
private readonly IAppDataFolder _appDataFolder;
|
private readonly IAppDataFolder _appDataFolder;
|
||||||
private readonly IRecipeParser _recipeParser;
|
private readonly IRecipeParser _recipeParser;
|
||||||
private readonly IRecipeManager _recipeManager;
|
private readonly IRecipeManager _recipeManager;
|
||||||
@@ -29,8 +24,6 @@ namespace Orchard.ImportExport.Services {
|
|||||||
|
|
||||||
public ImportExportService(
|
public ImportExportService(
|
||||||
IOrchardServices orchardServices,
|
IOrchardServices orchardServices,
|
||||||
IContentDefinitionManager contentDefinitionManager,
|
|
||||||
IContentDefinitionWriter contentDefinitionWriter,
|
|
||||||
IAppDataFolder appDataFolder,
|
IAppDataFolder appDataFolder,
|
||||||
IRecipeParser recipeParser,
|
IRecipeParser recipeParser,
|
||||||
IRecipeManager recipeManager,
|
IRecipeManager recipeManager,
|
||||||
@@ -39,8 +32,6 @@ namespace Orchard.ImportExport.Services {
|
|||||||
IEnumerable<IExportEventHandler> exportEventHandlers) {
|
IEnumerable<IExportEventHandler> exportEventHandlers) {
|
||||||
|
|
||||||
_orchardServices = orchardServices;
|
_orchardServices = orchardServices;
|
||||||
_contentDefinitionManager = contentDefinitionManager;
|
|
||||||
_contentDefinitionWriter = contentDefinitionWriter;
|
|
||||||
_appDataFolder = appDataFolder;
|
_appDataFolder = appDataFolder;
|
||||||
_recipeParser = recipeParser;
|
_recipeParser = recipeParser;
|
||||||
_recipeManager = recipeManager;
|
_recipeManager = recipeManager;
|
||||||
@@ -61,37 +52,18 @@ namespace Orchard.ImportExport.Services {
|
|||||||
return executionId;
|
return executionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Export(IEnumerable<string> contentTypes, ExportOptions exportOptions) {
|
public string Export(IEnumerable<IExportStepProvider> steps, ExportOptions exportOptions) {
|
||||||
//items need to be retrieved
|
var exportDocument = CreateExportRoot();
|
||||||
IEnumerable<ContentItem> contentItems = null;
|
|
||||||
if (exportOptions.ExportData) {
|
|
||||||
contentItems = _orchardServices.ContentManager.Query(GetContentExportVersionOptions(exportOptions.VersionHistoryOptions), contentTypes.ToArray()).List().ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Export(contentTypes, contentItems, exportOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Export(IEnumerable<string> contentTypes, IEnumerable<ContentItem> contentItems, ExportOptions exportOptions) {
|
|
||||||
var exportDocument = CreateExportRoot(exportOptions);
|
|
||||||
|
|
||||||
var context = new ExportContext {
|
var context = new ExportContext {
|
||||||
Document = exportDocument,
|
Document = exportDocument,
|
||||||
ContentTypes = contentTypes,
|
|
||||||
ExportOptions = exportOptions
|
ExportOptions = exportOptions
|
||||||
};
|
};
|
||||||
|
|
||||||
_exportEventHandlers.Invoke(x => x.Exporting(context), Logger);
|
_exportEventHandlers.Invoke(x => x.Exporting(context), Logger);
|
||||||
|
|
||||||
if (exportOptions.ExportMetadata && (!exportOptions.ExportData || contentItems.Any())) {
|
foreach (var step in steps) {
|
||||||
exportDocument.Element("Orchard").Add(ExportMetadata(contentTypes));
|
step.Export(context);
|
||||||
}
|
|
||||||
|
|
||||||
if (exportOptions.ExportSiteSettings) {
|
|
||||||
exportDocument.Element("Orchard").Add(ExportSiteSettings());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exportOptions.ExportData && contentItems.Any()) {
|
|
||||||
exportDocument.Element("Orchard").Add(ExportData(contentTypes, contentItems, exportOptions.ImportBatchSize));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_exportEventHandlers.Invoke(x => x.Exported(context), Logger);
|
_exportEventHandlers.Invoke(x => x.Exported(context), Logger);
|
||||||
@@ -99,143 +71,21 @@ namespace Orchard.ImportExport.Services {
|
|||||||
return WriteExportFile(exportDocument.ToString());
|
return WriteExportFile(exportDocument.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private XDocument CreateExportRoot(ExportOptions exportOptions) {
|
private XDocument CreateExportRoot() {
|
||||||
var recipeName = !String.IsNullOrWhiteSpace(exportOptions.RecipeName)
|
|
||||||
? exportOptions.RecipeName
|
|
||||||
: T("Generated by Orchard.ImportExport").ToString();
|
|
||||||
|
|
||||||
var exportRoot = new XDocument(
|
var exportRoot = new XDocument(
|
||||||
new XDeclaration("1.0", "", "yes"),
|
new XDeclaration("1.0", "", "yes"),
|
||||||
new XComment("Exported from Orchard"),
|
new XComment("Exported from Orchard"),
|
||||||
new XElement("Orchard",
|
new XElement("Orchard",
|
||||||
new XElement("Recipe",
|
new XElement("Recipe",
|
||||||
new XElement("Name", recipeName),
|
|
||||||
new XElement("Description", exportOptions.RecipeDescription),
|
|
||||||
new XElement("Author", _orchardServices.WorkContext.CurrentUser.UserName),
|
|
||||||
new XElement("WebSite", exportOptions.RecipeWebsite),
|
|
||||||
new XElement("Tags", exportOptions.RecipeTags),
|
|
||||||
new XElement("Version", exportOptions.RecipeVersion),
|
|
||||||
new XElement("IsSetupRecipe", exportOptions.SetupRecipe),
|
|
||||||
new XElement("ExportUtc", XmlConvert.ToString(_clock.UtcNow, XmlDateTimeSerializationMode.Utc))
|
new XElement("ExportUtc", XmlConvert.ToString(_clock.UtcNow, XmlDateTimeSerializationMode.Utc))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return exportRoot;
|
return exportRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private XElement ExportMetadata(IEnumerable<string> contentTypes) {
|
|
||||||
var typesElement = new XElement("Types");
|
|
||||||
var partsElement = new XElement("Parts");
|
|
||||||
var typesToExport = _contentDefinitionManager.ListTypeDefinitions()
|
|
||||||
.Where(typeDefinition => contentTypes.Contains(typeDefinition.Name))
|
|
||||||
.ToList();
|
|
||||||
var partsToExport = new Dictionary<string, ContentPartDefinition>();
|
|
||||||
|
|
||||||
foreach (var contentTypeDefinition in typesToExport.OrderBy(x => x.Name)) {
|
|
||||||
foreach (var contentPartDefinition in contentTypeDefinition.Parts) {
|
|
||||||
if (partsToExport.ContainsKey(contentPartDefinition.PartDefinition.Name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
partsToExport.Add(contentPartDefinition.PartDefinition.Name, contentPartDefinition.PartDefinition);
|
|
||||||
}
|
|
||||||
typesElement.Add(_contentDefinitionWriter.Export(contentTypeDefinition));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var part in partsToExport.Values.OrderBy(x => x.Name)) {
|
|
||||||
partsElement.Add(_contentDefinitionWriter.Export(part));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new XElement("Metadata", typesElement, partsElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
private XElement ExportSiteSettings() {
|
|
||||||
var siteContentItem = _orchardServices.WorkContext.CurrentSite.ContentItem;
|
|
||||||
var exportedElements = ExportContentItem(siteContentItem).Elements().ToList();
|
|
||||||
|
|
||||||
foreach (var contentPart in siteContentItem.Parts.OrderBy(x => x.PartDefinition.Name)) {
|
|
||||||
var exportedElement = exportedElements.FirstOrDefault(element => element.Name == contentPart.PartDefinition.Name);
|
|
||||||
|
|
||||||
//Get all simple attributes if exported element is null
|
|
||||||
//Get exclude the simple attributes that already exist if element is not null
|
|
||||||
var simpleAttributes =
|
|
||||||
ExportSettingsPartAttributes(contentPart)
|
|
||||||
.Where(attribute => exportedElement == null || exportedElement.Attributes().All(xAttribute => xAttribute.Name != attribute.Name))
|
|
||||||
.OrderBy(x => x.Name.LocalName)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (simpleAttributes.Any()) {
|
|
||||||
if (exportedElement == null) {
|
|
||||||
exportedElement = new XElement(contentPart.PartDefinition.Name);
|
|
||||||
exportedElements.Add(exportedElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
exportedElement.Add(simpleAttributes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exportedElements = exportedElements.OrderBy(x => x.Name.LocalName).ToList();
|
|
||||||
return new XElement("Settings", exportedElements);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<XAttribute> ExportSettingsPartAttributes(ContentPart sitePart) {
|
|
||||||
foreach (var property in sitePart.GetType().GetProperties().OrderBy(x => x.Name)) {
|
|
||||||
var propertyType = property.PropertyType;
|
|
||||||
|
|
||||||
// Supported types (we also know they are not indexed properties).
|
|
||||||
if (propertyType == typeof(string) || propertyType == typeof(bool) || propertyType == typeof(int)) {
|
|
||||||
// Exclude read-only properties.
|
|
||||||
if (property.GetSetMethod() != null) {
|
|
||||||
var value = property.GetValue(sitePart, null);
|
|
||||||
if (value == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
yield return new XAttribute(property.Name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private XElement ExportData(IEnumerable<string> contentTypes, IEnumerable<ContentItem> contentItems, int? batchSize) {
|
|
||||||
var data = new XElement("Data");
|
|
||||||
|
|
||||||
if (batchSize.HasValue && batchSize.Value > 0)
|
|
||||||
data.SetAttributeValue("BatchSize", batchSize);
|
|
||||||
|
|
||||||
var orderedContentItemsQuery =
|
|
||||||
from contentItem in contentItems
|
|
||||||
let identity = _orchardServices.ContentManager.GetItemMetadata(contentItem).Identity.ToString()
|
|
||||||
orderby identity
|
|
||||||
select contentItem;
|
|
||||||
|
|
||||||
var orderedContentItems = orderedContentItemsQuery.ToList();
|
|
||||||
|
|
||||||
foreach (var contentType in contentTypes.OrderBy(x => x)) {
|
|
||||||
var type = contentType;
|
|
||||||
var items = orderedContentItems.Where(i => i.ContentType == type);
|
|
||||||
foreach (var contentItem in items) {
|
|
||||||
var contentItemElement = ExportContentItem(contentItem);
|
|
||||||
if (contentItemElement != null)
|
|
||||||
data.Add(contentItemElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private XElement ExportContentItem(ContentItem contentItem) {
|
|
||||||
// Call export handler for the item.
|
|
||||||
return _orchardServices.ContentManager.Export(contentItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static VersionOptions GetContentExportVersionOptions(VersionHistoryOptions versionHistoryOptions) {
|
|
||||||
if (versionHistoryOptions.HasFlag(VersionHistoryOptions.Draft)) {
|
|
||||||
return VersionOptions.Draft;
|
|
||||||
}
|
|
||||||
return VersionOptions.Published;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string WriteExportFile(string exportDocument) {
|
private string WriteExportFile(string exportDocument) {
|
||||||
var exportFile = string.Format("Export-{0}-{1}.xml", _orchardServices.WorkContext.CurrentUser.UserName, DateTime.UtcNow.Ticks);
|
var exportFile = String.Format("Export-{0}-{1}.xml", _orchardServices.WorkContext.CurrentUser.UserName, DateTime.UtcNow.Ticks);
|
||||||
if (!_appDataFolder.DirectoryExists(ExportsDirectory)) {
|
if (!_appDataFolder.DirectoryExists(ExportsDirectory)) {
|
||||||
_appDataFolder.CreateDirectory(ExportsDirectory);
|
_appDataFolder.CreateDirectory(ExportsDirectory);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
fieldset.export-step-data table.items {
|
||||||
|
width: 500px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset.export-step-data table.items td,
|
||||||
|
fieldset.export-step-data table.items thead tr.sub th {
|
||||||
|
padding: 0 12px;
|
||||||
|
}
|
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Orchard.ImportExport.ViewModels {
|
||||||
|
public class ContentTypeEntry {
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
public bool ExportSchema { get; set; }
|
||||||
|
public bool ExportData { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Orchard.ImportExport.ViewModels {
|
||||||
|
public class CustomStepEntry {
|
||||||
|
public string CustomStep { get; set; }
|
||||||
|
public bool IsChecked { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.ImportExport.Models;
|
||||||
|
|
||||||
|
namespace Orchard.ImportExport.ViewModels {
|
||||||
|
public class DataExportStepViewModel {
|
||||||
|
public DataExportStepViewModel() {
|
||||||
|
ContentTypes = new List<ContentTypeEntry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<ContentTypeEntry> ContentTypes { get; set; }
|
||||||
|
public VersionHistoryOptions VersionHistoryOptions { get; set; }
|
||||||
|
public int? ImportBatchSize { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
using Orchard.Localization;
|
||||||
|
|
||||||
|
namespace Orchard.ImportExport.ViewModels {
|
||||||
|
public class ExportStepViewModel {
|
||||||
|
public string Name { get; set; }
|
||||||
|
public LocalizedString DisplayName { get; set; }
|
||||||
|
public LocalizedString Description { get; set; }
|
||||||
|
public bool IsSelected { get; set; }
|
||||||
|
public dynamic Editor { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -2,29 +2,7 @@
|
|||||||
|
|
||||||
namespace Orchard.ImportExport.ViewModels {
|
namespace Orchard.ImportExport.ViewModels {
|
||||||
public class ExportViewModel {
|
public class ExportViewModel {
|
||||||
public IList<ContentTypeEntry> ContentTypes { get; set; }
|
|
||||||
public IList<CustomStepEntry> CustomSteps { get; set; }
|
public IList<CustomStepEntry> CustomSteps { get; set; }
|
||||||
public IList<dynamic> ExportSteps { get; set; }
|
public IList<ExportStepViewModel> ExportSteps { get; set; }
|
||||||
public bool Metadata { get; set; }
|
|
||||||
public bool Data { get; set; }
|
|
||||||
public int? ImportBatchSize { get; set; }
|
|
||||||
public string DataImportChoice { get; set; }
|
|
||||||
public bool SiteSettings { get; set; }
|
|
||||||
public bool SetupRecipe { get; set; }
|
|
||||||
public string RecipeName { get; set; }
|
|
||||||
public string RecipeDescription { get; set; }
|
|
||||||
public string RecipeWebsite { get; set; }
|
|
||||||
public string RecipeTags { get; set; }
|
|
||||||
public string RecipeVersion { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ContentTypeEntry {
|
|
||||||
public string ContentTypeName { get; set; }
|
|
||||||
public bool IsChecked { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CustomStepEntry {
|
|
||||||
public string CustomStep { get; set; }
|
|
||||||
public bool IsChecked { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Orchard.ImportExport.ViewModels {
|
||||||
|
public class SetupRecipeStepViewModel {
|
||||||
|
public string RecipeName { get; set; }
|
||||||
|
public string RecipeDescription { get; set; }
|
||||||
|
public string RecipeAuthor { get; set; }
|
||||||
|
public string RecipeWebsite { get; set; }
|
||||||
|
public string RecipeTags { get; set; }
|
||||||
|
public string RecipeVersion { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
namespace Orchard.ImportExport.ViewModels {
|
||||||
|
public class SiteSettingsStepViewModel {}
|
||||||
|
}
|
@@ -1,114 +1,44 @@
|
|||||||
@using Orchard.Localization
|
@using Orchard.Utility.Extensions
|
||||||
@using Orchard.Utility.Extensions
|
|
||||||
@model Orchard.ImportExport.ViewModels.ExportViewModel
|
@model Orchard.ImportExport.ViewModels.ExportViewModel
|
||||||
@{ Layout.Title = T("Export").ToString(); }
|
@{ Layout.Title = T("Export").ToString(); }
|
||||||
@using (Html.BeginFormAntiForgeryPost()) {
|
@using (Html.BeginFormAntiForgeryPost()) {
|
||||||
Html.ValidationSummary();
|
Html.ValidationSummary();
|
||||||
|
var exportStepIndex = 0;
|
||||||
foreach (var exportStep in Model.ExportSteps) {
|
foreach (var exportStep in Model.ExportSteps) {
|
||||||
var displayName = (LocalizedString)exportStep.DisplayName;
|
var stepName = Html.NameFor(m => m.ExportSteps[exportStepIndex].IsSelected).ToString();
|
||||||
var stepId = String.Format("step-{0}", displayName.ToString().HtmlClassify());
|
var stepId = stepName.HtmlClassify();
|
||||||
<fieldset>
|
|
||||||
<legend><label><input type="checkbox" id="@stepId" />@displayName</label></legend>
|
<fieldset class="export-step export-step-@exportStep.Name.HtmlClassify()">
|
||||||
<div data-controllerid="@stepId">
|
<legend>
|
||||||
@Display(exportStep)
|
<input type="hidden" name="@Html.NameFor(m => m.ExportSteps[exportStepIndex].Name)" value="@Model.ExportSteps[exportStepIndex].Name"/>
|
||||||
</div>
|
<input type="checkbox" id="@stepId" name="@stepName" value="true"/>
|
||||||
</fieldset>
|
<label for="@stepId" class="forcheckbox">@exportStep.DisplayName</label>
|
||||||
}
|
</legend>
|
||||||
<fieldset>
|
@Html.Hint(@exportStep.Description)
|
||||||
<legend>@T("Choose the types to include in the export file:")</legend>
|
<div data-controllerid="@stepId">
|
||||||
<label><input type="checkbox" class="check-all" />@T("Select all")</label>
|
@Display(exportStep.Editor)
|
||||||
<ol>
|
|
||||||
@for (var contentTypeIndex = 0; contentTypeIndex < Model.ContentTypes.Count; contentTypeIndex++) {
|
|
||||||
<li>
|
|
||||||
<input type="hidden" value="@Model.ContentTypes[contentTypeIndex].ContentTypeName" name="@Html.NameOf(m => m.ContentTypes[contentTypeIndex].ContentTypeName)"/>
|
|
||||||
<input type="checkbox" value="true" name="@Html.NameOf(m => m.ContentTypes[contentTypeIndex].IsChecked)" id="@Html.NameOf(m => m.ContentTypes[contentTypeIndex].IsChecked)" />
|
|
||||||
<label class="forcheckbox" for="@Html.NameOf(m => m.ContentTypes[contentTypeIndex].IsChecked)">@Model.ContentTypes[contentTypeIndex].ContentTypeName.CamelFriendly()</label>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ol>
|
|
||||||
</fieldset>
|
|
||||||
<hr />
|
|
||||||
<fieldset>
|
|
||||||
<legend>@T("Choose what to save for these types:")</legend>
|
|
||||||
<div>
|
|
||||||
@Html.EditorFor(m => m.Metadata)
|
|
||||||
@Html.LabelFor(m => m.Metadata, T("Metadata").ToString(), new { @class = "forcheckbox" })
|
|
||||||
@Html.Hint(T("Metadata is the definition of your content types: what parts and fields they have, with what settings."))
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@Html.EditorFor(m => m.Data)
|
|
||||||
@Html.LabelFor(m => m.Data, T("Data").ToString(), new { @class = "forcheckbox" })
|
|
||||||
@Html.Hint(T("Data is the actual content of your site."))
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@Html.LabelFor(m => m.ImportBatchSize, T("Batch Size"))
|
|
||||||
@Html.TextBoxFor(m => m.ImportBatchSize, new {@class = "text small"})
|
|
||||||
@Html.Hint(T("The batch size to use when importing the data. Leave empty to disable batched imports."))
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>@T("Version History")</p>
|
|
||||||
@Html.RadioButtonFor(m => m.DataImportChoice, "Published", new {id = "Published", Checked = "Checked"})
|
|
||||||
<label for="Published" class="forcheckbox">@T("Only Published Versions")</label>
|
|
||||||
<br/>
|
|
||||||
@Html.RadioButtonFor(m => m.DataImportChoice, "Draft", new {id = "Draft"})
|
|
||||||
<label for="Draft" class="forcheckbox">@T("Only Drafts")</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@Html.EditorFor(m => m.SiteSettings)
|
|
||||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.SiteSettings)">@T("Site Settings")</label><br/>
|
|
||||||
@Html.Hint(T("Please verify that you are not exporting confidential information, such as passwords or application keys."))
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
<fieldset>
|
|
||||||
<legend>@T("Setup")</legend>
|
|
||||||
<div>
|
|
||||||
@Html.CheckBoxFor(m => m.SetupRecipe)
|
|
||||||
@Html.LabelFor(m => m.SetupRecipe, T("Setup Recipe").ToString(), new {@class = "forcheckbox"})
|
|
||||||
@Html.Hint(T("Check this option if you want to use the generated recipe as a setup recipe."))
|
|
||||||
</div>
|
|
||||||
<div data-controllerid="@Html.FieldIdFor(m => m.SetupRecipe)">
|
|
||||||
<div>
|
|
||||||
@Html.LabelFor(m => m.RecipeName, T("Name"))
|
|
||||||
@Html.TextBoxFor(m => m.RecipeName, new { @class = "text medium" })
|
|
||||||
@Html.Hint(T("Optionally provide a name for the setup recipe."))
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</fieldset>
|
||||||
@Html.LabelFor(m => m.RecipeDescription, T("Description"))
|
exportStepIndex++;
|
||||||
@Html.TextBoxFor(m => m.RecipeDescription, new {@class = "text large"})
|
if (exportStepIndex < Model.ExportSteps.Count) {
|
||||||
@Html.Hint(T("Optionally provide a description for the setup recipe."))
|
<hr />
|
||||||
</div>
|
}
|
||||||
<div>
|
}
|
||||||
@Html.LabelFor(m => m.RecipeWebsite, T("Website"))
|
|
||||||
@Html.TextBoxFor(m => m.RecipeWebsite, new {@class = "text large"})
|
|
||||||
@Html.Hint(T("Optionally provide a website URL for the setup recipe."))
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@Html.LabelFor(m => m.RecipeTags, T("Tags"))
|
|
||||||
@Html.TextBoxFor(m => m.RecipeTags, new {@class = "text large"})
|
|
||||||
@Html.Hint(T("Optionally provide tags for the setup recipe."))
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@Html.LabelFor(m => m.RecipeVersion, T("Version"))
|
|
||||||
@Html.TextBoxFor(m => m.RecipeVersion, new {@class = "text small"})
|
|
||||||
@Html.Hint(T("Optionally provide a version for the setup recipe."))
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
if (Model.CustomSteps.Any()) {
|
if (Model.CustomSteps.Any()) {
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>@T("Choose the custom steps to execute in the export file:")</legend>
|
<legend>@T("Choose the custom steps to execute in the export file:")</legend>
|
||||||
<ol>
|
<ol>
|
||||||
@for (var customStepIndex = 0; customStepIndex < Model.CustomSteps.Count; customStepIndex++) {
|
@for (var customStepIndex = 0; customStepIndex < Model.CustomSteps.Count; customStepIndex++) {
|
||||||
<li>
|
<li>
|
||||||
<input type="hidden" value="@Model.CustomSteps[customStepIndex].CustomStep" name="@Html.NameOf(m => m.CustomSteps[customStepIndex].CustomStep)"/>
|
<input type="hidden" value="@Model.CustomSteps[customStepIndex].CustomStep" name="@Html.NameOf(m => m.CustomSteps[customStepIndex].CustomStep)" />
|
||||||
<input type="checkbox" value="true" name="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)" id="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)" />
|
<input type="checkbox" value="true" name="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)" id="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)" />
|
||||||
<label class="forcheckbox" for="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)">@Model.CustomSteps[customStepIndex].CustomStep.CamelFriendly()</label>
|
<label class="forcheckbox" for="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)">@Model.CustomSteps[customStepIndex].CustomStep.CamelFriendly()</label>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
</ol>
|
</ol>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button type="submit" class="primaryAction">@T("Export")</button>
|
<button type="submit" class="primaryAction">@T("Export")</button>
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,57 @@
|
|||||||
<table>
|
@model Orchard.ImportExport.ViewModels.DataExportStepViewModel
|
||||||
<thead>
|
@{
|
||||||
|
Style.Include("exportstep-data.css");
|
||||||
</thead>
|
}
|
||||||
</table>
|
<div>
|
||||||
|
<table class="items">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>@T("Content Type")</th>
|
||||||
|
<th>@T("Schema")</th>
|
||||||
|
<th>@T("Data")</th>
|
||||||
|
<th>@T("Both")</th>
|
||||||
|
</tr>
|
||||||
|
<tr class="sub">
|
||||||
|
<th> </th>
|
||||||
|
<th><input type="checkbox"/></th>
|
||||||
|
<th><input type="checkbox"/></th>
|
||||||
|
<th><input type="checkbox"/></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@{ var contentTypeIndex = 0;}
|
||||||
|
@foreach (var contentType in Model.ContentTypes) {
|
||||||
|
<tr>
|
||||||
|
<td>@contentType.DisplayName</td>
|
||||||
|
<td>
|
||||||
|
<input type="hidden" name="@Html.NameFor(m => m.ContentTypes[contentTypeIndex].Name)" value="@Model.ContentTypes[contentTypeIndex].Name"/>
|
||||||
|
<input type="checkbox" name="@Html.NameFor(m => m.ContentTypes[contentTypeIndex].ExportSchema)" value="true"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" name="@Html.NameFor(m => m.ContentTypes[contentTypeIndex].ExportData)" value="true"/>
|
||||||
|
</td>
|
||||||
|
<td><input type="checkbox"/></td>
|
||||||
|
</tr>
|
||||||
|
contentTypeIndex++;
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
@Html.Hint(T("Choose the types to include in the export file"))
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.ImportBatchSize, T("Batch Size"))
|
||||||
|
@Html.TextBoxFor(m => m.ImportBatchSize, new { @class = "text small" })
|
||||||
|
@Html.Hint(T("The batch size to use when importing the data. Leave empty to disable batched imports."))
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>@T("Version History")</p>
|
||||||
|
@Html.RadioButtonFor(m => m.VersionHistoryOptions, "Published", new { id = "Published", Checked = "Checked" })
|
||||||
|
<label for="Published" class="forcheckbox">@T("Only Published Versions")</label>
|
||||||
|
<br />
|
||||||
|
@Html.RadioButtonFor(m => m.VersionHistoryOptions, "Draft", new { id = "Draft" })
|
||||||
|
<label for="Draft" class="forcheckbox">@T("Only Drafts")</label>
|
||||||
|
<br />
|
||||||
|
@Html.RadioButtonFor(m => m.VersionHistoryOptions, "Latest", new { id = "Latest" })
|
||||||
|
<label for="Latest" class="forcheckbox">@T("Latest Versions")</label>
|
||||||
|
</div>
|
@@ -0,0 +1,31 @@
|
|||||||
|
@model Orchard.ImportExport.ViewModels.SetupRecipeStepViewModel
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.RecipeName, T("Name"))
|
||||||
|
@Html.TextBoxFor(m => m.RecipeName, new { @class = "text medium" })
|
||||||
|
@Html.Hint(T("Optionally provide a name for the setup recipe."))
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.RecipeDescription, T("Description"))
|
||||||
|
@Html.TextBoxFor(m => m.RecipeDescription, new {@class = "text large"})
|
||||||
|
@Html.Hint(T("Optionally provide a description for the setup recipe."))
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.RecipeAuthor, T("Author"))
|
||||||
|
@Html.TextBoxFor(m => m.RecipeAuthor, new { @class = "text large" })
|
||||||
|
@Html.Hint(T("Optionally provide the name of the author for the setup recipe."))
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.RecipeWebsite, T("Website"))
|
||||||
|
@Html.TextBoxFor(m => m.RecipeWebsite, new { @class = "text large" })
|
||||||
|
@Html.Hint(T("Optionally provide a website URL for the setup recipe."))
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.RecipeTags, T("Tags"))
|
||||||
|
@Html.TextBoxFor(m => m.RecipeTags, new { @class = "text large" })
|
||||||
|
@Html.Hint(T("Optionally provide tags for the setup recipe."))
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.RecipeVersion, T("Version"))
|
||||||
|
@Html.TextBoxFor(m => m.RecipeVersion, new { @class = "text small" })
|
||||||
|
@Html.Hint(T("Optionally provide a version for the setup recipe."))
|
||||||
|
</div>
|
@@ -0,0 +1,2 @@
|
|||||||
|
@model Orchard.ImportExport.ViewModels.SiteSettingsStepViewModel
|
||||||
|
@Html.Hint(T("Please verify that you are not exporting confidential information, such as passwords or application keys."))
|
Reference in New Issue
Block a user