mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-26 20:16:15 +08:00
Content cloning and translation
Fixes #5535, #5089, #4983, #4970, #4538, #5031
This commit is contained in:
committed by
Sébastien Ros
parent
147b4fd05b
commit
87a394854d
@@ -11,6 +11,7 @@ using Orchard.Core.Common.ViewModels;
|
||||
using Orchard.Services;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
|
||||
namespace Orchard.Core.Common.Drivers {
|
||||
public class BodyPartDriver : ContentPartDriver<BodyPart> {
|
||||
@@ -75,6 +76,10 @@ namespace Orchard.Core.Common.Drivers {
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("Text", part.Text);
|
||||
}
|
||||
|
||||
protected override void Cloning(BodyPart originalPart, BodyPart clonePart, CloneContentContext context) {
|
||||
clonePart.Text = originalPart.Text;
|
||||
}
|
||||
|
||||
private static BodyEditorViewModel BuildEditorViewModel(BodyPart part,RequestContext requestContext) {
|
||||
return new BodyEditorViewModel {
|
||||
BodyPart = part,
|
||||
|
||||
@@ -123,5 +123,9 @@ namespace Orchard.Core.Common.Drivers {
|
||||
.SetAttributeValue("ModifiedUtc", XmlConvert.ToString(part.ModifiedUtc.Value, XmlDateTimeSerializationMode.Utc));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Cloning(CommonPart originalPart, CommonPart clonePart, CloneContentContext context) {
|
||||
clonePart.Container = originalPart.Container;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,10 @@ namespace Orchard.Core.Common.Drivers {
|
||||
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Text", field.Value);
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, TextField originalField, TextField cloneField, CloneContentContext context) {
|
||||
cloneField.Value = originalField.Value;
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(string), T("Value"), T("The text associated with the field."))
|
||||
|
||||
@@ -383,26 +383,24 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Clone(int id, string returnUrl) {
|
||||
var contentItem = _contentManager.GetLatest(id);
|
||||
public ActionResult Clone(int id) {
|
||||
var originalContentItem = _contentManager.GetLatest(id);
|
||||
|
||||
if (contentItem == null)
|
||||
return HttpNotFound();
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditContent, contentItem, T("Couldn't clone content")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.ViewContent, originalContentItem, T("Couldn't open original content")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
try {
|
||||
Services.ContentManager.Clone(contentItem);
|
||||
}
|
||||
catch (InvalidOperationException) {
|
||||
Services.Notifier.Warning(T("Could not clone the content item."));
|
||||
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
|
||||
}
|
||||
// pass a dummy content to the authorization check to check for "own" variations
|
||||
var dummyContent = _contentManager.New(originalContentItem.ContentType);
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditContent, dummyContent, T("Couldn't create clone content")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var cloneContentItem = _contentManager.Clone(originalContentItem);
|
||||
|
||||
Services.Notifier.Success(T("Successfully cloned. The clone was saved as a draft."));
|
||||
|
||||
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
|
||||
var adminRouteValues = _contentManager.GetItemMetadata(cloneContentItem).AdminRouteValues;
|
||||
return RedirectToRoute(adminRouteValues);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
@using Orchard.ContentManagement
|
||||
@using Orchard.Core.Contents
|
||||
@using Orchard.Utility.Extensions
|
||||
@{
|
||||
ContentPart contentPart = Model.ContentPart;
|
||||
}
|
||||
@if (Authorizer.Authorize(Permissions.EditContent, contentPart)) {
|
||||
<a href="@Url.Action("Clone", "Admin", new { Id = Model.ContentItem.Id, ReturnUrl = Request.ToUrlString(), Area = "Contents" })" itemprop="UnsafeUrl">@T("Clone")</a>
|
||||
<a href="@Url.Action("Clone", "Admin", new { Id = Model.ContentItem.Id, Area = "Contents" })" itemprop="UnsafeUrl">@T("Clone")</a>
|
||||
@T(" | ")
|
||||
}
|
||||
@@ -52,5 +52,9 @@ namespace Orchard.Core.Title.Drivers {
|
||||
protected override void Exporting(TitlePart part, ExportContentContext context) {
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("Title", part.Title);
|
||||
}
|
||||
|
||||
protected override void Cloning(TitlePart originalPart, TitlePart clonePart, CloneContentContext context) {
|
||||
clonePart.Title = originalPart.Title;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using Orchard.Comments.Settings;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
|
||||
namespace Orchard.Comments.Drivers {
|
||||
public class CommentsPartDriver : ContentPartDriver<CommentsPart> {
|
||||
@@ -110,7 +111,7 @@ namespace Orchard.Comments.Drivers {
|
||||
return Editor(part, shapeHelper);
|
||||
}
|
||||
|
||||
protected override void Importing(CommentsPart part, ContentManagement.Handlers.ImportContentContext context) {
|
||||
protected override void Importing(CommentsPart part, ImportContentContext context) {
|
||||
// Don't do anything if the tag is not specified.
|
||||
if (context.Data.Element(part.PartDefinition.Name) == null) {
|
||||
return;
|
||||
@@ -129,10 +130,16 @@ namespace Orchard.Comments.Drivers {
|
||||
);
|
||||
}
|
||||
|
||||
protected override void Exporting(CommentsPart part, ContentManagement.Handlers.ExportContentContext context) {
|
||||
protected override void Exporting(CommentsPart part, ExportContentContext context) {
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("CommentsShown", part.CommentsShown);
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("CommentsActive", part.CommentsActive);
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("ThreadedComments", part.ThreadedComments);
|
||||
}
|
||||
|
||||
protected override void Cloning(CommentsPart originalPart, CommentsPart clonePart, CloneContentContext context) {
|
||||
clonePart.CommentsShown = originalPart.CommentsShown;
|
||||
clonePart.CommentsActive = originalPart.CommentsActive;
|
||||
// ThreadedComments will be overrided with settings default
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentPicker.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Utility.Extensions;
|
||||
using Orchard.ContentPicker.Fields;
|
||||
|
||||
namespace Orchard.ContentPicker.Drivers {
|
||||
public class ContentPickerFieldDriver : ContentFieldDriver<Fields.ContentPickerField> {
|
||||
@@ -98,6 +99,10 @@ namespace Orchard.ContentPicker.Drivers {
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, ContentPickerField originalField, ContentPickerField cloneField, CloneContentContext context) {
|
||||
cloneField.Ids = originalField.Ids;
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(string), T("Ids"), T("A formatted list of the ids, e.g., {1},{42}"));
|
||||
|
||||
@@ -66,6 +66,10 @@ namespace Orchard.Fields.Drivers {
|
||||
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value);
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, BooleanField originalField, BooleanField cloneField, CloneContentContext context) {
|
||||
cloneField.Value = originalField.Value;
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(Boolean), T("Value"), T("The boolean value of the field."))
|
||||
|
||||
@@ -174,6 +174,10 @@ namespace Orchard.Fields.Drivers {
|
||||
context.Element(GetPrefix(field, part)).SetAttributeValue("Value", XmlConvert.ToString(value, XmlDateTimeSerializationMode.Utc));
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, DateTimeField originalField, DateTimeField cloneField, CloneContentContext context) {
|
||||
cloneField.DateTime = originalField.DateTime;
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(DateTime), T("Value"), T("The date and time value of the field."))
|
||||
|
||||
@@ -67,6 +67,10 @@ namespace Orchard.Fields.Drivers {
|
||||
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value);
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, EnumerationField originalField, EnumerationField cloneField, CloneContentContext context) {
|
||||
cloneField.Value = originalField.Value;
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(string), T("Value"), T("The selected values of the field."))
|
||||
|
||||
@@ -65,6 +65,10 @@ namespace Orchard.Fields.Drivers {
|
||||
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value);
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, InputField originalField, InputField cloneField, CloneContentContext context) {
|
||||
cloneField.Value = originalField.Value;
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(string), T("Value"), T("The value of the field."))
|
||||
|
||||
@@ -78,6 +78,12 @@ namespace Orchard.Fields.Drivers {
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, LinkField originalField, LinkField cloneField, CloneContentContext context) {
|
||||
cloneField.Text = originalField.Text;
|
||||
cloneField.Value = originalField.Value;
|
||||
cloneField.Target = originalField.Target;
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member("Text", typeof(string), T("Text"), T("The text of the link."))
|
||||
|
||||
@@ -110,6 +110,10 @@ namespace Orchard.Fields.Drivers {
|
||||
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, NumericField originalField, NumericField cloneField, CloneContentContext context) {
|
||||
cloneField.Value = originalField.Value;
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(decimal), T("Value"), T("The value of the field."))
|
||||
|
||||
@@ -213,5 +213,10 @@ namespace Orchard.Layouts.Drivers {
|
||||
var layoutDataString = JsonConvert.SerializeObject(layoutData, Formatting.None);
|
||||
return layoutDataString;
|
||||
}
|
||||
|
||||
protected override void Cloning(LayoutPart originalPart, LayoutPart clonePart, CloneContentContext context) {
|
||||
clonePart.LayoutData = originalPart.LayoutData;
|
||||
clonePart.TemplateId = originalPart.TemplateId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,29 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Contents.Settings;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Contents;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Localization.Models;
|
||||
using Orchard.Localization.Services;
|
||||
using Orchard.Localization.ViewModels;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.UI.Notify;
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Orchard.Localization.Controllers {
|
||||
namespace Orchard.Localization.Controllers
|
||||
{
|
||||
[ValidateInput(false)]
|
||||
public class AdminController : Controller, IUpdateModel {
|
||||
public class AdminController : Controller {
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly ICultureManager _cultureManager;
|
||||
|
||||
public AdminController(
|
||||
IOrchardServices orchardServices,
|
||||
IContentManager contentManager,
|
||||
ILocalizationService localizationService,
|
||||
ICultureManager cultureManager,
|
||||
IShapeFactory shapeFactory) {
|
||||
_contentManager = contentManager;
|
||||
_localizationService = localizationService;
|
||||
_cultureManager = cultureManager;
|
||||
T = NullLocalizer.Instance;
|
||||
Services = orchardServices;
|
||||
Shape = shapeFactory;
|
||||
@@ -32,16 +33,20 @@ namespace Orchard.Localization.Controllers {
|
||||
public Localizer T { get; set; }
|
||||
public IOrchardServices Services { get; set; }
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Translate(int id, string to) {
|
||||
var masterContentItem = _contentManager.Get(id, VersionOptions.Latest);
|
||||
if (masterContentItem == null)
|
||||
return HttpNotFound();
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.ViewContent, masterContentItem, T("Couldn't open original content")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var masterLocalizationPart = masterContentItem.As<LocalizationPart>();
|
||||
if (masterLocalizationPart == null)
|
||||
return HttpNotFound();
|
||||
|
||||
// Check is current item stll exists, and redirect.
|
||||
// Check if current item still exists, and redirect.
|
||||
var existingTranslation = _localizationService.GetLocalizedContentItem(masterContentItem, to);
|
||||
if (existingTranslation != null) {
|
||||
var existingTranslationMetadata = _contentManager.GetItemMetadata(existingTranslation);
|
||||
@@ -50,76 +55,24 @@ namespace Orchard.Localization.Controllers {
|
||||
existingTranslationMetadata.EditorRouteValues);
|
||||
}
|
||||
|
||||
var contentItemTranslation = _contentManager.New<LocalizationPart>(masterContentItem.ContentType);
|
||||
contentItemTranslation.MasterContentItem = masterContentItem;
|
||||
// pass a dummy content to the authorization check to check for "own" variations
|
||||
var dummyContent = _contentManager.New(masterContentItem.ContentType);
|
||||
|
||||
var content = _contentManager.BuildEditor(contentItemTranslation);
|
||||
|
||||
return View(content);
|
||||
}
|
||||
var contentItemTranslation = _contentManager.Clone(masterContentItem);
|
||||
|
||||
[HttpPost, ActionName("Translate")]
|
||||
[FormValueRequired("submit.Save")]
|
||||
public ActionResult TranslatePOST(int id) {
|
||||
return TranslatePOST(id, contentItem => {
|
||||
if (!contentItem.Has<IPublishingControlAspect>() && !contentItem.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable)
|
||||
Services.ContentManager.Publish(contentItem);
|
||||
});
|
||||
}
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditContent, contentItemTranslation, T("Couldn't create translated content")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
[HttpPost, ActionName("Translate")]
|
||||
[FormValueRequired("submit.Publish")]
|
||||
public ActionResult TranslateAndPublishPOST(int id) {
|
||||
return TranslatePOST(id, contentItem => Services.ContentManager.Publish(contentItem));
|
||||
}
|
||||
|
||||
public ActionResult TranslatePOST(int id, Action<ContentItem> conditionallyPublish) {
|
||||
var masterContentItem = _contentManager.Get(id, VersionOptions.Latest);
|
||||
if (masterContentItem == null)
|
||||
return HttpNotFound();
|
||||
|
||||
var masterLocalizationPart = masterContentItem.As<LocalizationPart>();
|
||||
if (masterLocalizationPart == null)
|
||||
return HttpNotFound();
|
||||
|
||||
var model = new EditLocalizationViewModel();
|
||||
TryUpdateModel(model, "Localization");
|
||||
|
||||
var existingTranslation = _localizationService.GetLocalizedContentItem(masterContentItem, model.SelectedCulture);
|
||||
if (existingTranslation != null) {
|
||||
var existingTranslationMetadata = _contentManager.GetItemMetadata(existingTranslation);
|
||||
return RedirectToAction(
|
||||
Convert.ToString(existingTranslationMetadata.EditorRouteValues["action"]),
|
||||
existingTranslationMetadata.EditorRouteValues);
|
||||
var localizationPart = contentItemTranslation.As<LocalizationPart>();
|
||||
if(localizationPart != null) {
|
||||
localizationPart.MasterContentItem = masterContentItem;
|
||||
localizationPart.Culture = string.IsNullOrWhiteSpace(to) ? null : _cultureManager.GetCultureByName(to);
|
||||
}
|
||||
|
||||
var contentItemTranslation = _contentManager
|
||||
.Create<LocalizationPart>(masterContentItem.ContentType, VersionOptions.Draft, part => {
|
||||
part.MasterContentItem = masterContentItem;
|
||||
});
|
||||
Services.Notifier.Success(T("Successfully cloned. The translated content was saved as a draft."));
|
||||
|
||||
var content = _contentManager.UpdateEditor(contentItemTranslation, this);
|
||||
|
||||
if (!ModelState.IsValid) {
|
||||
Services.TransactionManager.Cancel();
|
||||
|
||||
return View(content);
|
||||
}
|
||||
|
||||
conditionallyPublish(contentItemTranslation.ContentItem);
|
||||
|
||||
Services.Notifier.Success(T("Created content item translation."));
|
||||
|
||||
var metadata = _contentManager.GetItemMetadata(contentItemTranslation);
|
||||
return RedirectToAction(Convert.ToString(metadata.EditorRouteValues["action"]), metadata.EditorRouteValues);
|
||||
}
|
||||
|
||||
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());
|
||||
var adminRouteValues = _contentManager.GetItemMetadata(contentItemTranslation).AdminRouteValues;
|
||||
return RedirectToRoute(adminRouteValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Localization.Models;
|
||||
using Orchard.Localization.Services;
|
||||
using Orchard.Localization.ViewModels;
|
||||
@@ -89,25 +90,23 @@ namespace Orchard.Localization.Drivers {
|
||||
|
||||
private IEnumerable<LocalizationPart> GetDisplayLocalizations(LocalizationPart part, VersionOptions versionOptions) {
|
||||
return _localizationService.GetLocalizations(part.ContentItem, versionOptions)
|
||||
.Where(c => c.Culture != null)
|
||||
.Select(c => {
|
||||
var localized = c.ContentItem.As<LocalizationPart>();
|
||||
if (localized.Culture == null)
|
||||
localized.Culture = _cultureManager.GetCultureByName(_cultureManager.GetSiteCulture());
|
||||
return c;
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
private IEnumerable<LocalizationPart> GetEditorLocalizations(LocalizationPart part) {
|
||||
return _localizationService.GetLocalizations(part.ContentItem, VersionOptions.Latest)
|
||||
.Where(c => c.Culture != null)
|
||||
.Select(c => {
|
||||
var localized = c.ContentItem.As<LocalizationPart>();
|
||||
if (localized.Culture == null)
|
||||
localized.Culture = _cultureManager.GetCultureByName(_cultureManager.GetSiteCulture());
|
||||
return c;
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
protected override void Importing(LocalizationPart part, ContentManagement.Handlers.ImportContentContext context) {
|
||||
protected override void Importing(LocalizationPart part, ImportContentContext context) {
|
||||
// Don't do anything if the tag is not specified.
|
||||
if (context.Data.Element(part.PartDefinition.Name) == null) {
|
||||
return;
|
||||
@@ -131,7 +130,7 @@ namespace Orchard.Localization.Drivers {
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Exporting(LocalizationPart part, ContentManagement.Handlers.ExportContentContext context) {
|
||||
protected override void Exporting(LocalizationPart part, ExportContentContext context) {
|
||||
if (part.MasterContentItem != null) {
|
||||
var masterContentItemIdentity = _contentManager.GetItemMetadata(part.MasterContentItem).Identity;
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("MasterContentItem", masterContentItemIdentity.ToString());
|
||||
@@ -141,5 +140,9 @@ namespace Orchard.Localization.Drivers {
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("Culture", part.Culture.Culture);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Cloned(LocalizationPart originalPart, LocalizationPart clonePart, CloneContentContext context) {
|
||||
clonePart.Culture = originalPart.Culture;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace Orchard.Localization.Handlers {
|
||||
|
||||
protected static void PropertySetHandlers(ActivatedContentContext context, LocalizationPart localizationPart) {
|
||||
localizationPart.CultureField.Setter(cultureRecord => {
|
||||
localizationPart.Record.CultureId = cultureRecord.Id;
|
||||
localizationPart.Record.CultureId = cultureRecord != null ? cultureRecord.Id : 0;
|
||||
return cultureRecord;
|
||||
});
|
||||
|
||||
|
||||
@@ -135,9 +135,6 @@
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Admin\Translate.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\EditorTemplates\Parts\Localization.ContentTranslations.Edit.cshtml" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
@{
|
||||
Layout.Title = T("Translate Content").ToString();
|
||||
}
|
||||
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
@Html.ValidationSummary()
|
||||
@Display(Model)
|
||||
}
|
||||
@@ -6,58 +6,60 @@
|
||||
<fieldset class="localization culture-selection">
|
||||
<label for="@Html.FieldIdFor(m => m.SelectedCulture)">@T("Content Localization")</label>
|
||||
<div>
|
||||
@*Brand new content item*@
|
||||
@if (Model.ContentItem.ContentItem.Id == 0) {
|
||||
if (Model.MasterContentItem == null) {
|
||||
@T("This is the <em>{0}</em> variation of the content",
|
||||
BuildSelectedCultureList(
|
||||
Html.FieldIdFor(m => m.SelectedCulture),
|
||||
Html.FieldNameFor(m => m.SelectedCulture),
|
||||
Model.MissingCultures,
|
||||
Model.SelectedCulture))
|
||||
@if (!string.IsNullOrEmpty(Model.SelectedCulture))
|
||||
{
|
||||
@T("This is the <em>{0}</em> variation of the content",
|
||||
Html.Encode(Model.SelectedCulture))
|
||||
|
||||
if (Model.ContentLocalizations.Localizations.Any())
|
||||
{
|
||||
<dl class="content-localization">
|
||||
<dt>@T("Other translations:")</dt>
|
||||
<dd class="content-localizations">
|
||||
@Html.UnorderedList(Model.ContentLocalizations.Localizations, (c, i) =>
|
||||
Html.ItemEditLink(c.Culture.Culture, c), "localizations")
|
||||
</dd>
|
||||
</dl>
|
||||
}
|
||||
else {
|
||||
@T("This is the <em>{0}</em> variation of {1}",
|
||||
|
||||
if (Model.MissingCultures.Any())
|
||||
{
|
||||
var contentItemId = Model.MasterContentItem != null ? Model.MasterContentItem.Id : Model.ContentItem.Id;
|
||||
|
||||
<div class="add-localization">@Html.ActionLink(T("+ New translation").Text, "Translate", "Admin", new { area = "Orchard.Localization", id = contentItemId }, new { itemprop = "UnsafeUrl" })</div>
|
||||
}
|
||||
|
||||
@Html.Hidden(Html.FieldNameFor(m => m.SelectedCulture), Model.SelectedCulture)
|
||||
}
|
||||
else if (Model.MasterContentItem != null)
|
||||
{
|
||||
@T("This is the <em>{0}</em> variation of {1}",
|
||||
BuildSelectedCultureList(
|
||||
Html.FieldIdFor(m => m.SelectedCulture),
|
||||
Html.FieldNameFor(m => m.SelectedCulture),
|
||||
Model.MissingCultures,
|
||||
Model.SelectedCulture),
|
||||
Html.ItemEditLink(Model.MasterContentItem))
|
||||
|
||||
if (Model.ContentLocalizations.Localizations.Any())
|
||||
{
|
||||
<dl class="content-localization">
|
||||
<dt>@T("Other translations:")</dt>
|
||||
<dd class="content-localizations">
|
||||
@Html.UnorderedList(Model.ContentLocalizations.Localizations, (c, i) =>
|
||||
Html.ItemEditLink(c.Culture.Culture, c), "localizations")
|
||||
</dd>
|
||||
</dl>
|
||||
}
|
||||
}
|
||||
|
||||
@if (Model.ContentItem.ContentItem.Id > 0) {
|
||||
if (string.IsNullOrEmpty(Model.SelectedCulture)) {
|
||||
@T("This content currently has no culture associated to it, please select a culture to associate to this piece of content: {0}",
|
||||
BuildSelectedCultureList(
|
||||
Html.FieldIdFor(m => m.SelectedCulture),
|
||||
Html.FieldNameFor(m => m.SelectedCulture),
|
||||
Model.MissingCultures,
|
||||
Model.SelectedCulture))
|
||||
}
|
||||
else {
|
||||
@T("This is the <em>{0}</em> variation of the content",
|
||||
Html.Encode(Model.SelectedCulture))
|
||||
|
||||
if (Model.ContentLocalizations.Localizations.Any()) {
|
||||
<dl class="content-localization">
|
||||
<dt>@T("Other translations:")</dt>
|
||||
<dd class="content-localizations">
|
||||
@Html.UnorderedList(Model.ContentLocalizations.Localizations, (c, i) =>
|
||||
Html.ItemEditLink(c.Culture.Culture, c), "localizations")
|
||||
</dd>
|
||||
</dl>
|
||||
}
|
||||
|
||||
if (Model.MissingCultures.Any()) {
|
||||
var contentItemId = Model.MasterContentItem != null ? Model.MasterContentItem.Id : Model.ContentItem.Id;
|
||||
|
||||
<div class="add-localization">@Html.ActionLink(T("+ New translation").Text, "Translate", "Admin", new {area = "Orchard.Localization", id = contentItemId}, null)</div>
|
||||
}
|
||||
|
||||
@Html.Hidden(Html.FieldNameFor(m => m.SelectedCulture), Model.SelectedCulture)
|
||||
}
|
||||
else
|
||||
{
|
||||
@T("This is the <em>{0}</em> variation of the content",
|
||||
BuildSelectedCultureList(
|
||||
Html.FieldIdFor(m => m.SelectedCulture),
|
||||
Html.FieldNameFor(m => m.SelectedCulture),
|
||||
Model.MissingCultures,
|
||||
Model.SelectedCulture))
|
||||
}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
@@ -16,7 +16,7 @@ var localizationLinks = Html.UnorderedList(localizations, (c, i) => Html.ItemEdi
|
||||
}
|
||||
@if (Model.Culture != null && !((IEnumerable<string>)Model.SiteCultures).All(c => c == Model.Culture || localizations.Any(l => c == l.Culture.Culture)))
|
||||
{
|
||||
<div class="add-localization">@Html.ActionLink(T("+ New translation").Text, "Translate", "Admin", new { area = "Orchard.Localization", id = Model.Id }, null)</div>
|
||||
<div class="add-localization">@Html.ActionLink(T("+ New translation").Text, "Translate", "Admin", new { area = "Orchard.Localization", id = Model.Id }, new { itemprop = "UnsafeUrl" })</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.MediaLibrary.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Utility.Extensions;
|
||||
using Orchard.MediaLibrary.Fields;
|
||||
|
||||
namespace Orchard.MediaLibrary.Drivers {
|
||||
public class MediaLibraryPickerFieldDriver : ContentFieldDriver<Fields.MediaLibraryPickerField> {
|
||||
@@ -95,6 +96,10 @@ namespace Orchard.MediaLibrary.Drivers {
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, MediaLibraryPickerField originalField, MediaLibraryPickerField cloneField, CloneContentContext context) {
|
||||
cloneField.Ids = originalField.Ids;
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(string), T("Ids"), T("A formatted list of the ids, e.g., {1},{42}"));
|
||||
|
||||
@@ -341,6 +341,17 @@ namespace Orchard.Projections.Drivers {
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Cloning(ProjectionPart originalPart, ProjectionPart clonePart, CloneContentContext context) {
|
||||
clonePart.Record.Items = originalPart.Record.Items;
|
||||
clonePart.Record.ItemsPerPage = originalPart.Record.ItemsPerPage;
|
||||
clonePart.Record.Skip = originalPart.Record.Skip;
|
||||
clonePart.Record.PagerSuffix = originalPart.Record.PagerSuffix;
|
||||
clonePart.Record.MaxItems = originalPart.Record.MaxItems;
|
||||
clonePart.Record.DisplayPager = originalPart.Record.DisplayPager;
|
||||
clonePart.Record.QueryPartRecord = originalPart.Record.QueryPartRecord;
|
||||
clonePart.Record.LayoutRecord = originalPart.Record.LayoutRecord;
|
||||
}
|
||||
|
||||
private class ViewDataContainer : IViewDataContainer {
|
||||
public ViewDataDictionary ViewData { get; set; }
|
||||
}
|
||||
|
||||
@@ -89,5 +89,9 @@ namespace Orchard.Tags.Drivers {
|
||||
protected override void Exporting(TagsPart part, ExportContentContext context) {
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("Tags", String.Join(",", part.CurrentTags));
|
||||
}
|
||||
|
||||
protected override void Cloning(TagsPart originalPart, TagsPart clonePart, CloneContentContext context) {
|
||||
clonePart.CurrentTags = originalPart.CurrentTags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,6 +141,10 @@ namespace Orchard.Taxonomies.Drivers {
|
||||
_taxonomyService.UpdateTerms(part.ContentItem, terms.Select(x => x.As<TermPart>()), field.Name);
|
||||
}
|
||||
|
||||
protected override void Cloning(ContentPart part, TaxonomyField originalField, TaxonomyField cloneField, CloneContentContext context) {
|
||||
_taxonomyService.UpdateTerms(context.CloneContentItem, originalField.Terms, cloneField.Name);
|
||||
}
|
||||
|
||||
private TermPart GetOrCreateTerm(TermEntry entry, int taxonomyId, TaxonomyField field) {
|
||||
var term = default(TermPart);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user