PiranhaCMS / piranha.core

Piranha CMS is the friendly editor-focused CMS for .NET that can be used both as an integrated CMS or as a headless API.
http://piranhacms.org
MIT License
2.04k stars 561 forks source link

Blocks without Custom Editor Templates / Checkbox Field Serialization #585

Closed i-love-code closed 5 years ago

i-love-code commented 5 years ago

Hello again!

I was wondering if custom blocks without a custom editor template are meant to be supported, or if it's highly recommended to make a custom block editor.

I am working with a custom quote block that has some visual optional tweaks on it:

image

The visual lines either on top or bottom of the quote are represented by new properties "PullTop" and "PullBottom", with an optional "Author" field.

Without adding a custom editor template, they do render in edit mode and work in very specific scenarios, even though the UI is less than ideal, seen below:

image

I'm okay with this being the interface if it's just what happens without a custom editor. The problem is, I'm running into serialization errors caused by the checkbox field on the "CustomQuoteBlock" model.

I've spent some time looking into this and it appears that for some reason, it's caused by two hidden input value fields for the checkboxes being included at the very end of the page edit form, rather than within the block editing area:

<input name="Blocks[0].Value.PullBottom.Value" type="hidden" value="false" /><input name="Blocks[0].Value.PullTop.Value" type="hidden" value="false" /></form>

This causes an issue when making changes that changes the index of the custom block in the page's block area, because the javascript for the editing UI does not account for these fields. The editing interface's javascript does something similar to:

recalcblocks: function() {
            var items = $(".page-blocks-body .sortable >.sortable-item");

            ... modifies the attributes of the fields WITHIN each item above, ensuring to update their names to include their new index within the content area so that when it's submitted, they serialize with all their fields properly ...
}

Unfortunately, since these hidden input fields for the checkbox fields are being included in the bottom of the form and not with the rest of the block's inputs, they're excluded from the ID updates and are never updated.

As an example, you're able to repeat this reliably using a branch I have https://github.com/i-love-code/piranha.core/tree/reproduction/custom-block-saving by:

The call to save the page will fail with a serialization error:

   at Piranha.Extend.Serializers.CheckBoxFieldSerializer`1.Serialize(Object obj) in C:\Git\opensource\piranha.core\core\Piranha\Extend\Serializers\CheckBoxFieldSerializer.cs:line 29
   at Piranha.App.SerializeObject(Object obj, Type type) in C:\Git\opensource\piranha.core\core\Piranha\App.cs:line 294
   at Piranha.Services.ContentService`3.TransformBlocks(IList`1 models) in C:\Git\opensource\piranha.core\data\Piranha.Data.EF\Services\ContentService.cs:line 285
   at Piranha.Repositories.PageRepository.Save[T](T model) in C:\Git\opensource\piranha.core\data\Piranha.Data.EF\Repositories\PageRepository.cs:line 292
   at Piranha.Services.PageService.SaveAsync[T](T model) in C:\Git\opensource\piranha.core\core\Piranha\Services\PageService.cs:line 440
   at Piranha.Services.PageServiceSyncExtensions.Save[T](PageService service, T model) in C:\Git\opensource\piranha.core\core\Piranha.Extensions.Sync\PageServiceSyncExtensions.cs:line 160
   at Piranha.Areas.Manager.Services.PageEditService.Save(PageEditModel model, String& alias, Nullable`1 publish) in C:\Git\opensource\piranha.core\core\Piranha.Manager\Areas\Manager\Services\PageEditService.cs:line 74
   at Piranha.Areas.Manager.Controllers.PageController.Save(PageEditModel model) in C:\Git\opensource\piranha.core\core\Piranha.Manager\Areas\Manager\Controllers\PageController.cs:line 234
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at System.Threading.Tasks.ValueTask`1.get_Result()

You can see why it fails by checking out the data sent to the save call, you can see the two hidden checkbox value fields that never had their IDs updated to account for the new [1] position in the list of blocks since they're not touched by the javascript above which only concerns itself with inputs within the sortable block editors.

image

Thoughts? Is this expected, or should this type of block without a custom editor work?

tidyui commented 5 years ago

Not sure why this happens. In the current manager, when blocks are re-ordered all form field indexes are updated with javascript in the browser. For some reason this update misses the checkboxes. The new manager that will be released in 7.0 uses a completely different technology to achieve this, but we'll try to see if we can locate the issue for the 6.1 release.

i-love-code commented 5 years ago

Any chance in Version 7 blocks would support block properties having the same editors as a normal field within a page region would have? It's great to be able to override the editor view in order to have a user-friendly editing experience, but ideally it would leverage the normal field editing experience if it does not have one.

I know it's hard to tell, but any rough guestimate on v7 release? Or a recommended stable version? Trying to pick the best option for a new site and I've been running into a bit of bugs with v6

i-love-code commented 5 years ago

I found this (https://stackoverflow.com/questions/2697299/asp-net-mvc-why-is-html-checkbox-generating-an-additional-hidden-input) and submitted a PR to best fix the issue without interrupting the functionality it provides.

tidyui commented 5 years ago

Closing this as the PR is merged!