Adding custom fields to widget in recipe

Topics: Customizing Orchard
Apr 9, 2013 at 9:35 PM
So I exported everything with Orchards recipe export function, but it doesn't seem to export my custom widgets properly.
The data for the widget is not included, so I googled around and tried to add it myself, but it doesn't seem to work.

Below is one of my widgets in the recipe after my attempted fix (the puffpart tag was my addition).
Can anyone please tell me how to include data for custom fields in the recipe? :-)

Thanks in advance!
    <PuffWidget Id="/Identifier=5432a4r63f2c4f3ga92584fg3he737vr" Status="Published">
      <CommonPart Owner="/User.UserName=admin" Container="/Layer.LayerName=Always" CreatedUtc="2013-03-25T19:31:47Z" PublishedUtc="2013-03-25T19:31:47Z" ModifiedUtc="2013-03-25T19:32:23Z" />
      <WidgetPart Title="Skolhjalpen" Position="3" Zone="StartPageCenter" RenderTitle="false" Name="Skolhjalpen" />
      <PuffPart Title="test" Href="#" Last="false" ImageLink="#" Body="test" />
    </PuffWidget>
Developer
Apr 10, 2013 at 10:30 AM
Did you verify that the Type definition exists as well, with the Stereotype setting set to "Widget"?
Note that the Widgets module contains commands to create widgets. Perhaps there's something in there that could give a hint what else is required for widgets to be imported via XML instead of executing the widget create command.
Apr 10, 2013 at 12:36 PM
sfmskywalker wrote:
Did you verify that the Type definition exists as well, with the Stereotype setting set to "Widget"?
Note that the Widgets module contains commands to create widgets. Perhaps there's something in there that could give a hint what else is required for widgets to be imported via XML instead of executing the widget create command.
Yup, it's there
      <PuffWidget Stereotype="Widget" ContentTypeSettings.Creatable="False" ContentTypeSettings.Draftable="False" DisplayName="Puff Widget">
        <PuffPart />
        <WidgetPart />
        <CommonPart OwnerEditorSettings.ShowOwnerEditor="True" DateEditorSettings.ShowDateEditor="False" />
        <PuffWidget />
      </PuffWidget>
All other fields that are "built in", as in already there, like the Title, Zone and so on, are already there with the help of Orchards export function.
But my custom data is not there, and I can't seem to find the syntax on how to include it.

Maybe someone could give me an example on how they have done it with their custom widgets and recipe? :)
Developer
Apr 10, 2013 at 12:45 PM
Did you implement the Importing/Exporting methods in your PuffPartDriver?
Apr 10, 2013 at 12:53 PM
sfmskywalker wrote:
Did you implement the Importing/Exporting methods in your PuffPartDriver?
Hmmm no, how would that look like?
Haven't heard about that before, and can't seem to find any documentation about "drivers and export/import functions".

Could you maybe provide an example, or possibly a link? :-)
Developer
Apr 10, 2013 at 1:00 PM
http://skywalkersoftwaredevelopment.net/orchard-development/content-part-editors
Look for the "Creating the drivers" section on . It doesn't go into depth, but it should provide enough to get you started with.
Also, the Orchard source contains many drivers that implement import/export.
Developer
Apr 10, 2013 at 1:03 PM
The following post contains a more advanced import/export scenario, showing how to export references to other content items (look for the "The Driver" section): http://www.skywalkersoftwaredevelopment.net/blog/messaging-channels-rules-and-tokens-part-1
Apr 10, 2013 at 1:06 PM
sfmskywalker wrote:
The following post contains a more advanced import/export scenario, showing how to export references to other content items (look for the "The Driver" section): http://www.skywalkersoftwaredevelopment.net/blog/messaging-channels-rules-and-tokens-part-1
ah nice, thank you! :D
This is just what I need.
I will post again when I have tried it ;)
Apr 11, 2013 at 4:20 PM
Edited Apr 11, 2013 at 4:21 PM
Alright fixed it now and it works like a charm :)
Thanks a bunch!
protected override void Exporting(PuffPart part, ExportContentContext context)
{
    context.Element(part.PartDefinition.Name).SetAttributeValue("Title", part.Title);
    context.Element(part.PartDefinition.Name).SetAttributeValue("Href", part.Href);
    context.Element(part.PartDefinition.Name).SetAttributeValue("Body", part.Body);
    context.Element(part.PartDefinition.Name).SetAttributeValue("Last", part.Last);
}

protected override void Importing(PuffPart part, ImportContentContext context)
{
    context.ImportAttribute(part.PartDefinition.Name, "Title", x => part.Title = x);
    context.ImportAttribute(part.PartDefinition.Name, "Href", x => part.Href = x);
    context.ImportAttribute(part.PartDefinition.Name, "Body", x => part.Body = x);
    context.ImportAttribute(part.PartDefinition.Name, "Last", x => part.Last = Convert.ToBoolean(x));
}
Apr 12, 2013 at 1:45 PM
A follow-up question on this topic.
I noticed that when I export my widgets now, all data is there, but the "Id" field in the widget tag is empty, and if I export a "native" widget then the Id field is filled out.
Like such:
<MenuWidget Id="/Identifier=6032a4e42a0c48c0a92564ea3fe730cb" Status="Published">
    <CommonPart Owner="/User.UserName=admin" Container="/Layer.LayerName=Always" CreatedUtc="2013-03-25T19:41:27Z" PublishedUtc="2013-03-25T19:41:27Z" ModifiedUtc="2013-03-25T19:45:17Z" />
    <IdentityPart Identifier="6032a4e42a0c48c0a92564ea3fe730cb" />
    <WidgetPart Title="MainMenu" Position="1" Zone="Navigation" RenderTitle="false" Name="mainmenu" />
    <MenuWidgetPart Menu="/name=mainmenu" StartLevel="1" Levels="0" Breadcrumb="false" AddCurrentPage="false" AddHomePage="false" />
</MenuWidget>
I also noted that if I try to import one of my custom widgets that do not have the "Id" field filled in, it will not work and just silently not be imported.

This is my widget when I export it now (after adding the export functions)
<PuffWidget Id="" Status="Published">
    <MediaPickerField.ImageLink Url="~/Media/Default/Default/StartPage/start-1.png" Width="0" Height="0" />
    <CommonPart Owner="/User.UserName=admin" Container="/Layer.LayerName=Always" CreatedUtc="2013-03-25T19:25:54Z" PublishedUtc="2013-04-09T19:17:11Z" ModifiedUtc="2013-04-11T12:44:35Z" />
    <WidgetPart Title="Bildbutiken" Position="1" Zone="StartPageCenter" RenderTitle="false" Name="BildbutikenPuff" />
    <PuffPart Title="test" Href="#" Body="&lt;p&gt;test&lt;/p&gt;" Last="false" />
</PuffWidget>
And to make it import, I have to add it manually in the recipe, like such
<PuffWidget Id="/Identifier=9132a49owf2c4f3ga92584fg3he737vr" Status="Published">
    <MediaPickerField.ImageLink Url="~/Media/Default/Default/StartPage/start-1.png" Width="0" Height="0" />
    <CommonPart Owner="/User.UserName=admin" Container="/Layer.LayerName=Always" CreatedUtc="2013-03-25T19:25:54Z" PublishedUtc="2013-04-09T19:17:11Z" ModifiedUtc="2013-04-11T12:44:35Z" />
    <WidgetPart Title="Bildbutiken" Position="1" Zone="StartPageCenter" RenderTitle="false" Name="BildbutikenPuff" />
    <PuffPart Title="test" Href="#" Body="&lt;p&gt;test&lt;/p&gt;" Last="false" />
</PuffWidget>
I suspect that it has something to do with the following row in the first widget I pasted in this post
<IdentityPart Identifier="6032a4e42a0c48c0a92564ea3fe730cb" />
Is that relevant, and if yes, how would I go about adding the id so that it can be exported in my custom widget?
Is there some kind of part/field that I can add to my widget via the Migrations to achieve this?

Thanks a lot in advance!
And thanks a lot so far for all the help! :-)
Developer
Apr 12, 2013 at 2:47 PM
Yes, when importing content, each item must have a unique ID. If you attach the IdentityPart to your widget type, it should work.