Geta / geta-optimizely-categories

An alternative to Optimizely's default category functionality, where categories are instead stored as localizable IContent.
5 stars 10 forks source link

Category Picker doesn't update values on Inline Blocks (CMS 12.22.2) #22

Open GeekInTheNorth opened 1 year ago

GeekInTheNorth commented 1 year ago

We have the following block that we use for building up filters:

[ContentType(DisplayName = "Category Filter Block", GUID = "CDAC6F24-2175-4BEA-AC34-D6CA17E45884", GroupName = GroupNames.Content)]
[ContentTypeIcon(FontAwesome.Filter)]
public class CategoryFilterBlock : BlockData
{
    [Display(Name = "Label", GroupName = GroupNames.Content, Order = 10)]
    [CultureSpecific]
    [Required]
    public virtual string? Label { get; set; }

    [Display(Name = "Filter Categories", GroupName = GroupNames.Content, Order = 20)]
    [Categories]
    [CultureSpecific]
    [Required]
    public virtual IList<ContentReference>? FilterCategories { get; set; }
}

When creating this as a shared block (e.g. created under For This Site, For This Page) then the category picker works as intended and results in changes to the category picker being retained.

When creating this as an inline block directly in the content area, then only the categories set at the point of creation are applied. Any further updates to these on the block are not retained.

Steps to Reproduce:

I have also noted the same issue if I try and use the same block in a new block property list, e.g.

public virtual IList<CategoryFilterBlock>? FilterCategories { get; set; }
valdisiljuconoks commented 1 year ago

Inline blocks is great feature rushed out too fast.. :)

GeekInTheNorth commented 1 year ago

As an update, I ended up writing an interim attribute for use on Inline Blocks based on the [Categories] attribute. The issue appears to be on the display of the chosen categories, it only shows the first category when editing the block. But when I use this attribute I see all of the assigned categories on editing the block.:

/// <summary>
/// Cloned and cut down from the [Categories] attribute as it does not update when used on inline blocks.
/// </summary>
[Obsolete("This is a temporary fix for Category pickers on inline blocks not working and should be replaced with [Categories] once a fix is live. See: https://github.com/Geta/geta-optimizely-categories/issues/22")]
[AttributeUsage(AttributeTargets.Property)]
public class InlineBlockCategoriesAttribute : Attribute, IDisplayMetadataProvider, IMetadataDetailsProvider
{
    private readonly IEnumerable<IContentRepositoryDescriptor> _contentRepositoryDescriptors;

    public InlineBlockCategoriesAttribute()
      : this(ServiceProviderExtensions.GetInstance<IEnumerable<IContentRepositoryDescriptor>>(ServiceLocator.Current))
    {
    }

    public InlineBlockCategoriesAttribute(IEnumerable<IContentRepositoryDescriptor> contentRepositoryDescriptors)
    {
        this._contentRepositoryDescriptors = contentRepositoryDescriptors;
    }

    public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
    {
        if (!(context.DisplayMetadata.AdditionalValues[(object)"epi:extendedmetadata"] is ExtendedMetadata additionalValue))
            return;

        var repositoryDescriptor = _contentRepositoryDescriptors.First(x => x.Key == CategoryContentRepositoryDescriptor.RepositoryKey);

        additionalValue.EditorConfiguration["roots"] = (object)repositoryDescriptor.Roots;
    }
}