best way to create a hello world block?

Vote:
 

Following the official episerver documentation, there is a guide to how to create a new page.  There seems to be nothing similar on how to create a block.  I have also read "the missing manual" which is also missing this information.

I am guessting I need 3 files:

  1. Models/Blocks/MyBlock.cs
  2. Controllers/MyBlock.cs
  3. Views/MyBlock.cshtml

In VS, if I "add new" and select the epiplugin, I see:

  • Block Type (is this the model?)
  • Block controller(MVC)  
  • Block partial View (MVC razor)
  • etc.

I assume block type = model, block controller = conroller, and block partial view = view.

This seems to work - I can create a insatance f MyBlock in the CMS editor.

How do I put an area on a page which this block can be added? I cant find this in the docs.

I found this snippet in the missing manual, and put this on my hello world page model, but it doesnt work (nothing shown, only my existing title and body strings). I also tried creating a new page with my single page type, but still no content block where I can drag a block.  What am i missing?

        [Display(
Name = "Main Content Area",
GroupName = SystemTabNames.Content,
Order = 200)]
        public virtual ContentArea MyContentArea { get; set; }
    }
#210432
Edited, Nov 22, 2019 22:09
Vote:
 

So, the next thing is rendering the content, that you are adding into MyContentArea property. For that you need to add this line into view of your page (say my Page is StandardPage).

@Html.PropertyFor(x => x.CurrentPage.MyContentArea)

Remember one thing, property that you are accessing using Model.CurrentPage.MyContentArea depends on how you are adding model on your page. Above example is in context to Alloy site where the model is added as

@model PageViewModel<StandardPage>

If you are adding your model as

@model StandardPage

then you can directly access the properties from Model

@Html.PropertyFor(x => x.MyContentArea)

or, you can also render the property using @Html.DisplayFor()

@Html.DisplayFor(x => x.CurrentPage.MyContentArea)

The difference in DisplayFor() and PropertyFor() is that PropertyFor() allows you to edit your properties to edit in on-page edit mode.

#210437
Nov 23, 2019 3:13
Vote:
 

thanks Praful.  I tried copying from alloy, so added the last line here:

@using EPiServer.Core
@using EPiServer.Web.Mvc.Html

@model Empty1.Models.Pages.StandardPage

<div>
    <H1>@Html.PropertyFor(m => m.Heading)</H1>
    <div>
        @Html.PropertyFor(m => m.MainBody)
    </div>
</div>
@Html.PropertyFor(x => x.CurrentPage.MyContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.TwoThirdsWidth })

However, it cant resolved CurrentPate nor Global.

Any ideas?

#210441
Nov 23, 2019 10:07
Praful Jangid - Nov 23, 2019 13:47
Just like what I said, as you are passing your StandardPage as model you don't need CurrentPage. You can directly access your property.
@Html.PropertyFor(x => x.MyContentArea)
johnv - Nov 23, 2019 19:44
great, that worked. However, when I try to drop a "MyBlock" content block onto the content area, it gives "

ContentArea.ascx not found

System.Web.HttpException
HResult=0x80004005
Message=Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
Source=
johnv - Nov 23, 2019 19:51
Out of interest, how does one get Global and CurrentPage to resolve? i.e. how comes it works in Alloy?
Praful Jangid - Nov 24, 2019 10:59
It's nothing special, if you see code of AlloySite.CMS.Models.ViewModels.PageViewModel, it have a property CurrentPage. This property is of T (Generic) type (where T : SitePageData; defined in PageViewModel). Anything you pass into PageViewModel
Vote:
 

Thanks again Praful

This worked:

@using EPiServer.Core
@using EPiServer.Web.Mvc.Html

@model Empty1.Models.Pages.StandardPage

<div>
    <H1>@Html.PropertyFor(m => m.Heading)</H1>
    <div>
        @Html.PropertyFor(m => m.MainBody)
    </div>
</div>
@Html.PropertyFor(x => x.MyContentArea)

How when I edit "StandardPage" it shows an area where I can drag and drop a block.

However, when I drop an instance of MyBlock onto it, it gives:

ContentArea.ascx not found

System.Web.HttpException
  HResult=0x80004005
  Message=Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
  Source=<Cannot evaluate the exception source>
  StackTrace:
<Cannot evaluate the exception stack trace>

Inner Exception 1:
InvalidOperationException: The partial view 'Index' was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/MyBlock/Index.aspx
~/Views/MyBlock/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/MyBlock/Index.cshtml
~/Views/MyBlock/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
/Util/Views/Shared/Index.ascx
/Util/Views/Shared/DisplayTemplates/Index.ascx
/Util/Views/Shared/EditorTemplates/Index.ascx

#210444
Nov 23, 2019 19:50
Praful Jangid - Nov 26, 2019 9:33
If your bug got resolved then please close this thread (mark answer).
Thanks
Vote:
 

So the next thing is view for your MyBlock. Create your view as /Views/MyBlock/Index.cshtml and I am expecting that you are using the MVC pattern, right?

Here, it depends on your controller name and action name. MyBlockController (folder name without controller suffix) and Index is your action/method name inside that controller.

I hope this help. If you are very new to this, then I would suggest you to read about MVC pattern and routing.

Thanks

#210448
Nov 23, 2019 23:36
* 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.