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: Make the AutoroutePart's edit view visible in the placement.info: <Place Parts_Autoroute_Edit="Content:after"/> Remove all code from the AutoroutePart's edit view: 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!

Orchard CMS: module settings not visible in Admin area? placement.info is the key!

by Oliver 9. September 2011 22:29

Today I went off to create a custom search module for our new Orchard based web application. I simply copied the module Orchard.Search, renamed all namespaces and such to Teamaton.Search, replaced some strings and prepended a prefix of “Teamaton” to a bunch of them. I wanted the new module to be able to run side-by-side with the original Orchard.Search module to make sure I had an independent implementation and there wouldn’t be any conflicts in case the Orchard.Search module is already installed somewhere. A problem I ran into quite quickly was that I wouldn’t see any of the search index’s fields on the Admin page for the new module (to the right you see the settings in the original Search module which is what I expect to see on the left as well):             Searching the discussions on Orchard’s codeplex site, I found this very helpful post on Module site settings not showing up which promised to be the key to my problem. During the initial string replacement orgy, in SearchSettingsPartDriver I had changed return ContentShape(…).OnGroup(“search”) to return ContentShape(…).OnGroup(“TeamatonSearch”). Now, this wasn’t in sync anymore with the Group Id specified inside the SearchSettingsPartHandler, but it should be (as the mentioned post suggests). So I changed that to match the Group “TeamatonSearch” like so: 1: protected override void GetItemMetadata(GetContentItemMetadataContext context) { 2: if (context.ContentItem.ContentType != "Site") { 3: return; 4: } 5: base.GetItemMetadata(context); 6: context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("TeamatonSearch"))); 7: } Unfortunately, it still did not work. Frustration. Another post on the discussion list led me to believe it was a problem with my Copy’n’Paste. There, piedone states: One remarkable point is a name clashing with content parts: there can't be content parts with the same name in different modules as this leads to problems with schema creation and also when selecting them in them admin menus (because then their displayed name is also the same). This somehow made sense to me, so I went and prefixed the part type name with Teamaton. When that didn’t work I also prefixed all properties of all ContentParts and Records because I remembered that I’d encountered a similar problem before when building our Google Maps module which, contained the same Latitude and Longitude property names that another ContentPart had already defined. But still: to no avail. Desperation. In the first post mentioned above, Bertrand Le Roy also states: I have been in that exact situation. This is probably an error getting swallowed somewhere. […] In my case, it was the feature not enabling all the classes I needed, in particular the record, and the system couldn't find how to map database records. So I went to the Orchard console … feature disable Teamaton.Search … feature enable Teamaton.Search … still nothing. Next it hit me like a sledge hammer – Migrations.cs! I hadn’t taken a single look at the persistence mapping for the SettingPartRecord! Well, turns out there was something wrong in there, but only since after I prefixed both parts and properties because now they wouldn’t match the strings in Migrations.cs anymore (a good example where magic strings break stuff). Kind of helpless, I launched NHProf to look at the database calls that were being made and saw that there weren’t any for the Teamaton.Search module – but for the Orchard.Search module there were … hm. I scanned through the project files again – and stared at placement.info, another file I hadn’t touched since copying the original Search module. Bingo! This was the root of all evil or rather of the search fields not displaying. It looked like this: 1: <Placement> 2: <Place Parts_Search_SiteSettings="Content:1"/> 3: <Place Parts_Search_SearchForm="Content:1"/> 4: </Placement> The problem with it was that I had renamed all the view files and prepended a prefix to them! So the correct version should look like this: 1: <Placement> 2: <Place Parts_TeamatonSearch_SiteSettings="Content:1"/> 3: <Place Parts_TeamatonSearch_SearchForm="Content:1"/> 4: </Placement> That’s because the views are named TeamatonSearch.SiteSettings.cshtml and TeamatonSearch.SearchForm.cshtml and are both placed inside a Parts folder: And now I saw the search fields even for our own new search module. Lesson learned If you can’t see something check the  placement.info  if you (accidentally) haven’t forgot to make that something visible And if you still can’t see it – double check! Happy coding!

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.