I'm not sure why that note says they are unsupported. Property Lists were added years ago and I and many many developers have used them extensively without problem. They are definately supported!
Hi Scott Reed,
Thanks for your response. Can we use the List of Blocks in PageData model class in CMS12?
like below :
public class HoursBlock : BlockData
{
[Display(
GroupName = SystemTabNames.Content,
Order = 900,
Name = "Availability")]
public virtual string Availability { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 901,
Name = "Day(s) of the Week")]
public virtual string DayOfWeek { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 902,
Name = "Opening Time")]
public virtual DateTime OpenTime { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 903,
Name = "Closing Time")]
public virtual DateTime ClosingTime { get; set; }
}
public class Employee: PageData
{
[Display(
GroupName = SystemTabNames.Content,
Order = 100,
Name = "Title")]
[Required]
public virtual string Title { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 200,
Name = "Standard Hours (limit 7)")]
public virtual IList<HoursBlock> OpenHours { get; set; }
}
Why do you need them as blocks? Can you not just use a model as the https://world.optimizely.com/documentation/developer-guides/CMS/Content/Properties/generic-propertylist/ shows?
Yes, we can also use model based approach instead of blocks but in my case, the same data going to be used on multiple pages. Due to this reason, I chose the concept of the blocks that means the same instance will be used in the number of pages.
I've never seen it work this way for a property list so I'd suggest trying it and see.
Obviously you can just just a content area for a list of blocks and if you're on the newer versions of Opitmizely or have BlockEnhancements installed you can inline edit blocks from the page but you won't see them in page like the gneric list does.
If it doesn't work you could just create an interface inplemented by both your block model and property list model, at least that way you can keep the implementations in check.
I am using the latest CMS12 version. I didn't understand the part "create an interface implemented by both your block model and property list model".
Can you provide more details or sample snippets on this?
I just tested and I was able to get your block working in a property list. The problem is it's showing all the extra data that comes from the BlockData base class which makes it unusable.
For the interface comment I was just talking about standard Interface design in C#. We create interfaces to set patterns that classes need to adhere to, such as the below. That way you always make sure you update your interface as your primiary source and then you can just generate the properties on your other models using VS or Code.
public interface IHoursData
{
string Availability { get; set; }
string DayOfWeek { get; set; }
DateTime OpenTime { get; set; }
DateTime ClosingTime { get; set; }
}
}
public class HoursBlock : BlockData, IHoursData
{
[Display(
GroupName = SystemTabNames.Content,
Order = 900,
Name = "Availability")]
public virtual string Availability { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 901,
Name = "Day(s) of the Week")]
public virtual string DayOfWeek { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 902,
Name = "Opening Time")]
public virtual DateTime OpenTime { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 903,
Name = "Closing Time")]
public virtual DateTime ClosingTime { get; set; }
}
public class HoursPropertyListModel : IHoursData
{
[Display(
GroupName = SystemTabNames.Content,
Order = 900,
Name = "Availability")]
public virtual string Availability { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 901,
Name = "Day(s) of the Week")]
public virtual string DayOfWeek { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 902,
Name = "Opening Time")]
public virtual DateTime OpenTime { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 903,
Name = "Closing Time")]
public virtual DateTime ClosingTime { get; set; }
}
Great, Scott Reed for providing the code snippet. May I know what is the purpose of the HoursPropertyListModel class?
Shall I declare the List block like below:
public class Employee: PageData
{
[Display(
GroupName = SystemTabNames.Content,
Order = 100,
Name = "Title")]
[Required]
public virtual string Title { get; set; }
[Display(
GroupName = SystemTabNames.Content,
Order = 200,
Name = "Standard Hours (limit 7)")]
public virtual IList<HoursBlock> OpenHours { get; set; }
}
I am just curious to see the output in CMS Editor for list block types. Please share a screenshot if it's handy.
The HoursPropertyListModel is if you want to use an interface so that both a model for Blocks and a model for PropertyLists can be kept the same. It's just standard C# and OOP
To get your block working as a model you need to make sure two things.
1. You have your property definition class so it can be allowed for Property Lists. Add this as a separate C# file
[PropertyDefinitionTypePlugIn]
public class HoursBlockPropertyListDefinition : PropertyList<HoursBlock>
{
}
2. You have added the decorator above your OpenHours property to allow it to work
[EditorDescriptor(EditorDescriptorType = typeof(CollectionEditorDescriptor<HoursBlock>))]
As shown in the link https://world.optimizely.com/documentation/developer-guides/CMS/Content/Properties/generic-propertylist/ these are always required to configure your model on the property.
Hi Scott Reed, Thanks for clarifying my doubts.
I implemented it using List Block in the sample project and worked as expected but a lot of extra properties are showing on the Item Details dialogbox.
How to hide all extra properties in the Item Details Page.
Refer image for output of Item Details Dialog box: https://imgur.com/a/AqNjMe
Yes that's what I was saying when I said a few posts back "The problem is it's showing all the extra data that comes from the BlockData base class which makes it unusable." when I tried it too.
I don't think there's a way to specifically hide properties for only the Propery List showing as it's designed to auto show the properties because you're supposed to use a specific model not a block.
As this point I would personally say you're going way too in depth to try and protect yourself from having a model and the block.
Just create both with the interface as I mentioned so you can keep them aligned, the small duplication of property declaration code is miniscule compared to trying to enginerr a solution to dynamically hide and show property based on context.
thanks, Scott Reed for your detailed explanation of my problem. I will create both with an interface as you mentioned.
I would recommend using IList<ContentReference> instead. If you only want to allow a specific block type, you can decorate the property with the AllowedTypes attribute. The UI has better inline-editing nowadays.
We have full support for lists of value types, such as IList<string> and IList<int>. Use complex types with caution, because there is no built-in support for migration when you change the type. This has to be implemented in a custom serializer.
I have created the block as property and how to create a Collection of Blocks (like PropertyLinkCollection) in one of the page models?
We may be able to implement this using the Generic PropertyList referenced as per documentation.
Reference Link: https://world.optimizely.com/documentation/developer-guides/CMS/Content/Properties/generic-propertylist/
But this Generic Property List is not recommended by Optimizely CMS on the official website.
Due to the above reason, I am going to use the List of Blocks concept instead of the Generic PropertyList. Can you please provide any links or documents to implement the List of Blocks?