SaaS CMS has officially launched! Learn more now.

Rendering blocks with ContentReference issue

Vote:
 

I am trying out episerver forms and have a page where I want a single form to be inserted, so I added ContentReference property and limited it to FormContainerBlock types. Now, when I render this to the page, I load the block from the content reference and use the Html.DisplayFor method to output it to the page. The first thing I noticed is that there is no way to get to the form to edit it from the page that uses it. The default edit experience for that property shows the default tree navigator to select the block, but there is no way to navigate to the actual form that is referenced to edit it. What I would like to know is there a way to change that experience so users can get a link or an edit menu similar to how content areas work, but for a single ContentReference? I would be annoying for editors to have to click the ... button to open the tree navigator, then have to find that form in the assets pane in a second step.

#204508
Jun 04, 2019 18:07
Vote:
 

That sounds like you've got something weird set up or happening. If you add a form block to a page you should get the edit menu item in the CMS the same as a block. That's what we get on all our Episerver projects.

#204509
Jun 04, 2019 18:14
Vote:
 

Ahh I see what the issue is, you've got a content reference. Forms are created like blocks so then should be in a ContentArea restricted to the FormContainerBlock. Then you'll get the edit menu items for editing the underlying form.

#204510
Jun 04, 2019 18:15
Vote:
 

In my design I only want to allow one instance of that block in this property, so I am constrained to using a ContentReference. ContentArea would require extra validation to prevent adding more than one block to it. I am curious if there is a way to extend ContentReference to allow jumping to the block it references so you can edit it?

#204511
Jun 04, 2019 18:17
Vote:
 

Forms was built round the block system so the same as that you can't have a block in a ContentReference properly you can't have a form container.

I'd suggest just adding this attribute in your project you can put it on the ContentArea to limit the number of items to 1.

namespace Redweb.EpiServer.Models.Attributes
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using Castle.Core.Internal;
    using EPiServer.Core;
    using EPiServer.Find.Helpers;
    using EPiServer.SpecializedProperties;

    /// <summary>
    /// Allows the setting of max item number for a ContentArea or LinkItemCollection.
    /// </summary>
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
    public sealed class MaxItemCountAttribute : ValidationAttribute
    {
        /// <summary>
        /// Gets the limit.
        /// </summary>
        /// <value>The limit.</value>
        public int Limit { get; }

        /// <summary>
        /// Initializes a new instance of the <see cref="MaxItemCountAttribute"/> class.
        /// </summary>
        /// <param name="limit">The limit.</param>
        public MaxItemCountAttribute(int limit)
        {
            Limit = limit;
        }

        /// <summary>
        /// Determines whether the specified value is valid.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns><c>true</c> if the specified value is valid; otherwise, <c>false</c>.</returns>
        public override bool IsValid(object value)
        {
            var result = true;

            if (value != null && value is ContentArea area)
            {
                result = ValidateContentArea(area);
            }
            else if (value != null && value is LinkItemCollection collection)
            {
                result = ValidateLinkItemCollection(collection);
            }
            else if (value != null && value is IList list)
            {
                result = ValidateIList(list);
            }

            return result;
        }

        /// <summary>
        /// Validates the link item collection.
        /// </summary>
        /// <param name="linkItemCollection">The link item collection.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        private bool ValidateLinkItemCollection(LinkItemCollection linkItemCollection)
        {
            if (linkItemCollection == null || linkItemCollection.Count == 0)
                return true;

            return linkItemCollection.Count <= Limit;
        }

        /// <summary>
        /// Validates the content area.
        /// </summary>
        /// <param name="contentArea">The content area.</param>
        /// <returns>System.Boolean.</returns>
        private bool ValidateContentArea(ContentArea contentArea)
        {
            if (contentArea?.Items == null || !contentArea.Items.Any())
                return true;

            return contentArea.Items.Count <= Limit;
        }

        /// <summary>
        /// Validates the i list.
        /// </summary>
        /// <param name="iList">The i list.</param>
        /// <returns>System.Boolean.</returns>
        private bool ValidateIList(IList iList)
        {
            if (iList.IsNullOrEmpty())
                return true;

            return iList.Count <= Limit;
        }

        /// <summary>
        /// Formats the error message.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns>System.String.</returns>
        public override string FormatErrorMessage(string name)
        {
            return $"The maximum number of items for the {name} property is {Limit}";
        }
    }
}
[MaxItemCount(1)]
#204512
Jun 04, 2019 18:20
Vote:
 

That will have to do. I switched it to a ContentArea and applied this attribute and it works just fine. Better experience than using the ContentReference. I always thought you can reference any type of content with ContentReference, but it has its limitations I guess. Thanks for your help.

#204514
Jun 04, 2019 19:59
Vote:
 

Small stuff like this has been missing for ages. I would like to see an edit link next to all places where a conten item can be selected in edit mode.

#204516
Jun 04, 2019 23:03
Vote:
 

I get the sense that the core CMS does not get a lot of attention and updates these days...

#204517
Jun 04, 2019 23:09
Vote:
 

Since they have added all the personazation products and commerce is their core focus (as it brings in more Money) CMS is a little slow on the update cycle atm

#204520
Jun 05, 2019 9:35
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.