diff --git a/README.md b/README.md index 17a80b3..57643a7 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Property List is a property editor for making repeatable lists of a datatype for Umbraco 7.6+ +![Property List Editor](docs/img/screenshots/property-list-property-editor-02.png) + ## Getting Started ### Installation @@ -40,6 +42,11 @@ To clone it locally click the "Clone in Windows" button above or run the followi cd umbraco-property-list .\build.cmd + +### Documentation + +For details on how to use the Property List package, please refer to our [Developers Guide](docs/developers-guide.md) documentation. + --- ## Known Issues @@ -70,6 +77,10 @@ Have a question? * [Lee Kelleher](https://github.com/leekelleher) * [Matt Brailsford](https://github.com/mattbrailsford) +If you enjoy using Property List on your commercial Umbraco projects, please do consider supporting our work on other open-source Umbraco packages. + +Become a UMCO Patron! + ## License Copyright © 2017 UMCO, Our Umbraco and [other contributors](https://github.com/umco/umbraco-property-list/graphs/contributors) diff --git a/appveyor.yml b/appveyor.yml index f784139..33c066f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ image: Visual Studio 2017 # version format -version: 1.0.0.{build} +version: 1.0.1.{build} # UMBRACO_PACKAGE_PRERELEASE_SUFFIX if a rtm release build this should be blank, otherwise if empty will default to alpha # example UMBRACO_PACKAGE_PRERELEASE_SUFFIX=beta diff --git a/docs/developers-guide.md b/docs/developers-guide.md index 5a2a960..5c3eadf 100644 --- a/docs/developers-guide.md +++ b/docs/developers-guide.md @@ -1,2 +1,95 @@ # Property List - Developers Guide +### Contents + +1. [Introduction](#introduction) +2. [Getting Set Up](#getting-set-up) +3. [Configuring Property List](#configuring-property-list) +4. [Editing Property List](#editing-property-list) +5. [Rendering Property List](#rendering-property-list) +6. [Useful Links](#useful-links) + +--- + +### Introduction + +**Property List** is property editor for making repeatable lists for Umbraco 7.6+, similar to the default [**Multiple Textbox aka Repeatable textstrings**](https://our.umbraco.com/documentation/getting-started/backoffice/property-editors/built-in-property-editors/Multiple-Textbox) editor. However **Property List** has the ability to use any data-type to define the type of the list. By using data-types, we can use any property-editor to power the list, opening up to community property-editors, such as [**Styled Textbox**](https://our.umbraco.com/projects/backoffice-extensions/styled-textbox/). + +--- + +### Getting Set Up + +Before you get started, there are a number of things you will need: + +1. Umbraco 7.6.0+ +2. The **Property List** package installed + +--- + +### Configuring Property List + +The **Property List** property editor is set-up/configured in the same way as any standard property editor, via the *Data Types* admin interface. To set-up your Property List property, create a new *Data Type* and select **Property List** from the list of available property editors. + +You should then be presented with the **Property List** property editors prevalue editor as shown below. + +![Property List - Prevalue Editor](img/screenshots/property-list-data-prevalues.png) + +The prevalue editor allows you to configure the following properties. + +| Member | Type | Description | +|-----------------|---------|-------------| +| Data Type | Picker | Select the data-type you wish to use for your **Property List**. By default, the **Textstring** will be pre-selected. | +| Min Items | Integer | Sets the minimum number of items that should be allowed in the list. If greater than `0`, **Property List** will pre-populate your list with the minimum amount of allowed items and prevent deleting items below this level. Defaults to `0`. +| Max Items | Integer | Sets the maximum number of items that should be allowed in the list. If greater than `0`, **Property List** will prevent new items being added to the list above this threshold. Defaults to `0`. | +| Hide Label | Boolean | Enabling this will hide the property editors label and expand the **Property List** property editor to the full with of the editor window. | + +Once your data-type has been configured, set-up a property on your page document-type using your new data-type and you are set to start editing. + +--- + +### Editing Property List + +When viewing a **Property List** editor for the first time, you'll be presented with a simple "Add item" button to get you started. + +![Property List - Add Item](img/screenshots/property-list-property-editor-01.png) + +Clicking the "Add item" button will add a new item in the list. + +To reorder the list, click and drag the move icon up and down to place the items in the order you want. + +![Property List - Add Item](img/screenshots/property-list-property-editor-02.png) + +To remove an item from the list, click the trash can icon. If the minimum number of items is reached, then the trash can icon will disappear, this prevents going below the minimum allowed number of items. + +--- + +### Rendering Property List + +To render the stored value of your **Property List** property, a built-in value-converter is provided for you. By calling the `GetPropertyValue` method with a generic type of `IEnumerable` and the stored value will be returned as a list of `string` entity. + +Please note, that the type of the `IEnumerable` will depend on the data-type you have selected. The default **Textstring** will return a `string` object-type. If you select a different data-type, you will need to update the object-type (`T`) accordingly. + +Example: + +```csharp +@inherits Umbraco.Web.Mvc.UmbracoViewPage +@{ + var items = Model.GetPropertyValue>("myPropertyAlias"); + +
    + @foreach(var item in items) + { +
  • @item
  • + } +
+} +``` + +If you are using Umbraco's ModelsBuilder feature, then the underlying object-type will automatically be wired up for you. You don't need to worry about this part. + +--- + +### Useful Links + +* [Source Code](https://github.com/umco/umbraco-property-list) +* [Our Umbraco Project Page](http://our.umbraco.org/projects/backoffice-extensions/property-list) diff --git a/docs/img/screenshots/property-list-data-prevalues.png b/docs/img/screenshots/property-list-data-prevalues.png new file mode 100644 index 0000000..6de55c9 Binary files /dev/null and b/docs/img/screenshots/property-list-data-prevalues.png differ diff --git a/docs/img/screenshots/property-list-property-editor-01.png b/docs/img/screenshots/property-list-property-editor-01.png new file mode 100644 index 0000000..cc49a5b Binary files /dev/null and b/docs/img/screenshots/property-list-property-editor-01.png differ diff --git a/docs/img/screenshots/property-list-property-editor-02.png b/docs/img/screenshots/property-list-property-editor-02.png new file mode 100644 index 0000000..4ede366 Binary files /dev/null and b/docs/img/screenshots/property-list-property-editor-02.png differ diff --git a/src/Our.Umbraco.PropertyList/ValueConverters/PropertyListValueConverter.cs b/src/Our.Umbraco.PropertyList/ValueConverters/PropertyListValueConverter.cs index 9a4895f..d1dbdf8 100644 --- a/src/Our.Umbraco.PropertyList/ValueConverters/PropertyListValueConverter.cs +++ b/src/Our.Umbraco.PropertyList/ValueConverters/PropertyListValueConverter.cs @@ -19,14 +19,16 @@ public class PropertyListValueConverter : PropertyValueConverterBase, IPropertyV { public override bool IsConverter(PublishedPropertyType propertyType) { - return propertyType.PropertyEditorAlias.Equals(PropertyEditorKeys.Alias); + return propertyType.PropertyEditorAlias.InvariantEquals(PropertyEditorKeys.Alias); } public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) { var data = source?.ToString(); if (string.IsNullOrWhiteSpace(data)) + { return null; + } var innerPropertyType = this.GetInnerPublishedPropertyType(propertyType); @@ -41,14 +43,18 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o { var model = JsonConvert.DeserializeObject(data); if (model != null) + { items.AddRange(model.Values); + } } else { // otherwise we assume it's XML var elements = XElement.Parse(data); if (elements != null && elements.HasElements) + { items.AddRange(elements.XPathSelectElements("value").Select(x => x.Value)); + } } var values = new List(); @@ -79,14 +85,26 @@ public override object ConvertSourceToObject(PublishedPropertyType propertyType, } } - // Force result to right type + // Ensure the result is of the correct type var targetType = innerPropertyType.ClrType; var result = Array.CreateInstance(targetType, objects.Count); for (var i = 0; i < objects.Count; i++) { var attempt = objects[i].TryConvertTo(targetType); if (attempt.Success) + { result.SetValue(attempt.Result, i); + } + else + { + // NOTE: At this point `TryConvertTo` can't convert to the `targetType`. + // This may be a case where the `targetType` is an interface. + // We can attempt to cast it directly, as a last resort. + if (targetType.IsInstanceOfType(objects[i])) + { + result.SetValue(objects[i], i); + } + } } return result;