This project is read-only.

A different Export UI

Topics: Core, Customizing Orchard
Apr 25, 2013 at 11:34 PM
I end up using the export functionality quite often during development.
And every once in a while I need to export different chunks of data from my orchard environments.

It is just a really strange intersection...
"All the content types" x "Metadata and/or Data" x "Published or Draft"

In order to get the data I want, I have to go back and forth a few times, and often I end up missing something.

So I wanted an export user interface that was a bit more fine grained.

I think it is one of those... "Be Careful What You Wish For"... wishes
It is a bit scary to see all those checkboxes... but with it I'm able to craft exactly the export I want.

If I don't get my export right at first, I can continue to tick the boxes until I get exactly what I want.

I'm sure most won't like it...
But take a look at it and let me know what you think.

Apr 26, 2013 at 7:58 AM
One requestI add in import/export was to support a versioning of what is exported,
Too often during dev I have to change some model or change the was I export/import them.
Some data have also changed between the orchard versions, today we can't know exactly if we will be able to import from old orchard or modules still running with valuable data. With a version we can keep in import the old way and try adapting to new content.
Apr 26, 2013 at 8:14 AM
Edited Apr 26, 2013 at 8:15 AM
Thinking about other export I have been using, what is missing to Orchard if a kind of deep export/import.

This mean respecting relationship between object.

One exemple could be the small schema made by customer-product-order-orderdetail-invoice-payment, if I export an order, I would appreciate to have automatically exported its related detail lines, then products, eventually the customer, etc.

I think this is missing to Orchard, actually you may import objects without any warranty of success because the related data is not already imported.
Apr 26, 2013 at 9:31 AM
Edited Apr 26, 2013 at 9:31 AM
Personally I have never found the need for such fine grained control. All I ever want are the published versions. But that doesn't have to hold true for many others. Perhaps it could be configurable via settings:

O Simple Export
X Advanced Export

If you are building this, I would add a checkboxes to the top of each column, to be able to toggle the entire column on/off.
Perhaps do the same per row, so you're able to toggle an entire row on/off.
Extra checkboxes will make the UI even more intimidating of course. Perhaps it would be help if you could toggle checkboxes by dragging selection rectangles to save the user from all the clickity-clicks.

Perhaps add it to UserVoice and find out if there's demand for this.
Apr 26, 2013 at 9:32 AM
Orchard already supports exporting / importing related content. It is the responsibility of the drivers to do so correctly.
Apr 26, 2013 at 9:37 AM
Edited Apr 26, 2013 at 10:14 AM
Do you mean that if I export a User Profile, the driver will/would take care exporting the corresponding user, and the import will/should create the user if it doesn't exists ?
I will check but I don't think its working as you say for the average content items and modules ?
Apr 26, 2013 at 11:52 AM
If the drivers for the parts of that User Profile have been implemented as such, then yes. Orchard's driver API supports exporting and importing references to other content items by means of the ImportContentContext.GetItemFromSession() method.

Example import / export (taken from
protected override void Exporting(MessageTemplatePart part, ExportContentContext context) {
            context.Element(part.PartDefinition.Name).SetAttributeValue("Title", part.Title);
            context.Element(part.PartDefinition.Name).SetAttributeValue("Subject", part.Subject);
            context.Element(part.PartDefinition.Name).SetAttributeValue("Text", part.Text);
            context.Element(part.PartDefinition.Name).SetAttributeValue("IsLayout", part.IsLayout);
            // Here it gets interesting: "Layout" references another content item, and we can't simply serialize its Id because that may change across databases.
            // So instead, we leverage the content manager's GetItemMetadat method to ask for the content's Identity.
            // The resulting identity is built by various attached parts to the content item.
            // For example, the AutoroutePartHandler will contribute the DisplayAlias.
            // The IdentifierPartHandler will contribute a GUID.
            // This will of course only happen if the content item has these parts attached.
            // In our case, we don't require the content item to have either one attached, so we will have our own content handler contributing an identity.
            // We'll use this identity value in the Importing method to locate the referenced content item.
            if (part.Layout != null)
                context.Element(part.PartDefinition.Name).SetAttributeValue("Layout", context.ContentManager.GetItemMetadata(part.Layout).Identity.ToString());
        protected override void Importing(MessageTemplatePart part, ImportContentContext context) {
            context.ImportAttribute(part.PartDefinition.Name, "Title", x => part.Title = x);
            context.ImportAttribute(part.PartDefinition.Name, "Subject", x => part.Subject = x);
            context.ImportAttribute(part.PartDefinition.Name, "Text", x => part.Text = x);
            context.ImportAttribute(part.PartDefinition.Name, "IsLayout", x => part.IsLayout = XmlConvert.ToBoolean(x));
            // If "Layout" is specified, it will be the identoity of the referenced content item.
            // The context argument has a ethod called "GetItemFromSession" which will return the content item corresponding
            // to the identity value we used in the Exporting method.
            context.ImportAttribute(part.PartDefinition.Name, "Layout", x => {
                var layout = context.GetItemFromSession(x);
                if (layout != null && layout.Is<MessageTemplatePart>()) {
                    part.Layout = layout.As<MessageTemplatePart>();
Apr 26, 2013 at 12:16 PM
Ok, thanks for details, Bertrand already mentionned this when I declared a bug on Nwazet.commerce, but in this code, what if the corresponding part to this generated identity is not in the importing site database ?
Apr 26, 2013 at 12:36 PM
Then it simply won't be able to link with that missing content item. How this is to be handled varies per case, but it's up to the implementer of the Import method.

But I think I see your point: The issue arises when the user doesn't select all of the required content types when exporting. If you export items of Content Type A which have a references to content items of type B, these B content items will not be part of the export if you omit to select the B content type. Now when you import the exported file, you will miss all B content items. Currently, the only way around that is requiring the user to know that he should select both A and B types.

Perhaps the export system could be enhanced to automatically include related content types when it "detects" that a content item being exported has a reference to another content item, even when the user did not select its type.
I think this requires infrastructure that doesn't exists currently. But I think it is worth discussing it. Perhaps open an issue for it?
Apr 26, 2013 at 1:00 PM
Edited Apr 26, 2013 at 1:07 PM
You get my point, have you already exported data using SalesForce or MS Dynamics CRM...this is the way export should go: safely for datas and the whole site, because breaking data often breaks the site.
I won't open one more issue, my level of issues opening is raising the alarm level, if I had time I would have appreciated working rather than only reporting, on this because I think it is a very important feature (first versioning, next deeping in relations), but I have accumulated delays for non Orchard tasks so....
Apr 26, 2013 at 1:10 PM
Edited Apr 26, 2013 at 1:25 PM
It's no so difficult just building a parse tree of dependencies....
Apr 26, 2013 at 1:43 PM
I'm sure it's not difficult. The point is whether it should be done or not. Creating an issue gives the team a chance to discuss it during triage, hence my advice in doing that. Feel free to leave it as is.
Apr 26, 2013 at 2:04 PM
Right... So... Back to the User Interface... ;)

If you check out my fork that UI above already works... and I don't mind finishing at all.

A "toggle" at the top of the column is a good idea.
Another thought I had was to check if the Content Types were draftable, and disabling the draft checkbox accordingly.
Apr 26, 2013 at 7:39 PM
I embedded an image in the first post... Maybe it's not showing up for you...

Here is a link to it...

Let me know what you think...
Apr 26, 2013 at 7:44 PM
Edited Apr 26, 2013 at 7:57 PM
For me the UI is not mandatory,I would prefer more 'inside' improvements, have you a user documentation associated with your proposed UI modifications...but its only my opinion...
Apr 26, 2013 at 7:54 PM
@CSADNT ... ::sigh::
I understand you have entirely different interests than what I'm programming...
Which is fine really, but can you go start your own thread about it?
Apr 26, 2013 at 7:57 PM
have you a user documentation associated with your proposed documentations...but its only my opinion...
I think I may have brain damage trying to understand what you are adding to this conversation.

Are you trying to help? Or are you talking about an unrelated feature enhancement for no reason whatsoever?
Apr 26, 2013 at 8:29 PM
I am just refering to this, and if you have any other agressive participation like this, do not hesitate, :)
You may also give your opinion on the subject.
Apr 26, 2013 at 9:24 PM
Edited Apr 28, 2013 at 8:19 AM
Just to be complete, when somebody for exemple modify GoogleAnalytics import/export, all the old exported data become unreadable with the actual structure version, my opinion is that it would be better to implement a version in import/export rather than changing UI.
Apr 27, 2013 at 7:08 PM
Your points are all very valid...

What you don't seem to understand is...
Within the scope of this forum thread...
I don't care

I'm trying to give back one to the orchard community one thing.. That I made for myself in Orchard.. That I found useful...
And it probably wont ever happen, cause you came and trampled on the conversation.
Very literally... I'm talking about one thing, and you are talking about another...

I tried to bring the conversation back to what I'm talking about...
And then you go off on your own topic again...

How can I not get annoyed?
Apr 27, 2013 at 10:22 PM
Edited Apr 28, 2013 at 8:11 AM
My intention was just to give an opinion, I am listening and understanding what you are proposing in this thread.
Sorry. Feel free to continue without me :)
Apr 27, 2013 at 11:20 PM
Thanks Stanley for this contribution. I for one hope there will be more of this in the future.