Skip to content
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

Support Placement for Field Editor Options #4484

Merged
merged 1 commit into from
Oct 10, 2019
Merged

Conversation

deanmarcussen
Copy link
Member

Fixes #4483

When trying to find placement for a field editor options like TextField_Edit__Color the key in the shape descriptor lookup is expecting TextField_Edit, so this strips the shapeType in the same way that the ShapeAlterationBuilder does when creating the placement alteration.

Maybe fixing something in the wrong place again here though, as placement is a maze :)

@jtketch any thoughts?

…s to support TextField_Edit__Options shape type
@jtkech
Copy link
Member

jtkech commented Oct 6, 2019

I'm lost too ;) I worked on it but a while ago.

Yes, as i remember this delimiter is used to add specificity but not to change the underlying shape type and the related descriptor that will be used, then we can morph the shape type when creating a concrete shape and its final name will be used for rendering if no other alternates are provided.

We use this delimiter e.g for content type but to provide additional alternates, not to morph the shape type. Here we do a shape type morphing in ContentFieldDisplayDriver<TField>.

    protected string GetEditorShapeType(string shapeType, ContentPartFieldDefinition ...)
    {
        var editor = partFieldDefinition.Editor();
        return !String.IsNullOrEmpty(editor)
            ? shapeType + "__" + editor
            : shapeType;
    }

Maybe we could have used _ in place of __ but we would have to change all template views names, and, as said above, seems to be right to keep the same underlying shape type / descriptor.

There is this same kind of code in ShapeTable.cs that uses this delimiter. See in DefaultShapeFactory we pass a shapeType.

(await GetShapeTableAsync()).Descriptors.TryGetValue(shapeType, out shapeDescriptor);

And in ShapeTable.cs we use it as a shapeAlternate to retrieve the binding, and then we use the same delimiter to retrieve the same underlying shapeType and then its descriptor.

    public bool TryGetValue(string shapeAlternate, out ShapeBinding binding)
    {
        ShapeBinding shapeBinding;
        if (_shapeTable.ShapeBindings.TryGetValue(shapeAlternate, out shapeBinding))
        {
            var index = shapeAlternate.IndexOf("__");
            var shapeType = index < 0 ? shapeAlternate : shapeAlternate.Substring(0, index);

            ShapeDescriptor descriptor;
            if (_shapeTable.Descriptors.TryGetValue(shapeType, out descriptor))
            {
                binding = new ShapeBinding
                {
                    ShapeDescriptor = descriptor,
                    BindingName = shapeBinding.BindingName,
                    BindingSource = shapeBinding.BindingSource,
                    BindingAsync = shapeBinding.BindingAsync
                };

                return true;
            }
        }

So, in BaseDisplayManager.FindPlacementImpl seems to be right to use this delimiter in the same way.

LGTM

@ns8482e
Copy link
Contributor

ns8482e commented Oct 8, 2019

@deanmarcussen what shape are you using in placement.json ?
I tried following seems not working for me. It always displays tab regardless of my editor selection.
I only want to show tab in-case of Multiline and I do not want to show tab for Standard/Wysiwyg

  "HtmlField_Edit__Multiline": [
    {
      "place": "Parts#Source:0",
      "contentType": [ "HtmlWidget" ]
    }
  ]

@deanmarcussen
Copy link
Member Author

@ns8482e What I discover when trying this is that when shapes are read into the shape table, and the ShapeAlterationBuilder builds alterations from placement, is that the shape name is HtmlField_Edit, and the __Multiline is stripped, as anything with __ is considered an alteration to a primary shape.

So if you look in the shape table for TextField_Edit, for example you see the primary shape, and approx 8 alterations for the other shapes that are related, i.e. TextField_Edit__Color etc

This PR uses the same logic to remove any __ from the shape during render, when looking for placement for it.

To actually do placement alternations to these shapes you can use placement like this (but only with this PR)

  "TextField_Edit": [
    {
      "place": "Parts#Layout:0",
      "differentiator": "Paragraph-BackgroundColor"
    },
    {
      "place": "Parts#Layout:1",
      "differentiator": "Paragraph-ResponsiveOptions"
    }
  ]

In this case I use the differentiator as it is easier than the contentType matcher to be specific to the shape that I want to place, where Paragraph is the widget content type name, and ResponsiveOptions is the field name

@ns8482e
Copy link
Contributor

ns8482e commented Oct 9, 2019

@deanmarcussen differentiator won't work for me as It's same HtmlField.

Editor type should be part of differentiator

if above line changed to include editor type, I could write as following

"HtmlField_Edit": [
    {
      "place": "Parts#Source:0",
      "differentiator": "HtmlWidget-Content-Multiline" 
    }
  ]

@deanmarcussen
Copy link
Member Author

@ns8482e

I'm not against adding the editor type to the differentiator, but can you explain more.

I'm trying to understand how the same fieldname from the same widget can be rendered with two different editors?

@ns8482e
Copy link
Contributor

ns8482e commented Oct 9, 2019

@deanmarcussen The reason why we should add editor type to the differentiator is that each Field editor provides different user experience and any module can introduce new field editor for a given content field.

Adding the editor type to the differentiator would allows user to experience different look and feel.

Without editor type to the differentiator

Notice that changing editor type has no effect in placement
before-1

placement.json used with this PR

{  
  "HtmlField_Edit": [
    {
      "place": "Parts#Notes:0",
      "differentiator": "Product-Notes"
    }

  ]
}

With editor type to the differentiator

Notice that changing editor type also has effect in placement
after-1 (1)

placement.json used with this PR and with editor type added to the differentiator

{  
  "HtmlField_Edit": [
    {
      "place": "Parts#Product Details:0",
      "differentiator": "Product-Description-Wysiwyg"
    },
    {
      "place": "Parts#Product Specification:0",
      "differentiator": "Product-Specification-Wysiwyg"
    },    
    {
      "place": "Parts#Notes:0",
      "differentiator": "Product-Notes-Multiline"
    }
  ]
}

Only drawback is - for Notes to be displayed always on "Notes" tab, I have to explicitly define placement for each editor type. Here I have defined only "Multiline" editor to be placed on "Notes" tab hence, changing it to "Wysiwyg" moved it to content tab

@deanmarcussen
Copy link
Member Author

@ns8482e ok I see where you're coming from, but the drawback you mention about the having to specify the editor is the problem for me.

For me, without is enough.

{  
  "HtmlField_Edit": [
    {
      "place": "Parts#Product Details:0",
      "differentiator": "Product-Description"
    },
    {
      "place": "Parts#Product Specification:0",
      "differentiator": "Product-Specification"
    },    
    {
      "place": "Parts#Notes:0",
      "differentiator": "Product-Notes"
    }
  ]
}

However if you need the feature, I suggest you consider opening another pr if this one goes through.

Just an idea, but one other option that might work is a pattern matching option on the differentiator.
Something like "differentiator": "Product-Description*", would then also work with your suggestion of "differentiator": "Product-Specification-Wysiwyg".

The problem would be performance then because they're currently dictionary based lookups I think.

@ns8482e
Copy link
Contributor

ns8482e commented Oct 10, 2019

@deanmarcussen As you prefer - I'll create another PR.

However, It's obvious to include editor type in differentiator. I am not suggesting anything new, The display counterpart is already doing it.

Here editor type is nothing but a shape type.

@sebastienros
Copy link
Member

For me, without is enough.

For me too. Why would you define placement rules that depend on the editor, like you are switching back and forth? You chose an editor independently of the location. Then if you want to change the location, you also change it.

@sebastienros sebastienros merged commit 2d49b61 into dev Oct 10, 2019
@sebastienros sebastienros deleted the deanmarcussen/#4483 branch October 10, 2019 19:55
@ns8482e
Copy link
Contributor

ns8482e commented Oct 10, 2019

@sebastienros @deanmarcussen

To me, Administrator != Developer, and new Editor can be created in a module where developer can define placement, that, the developer may prefer to place editor based on module placement

Also not to forget, placement.json is embedded in assembly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Placement for field options not working
4 participants