In the Using Converge blog post I described how I upgraded the simple Starter Kit site from Umbraco version 7 to Umbraco 8. One of the details that I skipped over was how I dealt with the Terratype property editor, which is only available for Umbraco 7.
If you create a separate instance of Umbraco 8 and install the Starter Kit on that you will see that it replaces the use of Terratype with an Open Street Maps property editor. It made sense to copy this idea and use the same property editor for my upgrade.
To install the new property editor, I simply copied the "OsmMaps" folder structure from under "App_Plugins" into my V8 project.
Once this is done, "Open street maps" appears as an available property editor for data types.
To figure out how to create a data type converter, I need to compare the old data type in V7 with what it would become in V8. So, I created a new data type in the back office using the Open Street Maps property editor that I had installed above.
Looking at the two in Converge highlighted the differences between them.
These were the changes that I needed to make to the data type.
As the data type had been updated, any document type properties that use that data type will also need to be updated. Looking at the old "Contact" document type you can see that the "map" property needs to be updated.
Here, the following changes need to be made.
Using a similar method, I created some new content in V8 to see how a map reference would be stored in a property.
You can see that in V7 using TerraType, "Your Address" is stored as a JSON string. For the Open Street Maps property editor, we will need to change this to a comma-separated string (like "Map" in the V8 content).
In Converge I have provided the ability to convert a data type, so that the converted data type is compared and merged into the destination instance. To do this you create a new class which implements the "IDataTypeConverter" interface.
The interface requires the following methods to be implemented.
The name and description of the converter will be displayed in the Settings section of Converge, under Data Type Converters. Here, the converter can be switched on or off.
This method determines whether this converter should be applied to the property editor alias provided. It should return true if the conversion should be applied, false otherwise. In this instance I check if it is "Terratype", in which case it will be converted.
This method should return the minimum version of Umbraco that this converter should be applied to. It will not be used on versions prior to what is stated here. This conversion should be applied to any Umbraco 8 instance, so here we return 8.0.0.
This method does the actual work of converting the data type, here we change the Name, Property Editor Alias and Database Type as described above.
This method converts properties of any document type that use the data type that we are converting. Here we update the Data Type Name and Property Editor Alias.
This method converts the required properties of any content. Here we update the Property Editor Alias and use the JSON to create the comma-separated string required by Open Street Maps.
The full code is below.
public class TerratypeDataTypeConverter : IDataTypeConverter { public string GetConverterName() { return "Terratype"; } public string GetConverterDescription() { return "Convert Terratype to OsmMaps"; } public bool ConvertPropertyEditorAlias(string propertyEditorAlias) { return propertyEditorAlias == "Terratype"; } public Version GetMinumumUmbracoVersion() { return new Version(8,0,0); } public void ConvertDataType(DataTypeModel remoteDataType) { remoteDataType.Name = "Contact - Your Address - OsmMap"; remoteDataType.PropertyEditorAlias = "Our.Umbraco.OsmMaps"; remoteDataType.DatabaseType = "Nvarchar"; remoteDataType.Configuration = "{\"lat\":55.40626,\"lng\":10.3884,\"zoomlevel\":15}"; } public void ConvertPropertyType(PropertyTypeModel remotePropertyType) { remotePropertyType.DataTypeName = "Contact - Your Address - OsmMap"; remotePropertyType.PropertyEditorAlias = "Our.Umbraco.OsmMaps"; } public void ConvertProperty(PropertyModel remoteProperty) { remoteProperty.PropertyEditorAlias = "Our.Umbraco.OsmMaps"; // Example Terratype: { "zoom": 13, "position": { "id": "WGS84", "datum": "55.406321,10.387015" } } // Example OsmMaps: 55.40622012982414,10.388404726982117,18 try { // Can have different values for different languages foreach (var propertyValue in remoteProperty.Values) { string zoom = null; string datum = null; if (!String.IsNullOrWhiteSpace(propertyValue.Value)) { // Expecting Terratype JSON as in example above JObject remoteConfig = JObject.Parse(propertyValue.Value); // Get the zoom property from the JSON zoom = remoteConfig.Value<string>("zoom"); // Get the position object JObject position = remoteConfig.Value<JObject>("position"); if (position != null) { // Get the datum property from the position object datum = position.Value<string>("datum"); } if (!String.IsNullOrWhiteSpace(datum) && !String.IsNullOrWhiteSpace(zoom)) { // Build the expected value for OsmMaps (see above example) and update the property value propertyValue.Value = datum + "," + zoom; } } } } catch (Exception) { // Ignore error (e.g. JSON is invalid) } } }
The ConvergeConverters class has been made available to add the new converter to Converge, it includes the static method AddDataTypeConverter. To call this at startup in Umbraco 8, we need to create a composer and component. A full description of how these work is available on the Our Umbraco site. Here is my code to add the new data type converter.
public class StartupComponent : IComponent { public void Initialize() { ConvergeConverters.AddDataTypeConverter(new TerratypeDataTypeConverter()); } public void Terminate() { } }
And here is the Composer to trigger it.
[RuntimeLevel(MinLevel = RuntimeLevel.Run)] public class StartupComposer : ComponentComposer<StartupComponent> { }
Note, all of these interfaces and classes exist under the "Com.StuartMullinger.Converge" namespace. These will only be available to you if you have installed Converge using the NuGet package. Otherwise, you will need to add the reference to Converge.dll to your project yourself. The following using statements are required.
using Com.StuartMullinger.Converge.Converters; using Com.StuartMullinger.Converge.Models;
Within the Settings section of Converge there is a Data Type Converters tab and at the bottom of a long list we can see the new Terratype converter that was added.
Running another compare will show that the data type, document type and content have been updated as required.
Finally, I could merge the V7 content and check that the map feature is working correctly. In the back office the map displays and updates correctly for the property.
And, on the site the "Contact" page displays correctly.
If you want to find out more about using Converge then please take a look at the user guide.