How to make custom content truly draftable using a driver?

Topics: Customizing Orchard, Writing modules
Jul 6, 2011 at 10:28 PM

I have a custom content type. I would like for the user to be able to Save it without it publishing immediately. So, I added the Draftable part to the type. I also have a driver that is based on this example, to handle editing of content for my type.

When I initially create an instance of my content type, and click Save instead of Publish, I see that my new content does not show up on the site. Hooray! I click publish, and now my content is on the site. Double hooray!

But now, if I go and edit that content, the changes I make get saved to the published version, rather than a new draft. So as soon as I save (not publish), my changes take effect on the site anyway.

I found this blog post that indicates that, if I had a controller processing my content type saves, I would be able to tell it to actually obey whether the Save/Publish button was clicked. But I don't have a controller, I'm trying to do things as simply as possible, and I have merely a driver. The code for my driver is below.

Is there a way to properly write the editor methods on my driver so that they will apply edit saves to a new draft, rather than the existing published version? Or, do I have to use a controller so that I have more..control?

public class EducationHeroPartDriver : ContentPartDriver<EducationHeroPart>
		protected override DriverResult Display(EducationHeroPart part, string displayType, dynamic shapeHelper)
			return ContentShape("Parts_EducationHero", () => shapeHelper.Parts_EducationHero(
				ImageUrl: part.ImageUrl));

		protected override DriverResult Editor(EducationHeroPart part, dynamic shapeHelper) {
			return ContentShape("Parts_EducationHero_Edit",
			                    () => shapeHelper.EditorTemplate(
			                    	TemplateName: "Parts/EducationHero",
			                    	Model: part,
			                    	Prefix: Prefix));

		protected override DriverResult Editor(EducationHeroPart part, Orchard.ContentManagement.IUpdateModel updater, dynamic shapeHelper) {
			updater.TryUpdateModel(part, Prefix, null, null);
			return Editor(part, shapeHelper);

Jul 6, 2011 at 10:35 PM

That sounds like a bug: if you have draftable, that should be enough.

Jul 7, 2011 at 3:20 AM

I figured out what I was missing. My custom content part record was inheriting from ContentPartRecord instead of ContentPartVersionRecord. In addition, my data migration was creating a table as ContentPartRecord() rather than ContentPartVersionRecord(). Once I made these two changes, I saw true draftability.

I suspect that if I had included my models in the original post someone would have caught that right away. I was pretty sure that my issues had nothing to do with my model/data structure, until my bus ride home from work when I realized I didn't see anything about versions while I was viewing the data for my content type.

But does it make sense that in order to be truly draftable a content type has to also inherit from ContentPartVersionRecord? Bertrand, you made the statement that if it was draftable, that should be enough...does that statement stand, or were you assuming I had already inherited from ContentPartVersionRecord?

Jul 7, 2011 at 6:23 PM

I discovered something else. 

When I attach fields to a content type, they exhibit the improper versioning functionality that I saw with my original problem. Even if that content type extends ContentPartVersionRecord.

More specifically...I added a text field to my content type. When I edit an existing item, and change the value of the text field, and click Save (not publish), that change becomes immediately visible on the site, despite not publishing it. I saw the same results when I added a text field to a blog post, and Saved (not published) an existing blog post. 

It appears that field data gets saved in the Orchard_Framework_ContentItemRecord table, in the Data column. There is a table named Orchard_Framework_ContentItemVersionRecord, similar to the ContentPartRecord/ContentPartVersionRecord relationship I initially discovered...but the Data column of the Orchard_Framework_ContentItemVersionRecord table never actually contains anything. Is there something I need to do to my field or content part to make it use the ContentItemVersionRecord table for fields instead of ContentItemRecord? 

Jul 7, 2011 at 6:29 PM

Ca you file a bug?

Jul 7, 2011 at 7:13 PM

Done. Thanks!

Sep 25, 2011 at 2:13 AM
Edited Sep 25, 2011 at 2:14 AM

Hi, I could use help with this problem too.