November Happy Hour will be moved to Thursday December 5th.

Including required resouces for block rendered in layout? (CMS 11.20)

Vote:
 

Hi

I'm trying to put a block in the layout that also contains a Forms form. The block reference is specified on a seperate settings page, loaded in a IPageViewModel<T> and rendered using PropertyFor.

The block renderes fine, but any resouces required for the block (eg Forms) is not included in the rendering.

I'm guessing this is because the block isn't part of the PageData, and thus is never considered?

Is there any way to tell EPiServer to include everything required for a certain eg block "programatically" somewhere in the chain?

Thanks!

#268564
Dec 17, 2021 8:15
Vote:
 

Hi,

How are you referencing the block from the settings page? Can you share some code possibly?

Thanks

#268587
Dec 17, 2021 17:20
Vote:
 

Hi

It's not that much code to show to be honest. The block is a property (not a reference) of a settings page, and the block in turn has a reference to a Form block.

I've tried a few different methods, but right now it loads the referenced form in the block controller Index with the ContentLoader, and put on the BlockData as an (ignored) property FormBlock.

And then rendered with

@Html.PropertyFor(m => m.FormBlock)

I've also tried putting it in the Layout model, as an ignored Page property, etc, etc.

I can debug part of the code running rendering the form (eg custom form elements requiring resources) and it seems it's collecting resources as it should. It's just that they are never part of the rendered result. 🤔

When displaying a form as part of the page content as usual, all the resources are rendered in the <head>. Which is why i suspect the PropertyFor comes too late in the chain? But I can't find any method to manually inject a specific contents resources, or give the renderer a hint beforehand what to load.

#268657
Edited, Dec 19, 2021 11:48
Vote:
 

Hi,

Maybe I didn't explain that well, are you using a content area to reference the block, on your settings page?

public virtual ContentArea FormBlock{ get; set; }

Thanks

#268696
Edited, Dec 20, 2021 9:09
Vote:
 

No, as a Block (stored and versioned with the settings page).

SettingsPage.cs:

public class SettingsPage : PageData
{
    ......

    public virtual CartBlock CartBlock { get; set; }  
}

CartBlock.cs

public class CartBlock : BlockData
{
	[AllowedTypes(typeof(FormContainerBlock))]
	public virtual ContentReference Form { get; set; }

	// Right now I'm ContentLoading this property in the BlockController, and displaying it with Html.PropertyFor()
	[Ignore]
	public FormContainerBlock FormBlock { get; set; }
}

🙂

#268697
Dec 20, 2021 9:30
Vote:
 

Hi,

I had a play about with this and the only way I can get a form added to the settings page and then referenced is to use a 'ContentArea'.

On your viewmodel you would add a new property of type 'ContentArea' and then set it by retrieving the content area from the settings page.

Does this help at all?

As a form in its basic form is a block type there isn't really a need to create another block to add the form too, and if you read across the forums it is considered an anti-pattern to nest blocks within each other.

If you really need a block I would maybe go down the route of creating you own FormContainerBlock Type as described here. This way you have a block however it is not a nested block.

#268746
Edited, Dec 21, 2021 11:37
Vote:
 

In an Alloy site you can update and do this:

public interface IPageViewModel<out T> where T : SitePageData
    {
        T CurrentPage { get; }
        LayoutModel Layout { get; set; }
        IContent Section { get; set; }
        ContentArea Cart { get; set; } //New property for the cart form
    }
 public class PageViewModel<T> : IPageViewModel<T> where T : SitePageData
    {
        public PageViewModel(T currentPage)
        {
            CurrentPage = currentPage;
        }

        public T CurrentPage { get; private set; }
        public LayoutModel Layout { get; set; }
        public IContent Section { get; set; }

        public ContentArea Cart { get; set; } // Implemented new property from interface
    }

Add a Content Area to a page for demo here I have used startpage, this could be you settings page though as long as you can retrieve it. Then in the  PageContextActionFilter add the follwing at the end of the 'OnResultExecuting' method.

 var contentLoader = ServiceLocator.Current.GetInstance<ContentLoader>();
                var start = contentLoader.Get<StartPage>(ContentReference.StartPage); //This is the startpage however it could be any page you want.

                if (start != null)
                {
                    model.Cart = start.Forms;
                }

You will now have access to the form from anywhere in the site.

#268748
Dec 21, 2021 11:51
Vote:
 

Hi, sorry for the late reply, other projects got in the way.

I will try this out as soon as possibly and get back if this solves it, many thanks!

#269622
Jan 07, 2022 9:34
* 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.