Specific style for TinyMCE in ListProperty

 

Hi,

I have a Page: 

[ContentType(
GUID = "86f7b89e-1c56-40fa-a808-44e8e1e262c2",
DisplayName = "Columns with text blobs",
Description = "Text blobs with heading and body, organized in columns")]
public class TextBlobsInColumnsBlock : BlockData
{
[CultureSpecific]
[Display(Name = "Add margin in top of element", Order = 10)]
public virtual bool AddTopMargin { get; set; }

[Required]
[CultureSpecific]
[Display(Name = "Headline", Order = 20)]
public virtual string Headline { get; set; }

[Display(
Name = "Text blobs",
Description = "Add text blob",
Order = 30)]
[EditorDescriptor(EditorDescriptorType = typeof(CollectionEditorDescriptor<TextBlob>))]
public virtual IList<TextBlob> TextBlobs { get; set; }

}

With a ListProperty list of :

public class TextBlob:BlockData
{
public string Heading { get; set; }

public XhtmlString Body { get; set; }

}
}

When adding or editing a text blob the TinyMce is rendered too wide like this:

To make the TineMce slimmer I added this class:

[ModuleDependency(typeof(TinyMceInitialization))]
public class TextBlobMceSettings : IConfigurableModule
{
public void Initialize(InitializationEngine context)
{
}

public void Uninitialize(InitializationEngine context)
{
}

public void ConfigureContainer(ServiceConfigurationContext context)
{


context.Services.Configure<TinyMceConfiguration>(config =>
{
config.For<TextBlob>(x => x.Body).Width(460);
});
}
}

This approach works for normal page properties. But not in this senario. 

Any ideas to make this work? Or is there another way to do this?

#198226 Oct 23, 2018 14:00
  • Member since: 2014
     

    Hi Torsten,

    I encountered this same issue myself recently and was actually going to put out a brief blog post about it next week.

    Not to spoil that too much, but you can use an editor descriptor:

    [EditorDescriptorRegistration(TargetType = typeof(XhtmlString), EditorDescriptorBehavior = EditorDescriptorBehavior.OverrideDefault, UIHint = UIHint)]
    public class PropertyListXhtmlStringEditorDescriptor : XhtmlStringEditorDescriptor
    {
        public const string UIHint = "PropertyListXhtmlString";
    
        public PropertyListXhtmlStringEditorDescriptor(ServiceAccessor<TinyMceConfiguration> tinyMceConfiguration) : base(tinyMceConfiguration)
        {
        }
    
        public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
        {
            base.ModifyMetadata(metadata, attributes);
    
            if (!metadata.EditorConfiguration.ContainsKey("settings"))
            {
                return;
            }
    
            var settings = (TinyMceSettings)metadata.EditorConfiguration["settings"];
    
            if (settings == null)
            {
                return;
            }
    
            //Set the size as desired
            settings.Width(450);
            settings.Height(200);
            settings.Resize(TinyMceResize.Vertical);
        }
    }
    

    Then add the necessary UI hint to your property:

    public class TextBlob : BlockData
    {
        public string Heading { get; set; }
    
        [UIHint(PropertyListXhtmlStringEditorDescriptor.UIHint)]
        public XhtmlString Body { get; set; }
    }

    /Jake

    #198340 Edited, Oct 25, 2018 16:49
  •  

    Thanks Jake, it worked perfectly.

    /Torsten

    #198426 Oct 29, 2018 7:33
  • Member since: 2004
     

    It's worth noting that Episerver recommend against using XhtmlString and Blocks as list items or list item properties used with ListProperty. We do not support this usage and several other features such as Export/Import does not support it. The recommendation for such scenarios is instead to use ContentArea.

    #198545 Edited, Oct 30, 2018 23:13
  • Member since: 2014
     

    Hi Henrik,

    That's interesting, didn't realize that was the case. Is there any intention to add support in the future?

    #198553 Oct 31, 2018 6:07
  • Member since: 2004
     

    I think that it's more likely that we would add better support for editing string item properties inside a Property List using TinyMCE rather than supporting the XhtmlString construct. The reason for this and for not supporting Blocks here is that there is quite a lot of work that would have to go into supporting it, while we already have support for this through the ContentArea. So considering this it would be interesting to know why you would chose to use a PropertyList over a ContentArea as this is the intended property type for creating lists of blocks?

    #198607 Oct 31, 2018 22:03
  •  

    Hi Henrik,

    The UI that the PropertyList displays (with columns of data) is sometimes preffered over the UI ContantAreas displays.

    Question

    When using a ContentArea with blocks - how do you prevent the editor from creating instances of this block outside this single content area?

    #198618 Nov 01, 2018 9:50
  • Member since: 2014
     

    Hi Rasmus,

    In that scenario you should be able to decorate your ContentArea with an AllowedTypesAttribute, something like:

    public class ExamplePage : PageData
    {
        [Display(Name = "Blocks", Order = 10)]
        [AllowedTypes(typeof(ExampleBlock))]
        public virtual ContentArea Blocks{ get; set; }
    }

    And then restrict your block with an AvailableContentTypesAttribute:

    [AvailableContentTypes(Availability.None, IncludeOn = new[] { typeof(ExamplePage) })]
    public class ExampleBlock : BlockData
    {
    }

    Without testing, I think that should work.

    #198684 Nov 02, 2018 18:30
  • Member since: 2014
     

    @Henrik: From an editor perspective (and if there is no need for re-use), I think the advtange of an IList<string> over a ContentArea restricted to a block type containing a string property is clear. Similarly, in our use case we needed editors to also be able to also apply some formatting and add links - so in this scenario it appears to make sense to use a configured (restricted) TinyMCE editor in a PropertyList (through an XhtmlString). I'd argue that this gives the editor the clear advantages (in this sceanrio) of the PropertyList:

    1. Easier to add items to the list (e.g. not necessary to create a block)
    2. Easier to get an overview of items in the list (e.g. as Rasmus noted when there are many items in a list the PropertyList column view can be preferable)
    3. Easier to manage items in the list (similar to 2, when all data is visible I can remove, update and re-arrange the list in a more convenient fashion)

    Hope this gives some insight into that decision.

    Based on what you've said, it feels like one option would be to change the XhtmlString property to be a string and change the EditorDescriptorRegistration of my answer above to be:

    [EditorDescriptorRegistration(TargetType = typeof(string), EditorDescriptorBehavior = EditorDescriptorBehavior.OverrideDefault, UIHint = UIHint)]

    That'll essentially give a TinyMCE editor for a string and allows the necessary configuration. Seeing as you can't drag and drop blocks in the PropertyList context and if image functionality was turned off via configuration (amongst other things) it feels like this'd work (I'm guessing that those are the aspects of import/export that won't currently work).

    The other option is of course to go with the ContentArea 😊

    #198690 Nov 02, 2018 19:50
  • Member since: 2004
     

    Thanks for your well reasoned response Jake. It seems like we are pretty much on the same page on this, but you don’t want to assume that this is the case. Hopefully there will be some time for us to improve the experience in this area, but in the meanwhile it looks like your solution does the trick. :)

    #198698 Nov 02, 2018 21:49