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

Add custom properties to blocks #1791

Open
gadonski opened this issue Dec 20, 2021 · 5 comments
Open

Add custom properties to blocks #1791

gadonski opened this issue Dec 20, 2021 · 5 comments

Comments

@gadonski
Copy link

gadonski commented Dec 20, 2021

Hello,

I've extended the block ImageBlock to add a custom attibute (css class name), but (obviusly) the field not appear on screen.

How to extend the component "image-block" for appear the field?

@tidyui
Copy link
Member

tidyui commented Jan 20, 2022

The easiest way is to add a custom component with the new css class field and then use the standard image-block component from within it!

@tidyui
Copy link
Member

tidyui commented Feb 22, 2022

Instead of just fixing something for the ImageBlock I propose we add support for defining different properties for blocks in the application. For example we could add an extra "Style" dropdown for image blocks with something like this (consider this an idea).

App.Blocks.GetByType<Piranha.Extend.Blocks.ImageBlock>()?
    .Properties.Add(new SelectProperty()
    {
        Id = "Style",
        Name = "Display",
        Icon = "fa fas-fish",
        Options =
        {
            new() { Name = "Full", Value = "col-12" },
            new() { Name = "Half", Value = "col-6" }
        }
    });

This way properties is not bound to the implementation of the actual blocks, but rather something that is defined in the application using them.

@tidyui tidyui changed the title How to add a css class on image block? Add custom properties to blocks Feb 22, 2022
@tidyui tidyui added this to the Version 10.1 milestone Feb 22, 2022
@tidyui tidyui added this to To do in Version 10.1 via automation Feb 22, 2022
@gadonski
Copy link
Author

Instead of just fixing something for the ImageBlock I propose we add support for defining different properties for blocks in the application. For example we could add an extra "Style" dropdown for image blocks with something like this (consider this an idea).

App.Blocks.GetByType<Piranha.Extend.Blocks.ImageBlock>()?
    .Properties.Add(new SelectProperty()
    {
        Id = "Style",
        Name = "Display",
        Icon = "fa fas-fish",
        Options =
        {
            new() { Name = "Full", Value = "col-12" },
            new() { Name = "Half", Value = "col-6" }
        }
    });

This way properties is not bound to the implementation of the actual blocks, but rather something that is defined in the application using them.

Awesome! Thanks

Version 10.1 automation moved this from To do to Done Feb 23, 2022
@tidyui tidyui reopened this Feb 23, 2022
Version 10.1 automation moved this from Done to In progress Feb 23, 2022
@tidyui
Copy link
Member

tidyui commented Feb 23, 2022

Reopening issue as we’ll be using it to track the development

@tidyui tidyui added the request label Feb 23, 2022
@tidyui tidyui moved this from In progress to To do in Version 10.1 Feb 23, 2022
@tidyui tidyui modified the milestones: Version 10.1, Version 11.0 Apr 25, 2022
@tidyui tidyui removed this from To do in Version 10.1 Apr 25, 2022
@gh-at-sqh
Copy link

I'm still new to the product, and still interested for now. I'm hoping to see this feature implemented. I was surprised to find it exists in principle for Page<T>, but not Block, which is the more fundamental building block. Having the capability would mean being able to produce Modules full of Piranha widgets, I'm thinking. It would be easier to expand the product, if I'm not missing something.

Whatever it is or becomes, I think it should be as lightweight db-wise as possible. Another table and 2 joins is expensive (if you are thinking "BlockProperties" table). The 'Fields' decoration looks pretty verbose in storage, IMO, on first glance. I guess in the Manager it is not really critical. Don't want a hit during regular Block materialization, obviously. There is an expense (perhaps unnecesary) to auto-type conversion (ColorField <-> string, e.g.).

As an exercise, I'm dillying about with an ExtendedGalleryBlock class. Both it and its Blocks need lots of various properties to implement, depending on the backing js library. It is the same work accomplished in so many other CMS libs with ready-to-use widgets.

I'm thinking it could be done simply with just a single [Region] object, a POCO, named "Properties", "Options" or what have you. Perhaps default values and text description attributes on the POCO properties and enum types. The Manager could perhaps then just iterate across the Region object's properties and build UI inputs for them automatically. Add a button and slide-out to access a Block Settings dialog.

If attributes are required for POCO's then so be it.

The POCO's would be stored in the DB as json per Block instance somehow, no doubt. In this case just one new DB field instead of a Properties table + map? Please advise. I'm almost motivated to try, but am too much a newbie.

Example Idea'r (with kindest respect). All I need now is for the Region to be written/stored and a UI built in Manager, like is done for Page<T>.

[BlockGroupType(Name = "Gallery (Extended)", Category = "Media", Icon = "fas fa-images")]
[BlockItemType(Type = typeof(ExtendedImageBlock))]	
public class ExtendedGalleryBlock : ImageGalleryBlock
{
    [Region(Title = "Gallery Options")]
    public ExtendedGalleryBlockOptions Options { get; set; } = new();
}

public class ExtendedGalleryBlockOptions
{
    // Perhaps a new attribute, "Editor" instead of "Field".
    [Field(Editor="CheckboxField", DefaultValue = true, Title = "Include Titles", Description = "If true, each image Title will be displayed.")]
    public bool IncludeTitles {get;set;}
    public bool IncludeDescriptions {get;set;}
    public bool AutoPlay {get;set;}
    // Use the default SelectEditor w/Name=Value
    [Field(Description = "Type of transition between images")]
    public TransitionType DefaultTransition {get;set;}
    [Field(DefaultValue = ImageFit.ScaleToFit)]
    public ImageFit DefaultFit {get;set;}
    // Use a text input and validate for positive int, or a range; or provide validation/normalization via another getter at run-time
    [Field("Editor="IntegerField", EditorProperties="Min=0|Max=10000|Increment=100")]
    public int DefaultInterval {get;set;}
    // accept default int editor
    public int ReplayTimes {get;set;} = -1;
    [Field("Description="Classes added to each img.")]
    public string ImageClasses { get; set; }
    // Nice to have a color-picker
    [Field(Editor="ColorField", DefaultValue=null, EditorProperties="InitialValue=#252525")]
    public string BackgroundColor { get; set; } = null; 
}

public class ExtendedImageBlock: ImageBlock {
    [Region]
    public ExtendedImageBlockOptions Options {get; set;} = new();
    public NameValueCollection GetExifData() { return ImageFile.GetExifData().Select(it => new() {Name = it.ExifTag, Value = it.ExifValue}); }
}

public class ExtendedImageBlockOptions {
    public string Width {get;set;}
    public string Height {get;set;} 
    public int? Interval {get;set;} = null;
    [Field(Description="Override the gallery's default for this image")]
    public ImageFit? Fit {get;set;} = null;
    public string Classes {get;set;}
    public string Style {get;set;}
    [Field(Description = "Optional transition from previous image")]
    public Transition? Transition {get;set;}    
}

public enum ImageFit {
    [Glyph("fa fa-fish")] // Not really necessary
    [Description("No resize; crop bottom, left, right as needed to fit. ")]
    Contain,
    [Description("Zoom down to fit; no cropping.")]
    ScaleToFit,
    [Description("Size up/down to fill 100% width, Center vertically, crop top/bottom.")]
    Cover,
    [Description("Full width zoom in/out to width; crop to center vertically.")]
    ScaleToWidth,
    None,   
}

@tidyui tidyui modified the milestones: Version 11.0, Version 12.0 Jan 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants