Posts tagged export
Posts tagged export
32 notes &
While developing in Orchard with a team, recipes are very useful. Everyone has their own database (so we don’t break each others environment), and sometimes you want to share your content with a colleague. Or your database got corrupted and you need to re-install. Not to mention backupping. That’s when Recipes come in.
For each of my orchard projects I created extensive recipes with custom Commands and importable ContentParts. I want to share a little code snippet for importing and exporting complicated ContentParts. It’s not as easy as it seems because it works with Linq.XElement properties.
First, the exporting
Inside the ContentPartDriver, here’s my code for the override function Exporting(ContentPart part, ExportContentContext context), which exports a richtext string into an attribute and related Offer elements into child-elements:
// first, get the ContentPart element var parent = context.Element(part.PartDefinition.Name); // a simple one: a string if (!string.IsNullOrEmpty(part.RichTextBlock1)) parent.SetAttributeValue("RichTextBlock1", part.RichTextBlock1); // a 1-n relationship // create the container element parent.SetElementValue("offers", ""); var offers = parent.Element("offers"); foreach (var offer in part.Offers) { // every node must have a unique name, else SetElementValue won't work var elid = "offer" + offer.Id; // again, first create the container element offers.SetElementValue(elid, ""); var el = offers.Element(elid); // then import the values (without Id, it will be autogenerated) //el.SetAttributeValue("Id", offer.Id); el.SetAttributeValue("Image", offer.Image); el.SetAttributeValue("Price", offer.Price); el.SetAttributeValue("Url", offer.Url);
}
Expand the recipe
So now, when I execute the export function (don’t forget to check the Data checkbox!), I get the entire contentitem with my custom contentpart embedded into it. The export.xml file that’s generated can be used as recipe, or parts of it can be used.
And then, the importing
So now I override the Importing(ContentPart part, ImportContentContext context) function as follows:
// this gets injected into the constructor by Autofac
private readonly IRepository<OfferRecord> _offerRepository;
// first import the simple richtext field
var RichTextBlock1 = context.Attribute(part.PartDefinition.Name, "RichTextBlock1"); if (RichTextBlock1 != null) part.RichTextBlock1 = RichTextBlock1;
// then get the "offers" element var offers = context.Data.Element(part.PartDefinition.Name).Element("offers"); if (offers != null) { var offerList = new List<OfferRecord>();
// and import each of the offer elements. I'm not checking on nodenames because they're unique! foreach (var offer in offers.Elements()) { var n = new OfferRecord(); if (offer.Attribute("Image") != null) n.Image = offer.Attribute("Image").Value; if (offer.Attribute("Price") != null) n.Price = offer.Attribute("Price").Value; if (offer.Attribute("Url") != null) n.Url = offer.Attribute("Url").Value;
// the new offer should first be saved to database, then attached to the ContentPart _offerRepository.Create(n); offerList.Add(n); } part.Offers = offerList; }
That’s it! Importing and exporting works like a charme, and my colleague’s have the same pages as I have when they re-install orchard with my recipe!