Skip to main content
Home  ›  Docs › Export / Import

Export / Import with Extensive Features

Warning ⚠️: New Docs Available

These are old docs and we haven't found the time to completely move them. You will find comprehensive new docs on

Introduced in Version 05.04.00

In general the export just exports everything you selected without with the fewest possible modifications. But the Import is the real magic bullet. It does many things including:

  1. Fully automated: We're expecting the importing user to be low-tech, so the import runs without asking any questions
  2. Using Transactions: we're actually creating hundreds, sometimes thousands of records. Almost all of them are done in 1 transaction to ensure that any failure would result in a full rollback.
  3. Link-Fixing [since 05.04.01]: References to files in the source system like File:493 are re-mapped to the same file in the target system
  4. Complex language matching: since the export can contain many languages not available in the target system, and might also be missing some necessary languages, 2SexyContent will do the utmost to provide the optimal values for the target language.  

The Import Sequence in General since v.05.04

 It sometimes help to know more about the internals of something, especially if it's as complex as import/export. Here the birds-eye view of what happens:

  1. If it's a ZIP, unpack it and get the XML-Package with all the data; if it's already an XML, use that
  2. Verify version/compatibility
  3. Import portal files first (this is necessary to later on correct File:## links) [since 05.04.01]
  4. Import Content-Type-Definitions (this is like creating tables in a database)
  5. Import templates (the @Razor and [Token] files and folders with all helper files (must also happen before, because some Entities will refer to this)
  6. Configure the templates in the database
  7. Import Entities (the content in the tables)
    1. With extensive language matching
    2. And correcting links to internal files if found (the File:## links) [since 05.04.01]
  8. Log everything...
  9. ...and show confirmation message

Import Language Matching Explained

When importing data, we have the following scenarios

  1.  The import file can contain
    1. a single language - with or without language code
    2. multiple languages - but only the primary-language will certainly contain all values, all other languages might be partially translated or refer to the value of other languages
  2. The target system could be
    1. singe language - without a language code
    2. single language - with a language code
    3. multiple languages - with a primary language that can differ from the import-system

After the import, the following should be achieved

  1. The target system must have all entities with real values for the primary-language of the target system
  2. The target system should have as many other values as possible pre-filled from the import-system
  3. If the languages don't match fully (like the import being for en-us, the target expecting en-uk), the target should contain the best fall-back
  4. The target system should have the same sharing of values as the source system (and the same read/write-sharing), so if the source shared the title in FR and ES and the target has these languages too, then the target should still share this value so that changing either FR or ES will change both

The logic at value-level

The language-matching happens at the lowest level, at the value level. The full logic used (for every single value) is as follows: Go through each attribute in source (so for example, look at the Teaser of a Content-Type Product) and do the following language-matchings for each target language.

  1. Go through each language in target, always do primary first, then all other target languages from A-Z
    1. Try to get a value for the current target language by doing this:
      1. Try to find exact language match (en-us for en-us) - if found, use this
      2. Otherwise try to find un-exact language match (e.g. en-uk for en-us)
        1. If there is exactly one un-exact language value, use this
        2. If there are multiple values (like target expects en-us, source has en-uk and en-au)
          1. If possible, use source primary language (if import had en-au as primary, use that)
          2. Otherwise try to find languages with matching country, because fr-fr is usually better than fr-ch
          3. If neither is the case, just use the first un-exact language when ordered by alphabet (so de-at comes before de-ch)
      3. If no value can be found
        1. If target language is primary (the primary cannot stay blank), then use source primary language
        2. If the target language we're trying to fill is not primary, it can stay blank (this will result in a fallback to the primary) 
    2. Don't import yet, just assign the value (as pointer) – to the internal list of values to import
      1. If value has not been assigned, add with original ReadOnly state
        Example: second target language is being matched and found. It should now point to the correct value and if the original pointer was read-only (like in shared-value situations), then it will also be read-only.
      2. If value has already been assigned to the list, add just dimension with original ReadOnly state
        Example: this is the third language it's checking and it's using the same value as a language before (same meaning same pointer, not same text), then it also must use the same pointer and ensure that it has the same read/write relationship as in the original system.
      3. Set ReadOnly to false if target language is primary
        Example: target primary is FR, source primary was EN. Then the original relationship could have been read-only, but the primary must always be read/write, so it's corrected.
  2. Correct ReadOnly states
    1. Sometimes we might import shared information resulting in all referring to this as a read-only relationship. This is technically correct but a hasslet to edit later on, so: Set ReadOnly to false on first language if ReadOnly for all languages (for a specific value) is true 

Correcting Links to Files (v. 05.04.01)

The export-file of 2SexyContent 05.04.01 and later contains an additional list of all linked files (fields of type Hyperlink pointing to a File:###). The list contains the original ID and the location of the file in the portal-content folder when it was exported.

  1. Note that the import-sequence will automatically import all content-files found in the ZIP (you have to create the ZIP yourself, the export doesn't do this yet)
  2. Note also that if a file already exists, it will not be replaced

After these steps, 2SexyContent reviews the folder structure and corrects links. Here's an example:

  • The source data has an entity of type Product with a field Image linking to the File:8437
  • The source data has a list of files placing the file with the ID 8437 in the folder "/Products/Packshots/Packshot-Cornflakes.jpg"
  • The target system didn't have this folders or files, so this was all created and imported, but of course this file has a different ID in the new DNN
  • So the import-data gets rewritten to File:1094 (which points to the same location in the new system)

Importing Content-Type Definitions

A few infos regarding content-types definitions 

  1. Each Zone (DNN-Portal) and App (a logical group of related things in this Zone) can only contain a content-type once. Note that for now, each Zone (DNN-Portal) just has one App, so for now you could say: each content-type can only exist once per portal.
  2. Note that a content-type is actually referred to by an internal name - usually a GUID. So two types called "Address" but using different GUIDs are different content-types.
  3. When importing a content-type this always works as follows:
    1. If the content-type didn't exist yet, create it
    2. If it did exist, don't overwrite anything
    3. If it did exist and the new import contains some enhancements (new fields, etc.) then this can be imported. So existing content-types could only grow, never change

The reason we did this is as follows: a import of an existing content-type should only happen in one of these cases:

  • if you re-export data from a source-system (because you changed something, and want to import it again)
  • if you exported multiple packages from a source-system (like a gallery with a lightbox and another with google-maps) and import both
  • if an export from DNN #1 was installed on DNN #2 and #3, then improvements were made on #2 and re-imported on #3

Now one of the main values of 2SexyContent is that I can customize these things in the target system, and a re-import shouldn't break anything I customized. So to ensure this, we only add things that the target system didn't have yet, and don't overwrite anything that was already in it.

To Document and ToDo

The following is not nicely documented yet

  1. Structure of the XML - please just look at one and figure it out yourself
  2. Structure of the ZIP-File - please just unpack one and figure it out yourself

The following is not nicely automated yet

  1. Manual re-mapping of languages from source to target
    In the rare cases this is necessary - for example if the source package contains English as primary and Russian as secondary, and you would like to import it to a Ukranian system. Then you probably would prefer Russian to English in your target system. To do this, just edit the XML as needed.
  2. Export-ZIP-creation
    This is simply not done yet and we probably won't get to this for a while, as it's not on the main priorities. Please create them manually - or contribute code that we can include in a future distribution
  3. Relationship-Export and import
    Entity-relationships are not handled yet
  4. Manual language-selection on export
    This is not possible ATM and not a priority. If you want to ensure that a language is not recognized in a following import, just edit the XML file.