-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Content cloning and translation #6630
Conversation
Tested and works. I need to review if we could use ILocalizableAspect in some places. |
Going forward, I've set every content types to be listable in Orchard to see if it could uncover missing use cases. Here is what can/cannot be cloned :
You get the idea... there's probably more but I think this PR replaces what was already there and it does'nt break anything. |
Merge conflict ... sorry |
0dae243
to
58323ff
Compare
Rebased |
And a squash would be appreciated too. @Skrypt how did you tests go with this change? |
Give me some time I'll test this soon after I get my cup of coffee. |
@@ -35,7 +35,7 @@ public class BooleanFieldDriver : ContentFieldDriver<BooleanField> { | |||
|
|||
protected override DriverResult Editor(ContentPart part, BooleanField field, dynamic shapeHelper) { | |||
// if the content item is new, assign the default value | |||
if(!part.HasDraft() && !part.HasPublished()) { | |||
if(!field.Value.HasValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Working on field drivers, i noticed that with the boolean field you can use a neutral option in settings, e.g Maybe
. So, if you select Maybe
, then !field.Value.HasValue
will be true without meaning it's a new content item. This because here null is considered as a valid value.
If, for another reason, you still need to change this test, i think we can find the right one.
Best
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, need to find another way to initialize whith default value without overriding the cloned one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works "and tested" :
protected override DriverResult Editor(ContentPart part, BooleanField field, dynamic shapeHelper) {
string action = HttpContext.Current.Request.RequestContext.RouteData.Values["action"].ToString().ToLowerInvariant();
// if the content item is new, assign the default value
if (action == "create") {
var settings = field.PartFieldDefinition.Settings.GetModel<BooleanFieldSettings>();
field.Value = settings.DefaultValue;
}
return ContentShape("Fields_Boolean_Edit", GetDifferentiator(field, part),
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: field, Prefix: GetPrefix(field, part)));
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't seen the details of cloning, but, as i understand, we can't use the previous test because we work on a content item that is being cloning, and therefore has a draft or is published...
So, after a 1st look, and because i think this method is called only during a regular web request, your code looks good for me. Maybe we need a null check on the action string?
Best
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main problem here is that there is no way to know if the Boolean Field has been assigned a null value "explicitly"... since a null value is a null ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, i was talking about the action
string, and, indeed, here the null check is useless ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to adapt my code to use IHttpContextAccessor instead of HttpContext wich is pre .NET 3.5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, by injecting an IHttpContextAccessor
and using _httpContextAccessor.Current()
. Then, one rule is to also use this mvc extension if (!httpContext.IsBackgroundContext())
when it doesn't make sense to do something, e.g in a background task. But i think that the Editor()
method will never be executed in the background (unlike the Display()
method). Anyway, in the background an empty (but not null) route data would be returned.
So, not tested but i propose something like the following:
Note: maybe good to create a route extension GetActionName()
as already done for GetAreaName()
.
...
var routeData = _httpContextAccessor.Current().Request.RequestContext.RouteData;
object action;
if (routeData.Values.TryGetValue("action", out action)) {
var actionString = action as string;
// if the content item is new, assign the default value
if (!String.IsNullOrEmpty(actionString) && actionString.Equals("create", StringComparison.OrdinalIgnoreCase)) {
var settings = field.PartFieldDefinition.Settings.GetModel<BooleanFieldSettings>();
field.Value = settings.DefaultValue;
}
}
...
About my line note on BooleanFieldDriver.cs, without disturbing you, if you can tell me why you have to change this test, i could try to find a compromise. Best. |
@sebastienros All the tests I've made have the same results as before. |
It is GTG if we fix the small bug with the boolean field. |
I think we should also provide unit tests on this one. At least one for making sure that the identityPart generates a new GUID. |
I think there is an issue with all fields (not bound to cloning) : Do you agree with that ? |
I agree. Though, it is not a ship blocker for this PR. If we need to implement such thing, let's propose it in another issue. Else we are going East and West with this one. |
But I think the PR won't be accepted with a condition on Action name... |
This is a grey zone. Implement it and let's summon @sebastienros |
I assume either a default value should be implemented for Editor only, or in a Content Handler when an item is created. |
Well, it depends what we think of the default value. Like the first value that is shown to the user, but the user could delete it. Or the value to assign when there is no value, on save. |
Not everyone will want their TextboxField to have forced default values saved when an empty string is submitted by the form. I think that the default values should be only proposed in that scenario. Though, if it comes from a background task it should force default values. So IMO it's kind of both. |
Indeed, as @sebastienros said there could be different meanings around default values. Initial value on creation, predefined value on editing, default value on submission... But, in our context, note that currently most of the fields don't use a default value on first editing / creation. As i remember, only the enum and bool fields use it. And the boolean field is a special case where null can be a valid value (if the neutral option is set). I agree with what @TFleury said about content handler and lazy fields. Or, maybe, by adding a new field driver "event" for this purpose, as done for cloning, through That said, not tested but isn't there any solution by using, in the Best. |
Here is the result of my search on how Drupal does it. |
@sebastienros @TFleury @Skrypt Just tried, great feature! Didn't test everithing because Jasmin did it. So, if you can check this simple solution in
Best. |
2 questions
|
Right now the clone feature opens up a "Create new" form and sets the owner to the current user. The new content item should have then a new IdentityPart since it has the same logic than "Create". So it is done on the created item (Parts). Though we would need to assert that if this is done by a background task that it also changes the current owner properly. |
@sebastienros which is the best (acceptable) way to solve our problem with default value handling ?
|
From a discussion with @sebastienros
I think Fields should mimic what we can do with Fields in SQL Server. So, my opinion is that default values should only be proposed. Fields can be attached to a content type even when this content type has content items. If we set a default value to this new field, we don't need to batch update all the content items since the default value can be retrieved by the Field properties. Also, if we export/import those content items, and we decide to ommit this field in the import, I don't think we should then set this field to it's default value. to continue ... |
Not sure that all we can discuss around default values should block this PR. I thought cloning was not directly concerned by this, and, here, we just needed to fix a specific case with the boolean field editor. About default values we have to separate contexts where different values can be used or not. So, here, for clarity, just more infos on the current implementation related to default form values for field editing.
Anyway, regarding default values, the only problem i see here is with the boolean field because null can be a valid value (Neutral), so, when 2. is used we can't detect if it has no value as in a 1st edition. Maybe we can first find a compromise for this (see above the list suggested by Thierry). Best. |
Cloned content has same culture as original by default
This reverts commit 54394d8.
bedc0fb
to
32cdbf9
Compare
Just updated my PR. |
Will merge as someone says it works on dev. |
This PR waiting on me to re-re-test it ? 😉 |
Let's watch Orchard burning ... |
Oops ! it did not close the thousands issues related to it 😄 |
In light of #7352 I pulled the latest commit related to cloning into a (local) branch off 1.10.x. The commit is 87a3948 |
@MatteoPiovanelli-Laser thank you for your comments, I tried to answer all of them. |
Initial PR : #6540
This PR adds new clone handling to replace export/import logic, and also allow translating a clone of the master content item.
It fixes : #5535, #5089, #4983, #4970, #4538, #5031