private void GenerateForm()
{
var fieldNameToBindingNameMapper = new Dictionary<string, string>();
_bindingsXml = new XElement(CmsBindingsElementTemplate);
var layout = new XElement(CmsLayoutElementTemplate);
if (!string.IsNullOrEmpty(LayoutIconHandle))
{
layout.Add(new XAttribute("iconhandle", LayoutIconHandle));
}
// Add a read binding as the layout label
if (!string.IsNullOrEmpty(LayoutLabel))
{
var labelAttribute = new XAttribute("label", LayoutLabel);
layout.Add(labelAttribute);
}
else if (!string.IsNullOrEmpty(_dataTypeDescriptor.LabelFieldName))
{
layout.Add((new XElement(CmsNamespace + "layout.label", new XElement(CmsNamespace + "read", new XAttribute("source", _dataTypeDescriptor.LabelFieldName)))));
}
_panelXml = new XElement(MainNamespace + "FieldGroup");
string formLabel = !string.IsNullOrEmpty(FieldGroupLabel) ? FieldGroupLabel : _dataTypeDescriptor.Title;
if (!string.IsNullOrEmpty(formLabel))
{
_panelXml.Add(new XAttribute("Label", formLabel));
}
layout.Add(_panelXml);
foreach (var fieldDescriptor in _dataTypeDescriptor.Fields)
{
var bindingType = GetFieldBindingType(fieldDescriptor);
var bindingName = GetBindingName(fieldDescriptor);
fieldNameToBindingNameMapper.Add(fieldDescriptor.Name, bindingName);
var binding = new XElement(CmsNamespace + FormKeyTagNames.Binding,
new XAttribute("name", bindingName),
new XAttribute("type", bindingType));
if (fieldDescriptor.IsNullable)
{
binding.Add(new XAttribute("optional", "true"));
}
_bindingsXml.Add(binding);
if (!_readOnlyFields.Contains(fieldDescriptor.Name))
{
XElement widgetFunctionMarkup;
var label = fieldDescriptor.FormRenderingProfile.Label;
if (label.IsNullOrEmpty())
{
label = fieldDescriptor.Name;
}
var helptext = fieldDescriptor.FormRenderingProfile.HelpText ?? "";
if (!string.IsNullOrEmpty(fieldDescriptor.FormRenderingProfile.WidgetFunctionMarkup))
{
widgetFunctionMarkup = XElement.Parse(fieldDescriptor.FormRenderingProfile.WidgetFunctionMarkup);
}
else if (!DataTypeDescriptor.IsCodeGenerated && fieldDescriptor.FormRenderingProfile.WidgetFunctionMarkup == null)
{
// Auto generating a widget for not code generated data types
Type fieldType;
if (!fieldDescriptor.ForeignKeyReferenceTypeName.IsNullOrEmpty())
{
Type foreignKeyType;
try
{
foreignKeyType = Type.GetType(fieldDescriptor.ForeignKeyReferenceTypeName, true);
}
catch (Exception ex)
{
throw new InvalidOperationException("Failed to get referenced foreign key type '{0}'".FormatWith(fieldDescriptor.ForeignKeyReferenceTypeName), ex);
}
var referenceTemplateType = fieldDescriptor.IsNullable ? typeof(NullableDataReference<>) : typeof(DataReference<>);
fieldType = referenceTemplateType.MakeGenericType(foreignKeyType);
}
else
{
fieldType = fieldDescriptor.InstanceType;
}
var widgetFunctionProvider = StandardWidgetFunctions.GetDefaultWidgetFunctionProviderByType(fieldType);
if (widgetFunctionProvider != null)
{
widgetFunctionMarkup = widgetFunctionProvider.SerializedWidgetFunction;
}
else
{
continue;
}
}
else
{
continue;
}
var widgetRuntimeTreeNode = (WidgetFunctionRuntimeTreeNode)FunctionTreeBuilder.Build(widgetFunctionMarkup);
widgetRuntimeTreeNode.Label = label;
widgetRuntimeTreeNode.HelpDefinition = new HelpDefinition(helptext);
widgetRuntimeTreeNode.BindingSourceName = bindingName;
var element = (XElement)widgetRuntimeTreeNode.GetValue();
_panelXml.Add(element);
}
}
if (_showPublicationStatusSelector && _dataTypeDescriptor.SuperInterfaces.Contains(typeof(IPublishControlled)))
{
var placeholder = new XElement(MainNamespace + "PlaceHolder");
_panelXml.Remove();
placeholder.Add(_panelXml);
layout.Add(placeholder);
var publishFieldsXml = new XElement(MainNamespace + "FieldGroup", new XAttribute("Label", Texts.PublicationSettings_FieldGroupLabel));
placeholder.Add(publishFieldsXml);
var publicationStatusOptionsBinding = new XElement(CmsNamespace + FormKeyTagNames.Binding,
new XAttribute("name", PublicationStatusOptionsBindingName),
new XAttribute("type", typeof(object)));
_bindingsXml.Add(publicationStatusOptionsBinding);
var element =
new XElement(MainNamespace + "KeySelector",
new XAttribute("OptionsKeyField", "Key"),
new XAttribute("OptionsLabelField", "Value"),
new XAttribute("Label", Texts.PublicationStatus_Label),
new XAttribute("Help", Texts.PublicationStatus_Help),
new XElement(MainNamespace + "KeySelector.Selected",
new XElement(CmsNamespace + "bind", new XAttribute("source", PublicationStatusBindingName))),
new XElement(MainNamespace + "KeySelector.Options",
new XElement(CmsNamespace + "read", new XAttribute("source", PublicationStatusOptionsBindingName)))
);
publishFieldsXml.Add(element);
var publishDateBinding = new XElement(CmsNamespace + FormKeyTagNames.Binding,
new XAttribute("name", "PublishDate"),
new XAttribute("type", typeof(DateTime)),
new XAttribute("optional", "true"));
_bindingsXml.Add(publishDateBinding);
publishFieldsXml.Add(
new XElement(MainNamespace + "DateTimeSelector",
new XAttribute("Label", Texts.PublishDate_Label),
new XAttribute("Help", Texts.PublishDate_Help),
new XElement(CmsNamespace + "bind",
new XAttribute("source", "PublishDate"))));
var unpublishDateBinding = new XElement(CmsNamespace + FormKeyTagNames.Binding,
new XAttribute("name", "UnpublishDate"),
new XAttribute("type", typeof(DateTime)),
new XAttribute("optional", "true"));
_bindingsXml.Add(unpublishDateBinding);
publishFieldsXml.Add(
new XElement(MainNamespace + "DateTimeSelector",
new XAttribute("Label", Texts.UnpublishDate_Label),
new XAttribute("Help", Texts.UnpublishDate_Help),
new XElement(CmsNamespace + "bind",
new XAttribute("source", "UnpublishDate"))));
}
var formDefinition = new XElement(CmsFormElementTemplate);
formDefinition.Add(_bindingsXml);
formDefinition.Add(layout);
if (CustomFormDefinition == null)
{
_generatedForm = formDefinition.ToString();
}
else
{
if (_dataTypeDescriptor.SuperInterfaces.Contains(typeof(IPublishControlled)))
{
fieldNameToBindingNameMapper.Add("PublishDate", "PublishDate");
fieldNameToBindingNameMapper.Add("UnpublishDate", "UnpublishDate");
}
Func<XElement, IEnumerable<XAttribute>> getBindingsFunc =
doc => doc.Descendants(CmsNamespace + "binding").Attributes("name")
.Concat(doc.Descendants(CmsNamespace + "bind").Attributes("source"))
.Concat(doc.Descendants(CmsNamespace + "read").Attributes("source"));
// Validation
foreach (var bindingNameAttribute in getBindingsFunc(CustomFormDefinition.Root))
{
var bindingName = bindingNameAttribute.Value;
if (!IsNotFieldBinding(bindingName) && !fieldNameToBindingNameMapper.ContainsKey(bindingName))
{
throw new ParseDefinitionFileException("Invalid binding name '{0}'".FormatWith(bindingName), bindingNameAttribute);
}
}
var formDefinitionElement = new XElement(CustomFormDefinition.Root);
foreach (var bindingNameAttribute in getBindingsFunc(formDefinitionElement).Where(attr => !IsNotFieldBinding(attr.Value)))
{
bindingNameAttribute.Value = fieldNameToBindingNameMapper[bindingNameAttribute.Value];
}
if (!string.IsNullOrEmpty(FieldGroupLabel))
{
foreach (var fieldGroupElement in formDefinitionElement.Descendants(MainNamespace + "FieldGroup"))
{
if (fieldGroupElement.Attribute("Label") == null)
{
fieldGroupElement.Add(new XAttribute("Label", FieldGroupLabel));
}
}
}
_generatedForm = formDefinitionElement.ToString();
_panelXml = formDefinitionElement.Elements().Last().Elements().LastOrDefault();
}
}