Orchard CMS - ContentPart will not update if made invisible through placement

by Oliver 17. December 2013 22:01

Today we decided that auto-updating our entries' urls when their names change is a rather good idea. Our entries are ContentItems consisting of our custom EntryPart, an AutoroutePart, and some more that are not important here. I thought it would be a matter of minutes to get this user story done. Simply set the correct Autoroute setting inside a migration step and it should work:

public int UpdateFrom9() {
     ContentDefinitionManager.AlterTypeDefinition(
         "Entry", cfg => cfg.WithPart(
             "AutoroutePart",
             acfg => acfg.WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "true")));
     return 10; }

Well, it didn't.

Placement affects ContentPart updates

In discoverize, we offer a distinct management area (totally separated from the Admin area) where owners of entries can edit their own entry's data but not much more. The decision which url should point to their respective entry is one that we don't want them to make so we simply never rendered the AutoroutePart's edit view using the following line in our management modules placement.info file:

<Place Parts_Autoroute_Edit="-" />

It turned out that this will cause Orchard to skip running through the POST related Editor() overload in the AutoroutePartDriver because in the ContentPartDriver.UpdateEditor() method there is an explicit check for the location of the currently processed part being empty:

if (string.IsNullOrEmpty(location) || location == "-") {
     return editor; }

Because of the above check, the handling of the AutoroutePart of the currently saved entry is stopped right there and the code that is responsible for triggering the url regeneration based is never called.

Updating ContentParts despite Invisible Edit View

The solution is simple – thanks to Orchard's phenomenal architecture – and consists of two steps:

  1. Make the AutoroutePart's edit view visible in the placement.info:
    <Place Parts_Autoroute_Edit="Content:after"/>
    
  2. Remove all code from the AutoroutePart's edit view:
    image

With this in place, Orchard won't enter the if (location == "-") condition above but instead will execute the url regeneration we were after in the first place.

Beware of Unrendered Views

So, Orchard connects certain behavior to the visibility of our parts' rendered views. Not what I'd call intuitive, but at least now we know.

Happy Coding!

Comments (2) -

Hazza United Kingdom
12/19/2013 12:09:10 PM #

Interesting, never knew that. Definitely not intuitive indeed.

Cheers for the heads up!

Zoltán Lehóczky (Piedone) Hungary
12/19/2013 2:46:08 PM #

This behaviour is because of security: if you hide an editor users could still tinker with the posted data and potentially get something saved that they supposedly can't edit.

If you do what you've described in this post without further checks you enabled users to potentially override their content items' URL.

Comments are closed

About Oliver

shades-of-orange.com code blog logo I build web applications using ASP.NET and have a passion for javascript. Enjoy MVC 4 and Orchard CMS, and I do TDD whenever I can. I like clean code. Love to spend time with my wife and our children. My profile on Stack Exchange, a network of free, community-driven Q&A sites

About Anton

shades-of-orange.com code blog logo I'm a software developer at teamaton. I code in C# and work with MVC, Orchard, SpecFlow, Coypu and NHibernate. I enjoy beach volleyball, board games and Coke.