Cofoundry 0.3.2 is out! This release includes a number of bug fixes and a handful of interesting new features. Here's what's included:
New List Data Annotations & Admin Controls
We've added three new data annotations for list-style controls:
- SelectList: Renders as a drop-down list of options.
- RadioList: Renders as list of radio buttons that allows only a single option to be selected.
- CheckboxList: Renders as list of checkbox options that allows multiple option selection.
Options can be expressed in three different ways:
- Enum: Use an enum type to derive the options from enum values.
- IListOptionSource: Define a class that generates option values at runtime.
- IListOptionApiSource: Define a class that tells Cofoundry how to extract options from an API or static file.
Examples
Enum SelectList
In this simple example, we just provide the enum type to the SelectList
data annotation to generate the options.
public enum ColorOption
{
Red,
Orange,
Yellow,
Green,
Blue,
Indigo,
Violet
}
public class ExampleDataModel : ICustomEntityDataModel
{
[SelectList(typeof(ColorOption))]
public ColorOption FavoriteColor { get; set; }
}
Output:
IListOptionSource RadioList
Using an IListOptionSource
provides more control of option text and values. Note that the option value should be the same type as the property value, although nullable types are supported which makes the field optional
For optional lists, the default null item text is None but you can customize this with the DefaultItemText
property:
using Cofoundry.Domain;
using System.Collections.Generic;
public class ExampleListOptionSource : IListOptionSource
{
public ICollection<ListOption> Create()
{
var options = new List<ListOption>();
options.Add(new ListOption("Negative", 1));
options.Add(new ListOption("Neutral", 2));
options.Add(new ListOption("Positive", 3));
return options;
}
}
public class ExampleDataModel : ICustomEntityDataModel
{
[RadioList(typeof(ExampleListOptionSource), DefaultItemText = "Not Specified")]
public int? Feedback { get; set; }
}
Output:
IListOptionApiSource CheckboxList
Using an API source give you the flexibility of pulling data from a dynamic source such as a database. The CheckBox list allows for multiple selection and should be used with a collection property type.
public class PetsApiOptionSource : IListOptionApiSource
{
public string Path => "/admin/api/pets";
public string NameField => "Title";
public string ValueField => "Id";
}
public class ExampleDataModel : ICustomEntityDataModel
{
[CheckboxList(typeof(PetsApiOptionSource))]
public ICollection<int> PetIds { get; set; }
}
Output:
Html Editor Improvements
We've had some feedback about issues with how the HTML editor validates and filters HTML code. We use TinyMCE as our html editor which has many settings, but until now you've only been able to customize the toolbar configuration.
First off, we've added documentation for the [Html]
data annotation demonstrating the existing functionality for customizing toolbars. For example you can already specify which toolbars to use using the default constructor:
public class ExampleDataModel : ICustomEntityDataModel
{
[Html(HtmlToolbarPreset.BasicFormatting, HtmlToolbarPreset.Media, HtmlToolbarPreset.Source)]
public string Content { get; set; }
}
Secondly we've added two different ways to specify custom TinyMCE configuration:
ConfigSource
Use a class to determine any additional configuration options to apply to the html editor. This should be a class that inherits from IHtmlEditorConfigSource
, which provides a .NET code generated set of options.
public class ExampleHtmlEditorConfigSource : IHtmlEditorConfigSource
{
private static readonly Dictionary<string, object> _options = new Dictionary<string, object>()
{
{ "resize", false },
{ "browser_spellcheck", false }
};
public IDictionary<string, object> Create()
{
return _options;
}
}
public class ExampleDataModel : ICustomEntityDataModel
{
[Html(ConfigSource = typeof(ExampleHtmlEditorConfigSource))]
public string Content { get; set; }
}
ConfigFilePath
You can also define a path to a json configuration file if you prefer to write your config in json.
public class ExampleDataModel : ICustomEntityDataModel
{
[Html(ConfigFilePath = "/content/html-editor-config.json")]
public string Content { get; set; }
}
Custom html editor attributes
If you're using a specific configuration often, you may want to consider deriving a new data annotation using HtmlAttribute
as the base.
[AttributeUsage(AttributeTargets.Property)]
public class HtmlWithCustomEditorAttribute : HtmlAttribute
{
public HtmlWithCustomEditorAttribute()
: base(HtmlToolbarPreset.BasicFormatting, HtmlToolbarPreset.Media, HtmlToolbarPreset.Source)
{
ConfigFilePath = "/content/html-editor-config.json";
Rows = 40;
}
}
public class ExampleDataModel : ICustomEntityDataModel
{
[HtmlWithCustomEditor]
public string Content { get; set; }
}
DocumentCollection Data Annotation
We've added a new [DocumentCollection]
data annotation to mirror similar functionality already available with the [ImageCollection]
attribute.
Document file types can be filtered using the optional FileExtensions
property.
public class ExampleDataModel : ICustomEntityDataModel
{
[Display(Name="Documents")]
[DocumentCollection(FileExtensions = new string[] { "pdf" })]
public ICollection<int> DocumentIds { get; set; }
}
Output:
Document Asset Downloads
Following feedback we've changed the behavior of document asset downloads so that by default they use "inline" content-disposition rather than "attachment", which better mirrors default webserver/browser behavior.
To force a file to download rather than display inline you can instead generate the link using one of the new alternative download methods on IDocumentAssetRouteLibrary
or IContentRouteLibrary
.
Bug Fixes
- #209 PageRegion EmptyContentMinHeight renders in non-edit mode
- #208 Embedding a script (e.g. tweet) in a page block breaks the json rendering in edit mode
- #213 Custom Entity Ordering: Re-ording one entity type removes ordering from another
- #214 "Pending draft" link in page list for custom entities is not working
- #212 Open pdf file on browser
Links
- Packages on NuGet
- Full 0.3.2 release notes on GitHub