Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8610f69c88 | |||
| 34b4209de7 | |||
| b6145c9275 | |||
| f51ca65659 | |||
| d026af9fd2 | |||
| 11fff5da1a | |||
| 788a5dd720 | |||
| 24e232b2cc | |||
| 5bdcb23933 | |||
| 34b3ed3b47 | |||
| 50a486a9ac | |||
| 4f4128a744 | |||
| 4851797a83 | |||
| 54a435dce7 | |||
| 03a170d716 | |||
| 37976abc84 | |||
| f7e96438be | |||
| f1c3caae2d | |||
| 8f8078e12f | |||
| dbc9b872d8 | |||
| eef1b94586 | |||
| 9bbf366fe2 | |||
| 368a9f6c07 | |||
| d3b3f80f3d | |||
| 11f7881dd7 | |||
| 9894357469 | |||
| 146a3770a1 | |||
| caf9d1ac15 | |||
| 614595ceb3 | |||
| d1b21a1ca7 | |||
| 54bc507049 | |||
| 037585458c | |||
| f52649eb9e | |||
| 423fedb954 | |||
| b39312ccd2 | |||
| b9c4be0bb6 | |||
| 29285607a9 | |||
| 909b87cea0 | |||
| 3d25f75fb9 | |||
| 6fa713f88e | |||
| d9982fe3a2 | |||
| 588bdfe429 | |||
| 0174f6d78b | |||
| 84144b6206 | |||
| 27910e8d22 | |||
| 9bf413207f | |||
| e5cd3d0cb0 | |||
| 032ee958c1 | |||
| ef5bd7ccc8 | |||
| 7839e4a992 | |||
| 408c178348 |
+13
-9
@@ -55,11 +55,15 @@ module.exports = function(grunt) {
|
||||
'app/controllers/controller.js',
|
||||
'app/controllers/config.controller.js',
|
||||
'app/directives/archetypeproperty.js',
|
||||
'app/directives/archetypesubmitwatcher.js',
|
||||
'app/directives/archetypecustomview.js',
|
||||
'app/directives/localize.js',
|
||||
'app/services/localization.js',
|
||||
'app/helpers/labelhelpers.js',
|
||||
'app/resources/propertyeditor.js'
|
||||
'app/directives/archetypeLocalize.js',
|
||||
'app/services/archetypeLocalizationService.js',
|
||||
'app/helpers/sampleLabelHelpers.js',
|
||||
'app/resources/archetypePropertyEditorResource.js',
|
||||
'app/services/archetypeService.js',
|
||||
'app/services/archetypeLabelService.js',
|
||||
'app/services/archetypeCacheService.js'
|
||||
],
|
||||
dest: '<%= basePath %>/js/archetype.js'
|
||||
}
|
||||
@@ -73,7 +77,7 @@ module.exports = function(grunt) {
|
||||
expand: true
|
||||
},
|
||||
dll: {
|
||||
cwd: 'app/Umbraco/Umbraco.Archetype/bin/Release/',
|
||||
cwd: 'app/Umbraco/Umbraco.Archetype/bin/Debug/',
|
||||
src: 'Archetype.dll',
|
||||
dest: '<%= dest %>/bin/',
|
||||
expand: true
|
||||
@@ -163,10 +167,10 @@ module.exports = function(grunt) {
|
||||
|
||||
assemblyinfo: {
|
||||
options: {
|
||||
files: ['app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj'],
|
||||
files: ['app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj', 'app/Umbraco/Umbraco.Archetype/Archetype.Courier.csproj'],
|
||||
filename: 'VersionInfo.cs',
|
||||
info: {
|
||||
version: '<%= (pkgMeta.version.indexOf("-") ? pkgMeta.version.substring(0, pkgMeta.version.indexOf("-")) : pkgMeta.version) %>',
|
||||
version: '<%= (pkgMeta.version.indexOf("-") > 0 ? pkgMeta.version.substring(0, pkgMeta.version.indexOf("-")) : pkgMeta.version) %>',
|
||||
fileVersion: '<%= pkgMeta.version %>'
|
||||
}
|
||||
}
|
||||
@@ -199,9 +203,9 @@ module.exports = function(grunt) {
|
||||
}
|
||||
},
|
||||
dist: {
|
||||
src: ['app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj'],
|
||||
src: ['app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj','app/Umbraco/Archetype.Courier/Archetype.Courier.csproj'],
|
||||
options: {
|
||||
projectConfiguration: 'Release',
|
||||
projectConfiguration: 'Debug',
|
||||
targets: ['Clean', 'Rebuild'],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ Install the selected <a href='https://github.com/imulus/Archetype/releases'>rele
|
||||
|
||||
|
||||
## Official Docs ##
|
||||
http://imulus.github.io/Archetype
|
||||
https://github.com/kgiszewski/ArchetypeManual
|
||||
|
||||
Follow us on Twitter https://twitter.com/ArchetypeKit
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Archetype.Extensions;
|
||||
using Archetype.Models;
|
||||
using Archetype.PropertyConverters;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Courier.Core;
|
||||
using Umbraco.Courier.Core.Logging;
|
||||
using Umbraco.Courier.Core.ProviderModel;
|
||||
using Umbraco.Courier.DataResolvers;
|
||||
using Umbraco.Courier.ItemProviders;
|
||||
@@ -27,7 +25,7 @@ namespace Archetype.Courier.DataResolvers
|
||||
{
|
||||
get
|
||||
{
|
||||
return Archetype.Constants.PropertyEditorAlias;
|
||||
return Constants.PropertyEditorAlias;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +54,7 @@ namespace Archetype.Courier.DataResolvers
|
||||
if (item.Prevalues != null && item.Prevalues.Count > 0)
|
||||
{
|
||||
var prevalue = item.Prevalues[0];
|
||||
if (prevalue.Alias.InvariantEquals(Archetype.Constants.PreValueAlias) && !string.IsNullOrWhiteSpace(prevalue.Value))
|
||||
if (prevalue.Alias.InvariantEquals(Constants.PreValueAlias) && !string.IsNullOrWhiteSpace(prevalue.Value))
|
||||
{
|
||||
var config = JsonConvert.DeserializeObject<ArchetypePreValue>(prevalue.Value);
|
||||
|
||||
@@ -77,16 +75,26 @@ namespace Archetype.Courier.DataResolvers
|
||||
{
|
||||
if (propertyData != null && propertyData.Value != null)
|
||||
{
|
||||
var dataTypeId = ExecutionContext.DatabasePersistence.GetNodeId(propertyData.DataType, NodeObjectTypes.DataType);
|
||||
var fakePropertyType = this.CreateDummyPropertyType(dataTypeId, this.EditorAlias);
|
||||
var dataType = ExecutionContext.DatabasePersistence.RetrieveItem<DataType>(new ItemIdentifier(propertyData.DataType.ToString(),
|
||||
ProviderIDCollection.dataTypeItemProviderGuid));
|
||||
|
||||
var converter = new ArchetypeValueConverter();
|
||||
var archetype = (ArchetypeModel)converter.ConvertDataToSource(fakePropertyType, propertyData.Value, false);
|
||||
//Fetch the Prevalues for the current Property's DataType (if its an 'Archetype config')
|
||||
var prevalue = dataType.Prevalues.FirstOrDefault(x => x.Alias.ToLowerInvariant().Equals("archetypeconfig"));
|
||||
var archetypePreValue = prevalue == null
|
||||
? null
|
||||
: JsonConvert.DeserializeObject<ArchetypePreValue>(prevalue.Value,
|
||||
ArchetypeHelper.Instance.JsonSerializerSettings);
|
||||
RetrieveAdditionalProperties(ref archetypePreValue);
|
||||
|
||||
//Deserialize the value of the current Property to an ArchetypeModel and set additional properties before converting values
|
||||
var sourceJson = propertyData.Value.ToString();
|
||||
var archetype = JsonConvert.DeserializeObject<ArchetypeModel>(sourceJson, ArchetypeHelper.Instance.JsonSerializerSettings);
|
||||
RetrieveAdditionalProperties(ref archetype, archetypePreValue);
|
||||
|
||||
if (archetype != null)
|
||||
{
|
||||
// get the `PropertyItemProvider` from the collection.
|
||||
var propertyItemProvider = ItemProviderCollection.Instance.GetProvider(ProviderIDCollection.propertyDataItemProviderGuid, this.ExecutionContext);
|
||||
var propertyItemProvider = ItemProviderCollection.Instance.GetProvider(ProviderIDCollection.propertyDataItemProviderGuid, ExecutionContext);
|
||||
|
||||
foreach (var property in archetype.Fieldsets.SelectMany(x => x.Properties))
|
||||
{
|
||||
@@ -94,10 +102,10 @@ namespace Archetype.Courier.DataResolvers
|
||||
continue;
|
||||
|
||||
// create a 'fake' item for Courier to process
|
||||
var fakeItem = new ContentPropertyData()
|
||||
var fakeItem = new ContentPropertyData
|
||||
{
|
||||
ItemId = item.ItemId,
|
||||
Name = string.Format("{0} [{1}: Nested {2} ({3})]", new[] { item.Name, this.EditorAlias, property.PropertyEditorAlias, property.Alias }),
|
||||
Name = string.Format("{0} [{1}: Nested {2} ({3})]", new[] { item.Name, EditorAlias, property.PropertyEditorAlias, property.Alias }),
|
||||
Data = new List<ContentProperty>
|
||||
{
|
||||
new ContentProperty
|
||||
@@ -119,7 +127,7 @@ namespace Archetype.Courier.DataResolvers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<ArchetypeDataResolver>(string.Concat("Error packaging data value: ", fakeItem.Name), ex);
|
||||
CourierLogHelper.Error<ArchetypeDataResolver>(string.Concat("Error packaging data value: ", fakeItem.Name), ex);
|
||||
}
|
||||
|
||||
// pass up the dependencies and resources
|
||||
@@ -135,7 +143,7 @@ namespace Archetype.Courier.DataResolvers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<ArchetypeDataResolver>(string.Concat("Error extracting data value: ", fakeItem.Name), ex);
|
||||
CourierLogHelper.Error<ArchetypeDataResolver>(string.Concat("Error extracting data value: ", fakeItem.Name), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,9 +168,47 @@ namespace Archetype.Courier.DataResolvers
|
||||
}
|
||||
}
|
||||
|
||||
private PublishedPropertyType CreateDummyPropertyType(int dataTypeId, string propertyEditorAlias)
|
||||
private void RetrieveAdditionalProperties(ref ArchetypePreValue preValue)
|
||||
{
|
||||
return new PublishedPropertyType(null, new PropertyType(new DataTypeDefinition(-1, propertyEditorAlias) { Id = dataTypeId }));
|
||||
if (preValue == null)
|
||||
return;
|
||||
|
||||
foreach (var fieldset in preValue.Fieldsets)
|
||||
{
|
||||
foreach (var property in fieldset.Properties)
|
||||
{
|
||||
var dataType = ExecutionContext.DatabasePersistence.RetrieveItem<DataType>(
|
||||
new ItemIdentifier(property.DataTypeGuid.ToString(),
|
||||
ProviderIDCollection.dataTypeItemProviderGuid));
|
||||
|
||||
if (dataType == null)
|
||||
continue;
|
||||
|
||||
property.PropertyEditorAlias = dataType.PropertyEditorAlias;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RetrieveAdditionalProperties(ref ArchetypeModel archetype, ArchetypePreValue preValue)
|
||||
{
|
||||
foreach (var fieldset in preValue.Fieldsets)
|
||||
{
|
||||
var fieldsetAlias = fieldset.Alias;
|
||||
foreach (var fieldsetInst in archetype.Fieldsets.Where(x => x.Alias == fieldsetAlias))
|
||||
{
|
||||
foreach (var property in fieldset.Properties)
|
||||
{
|
||||
var propertyAlias = property.Alias;
|
||||
foreach (var propertyInst in fieldsetInst.Properties.Where(x => x.Alias == propertyAlias))
|
||||
{
|
||||
propertyInst.DataTypeGuid = property.DataTypeGuid.ToString();
|
||||
propertyInst.DataTypeId = ExecutionContext.DatabasePersistence.GetNodeId(
|
||||
property.DataTypeGuid, NodeObjectTypes.DataType);
|
||||
propertyInst.PropertyEditorAlias = property.PropertyEditorAlias;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@ namespace Archetype.Extensions
|
||||
_app = ApplicationContext.Current;
|
||||
}
|
||||
|
||||
internal JsonSerializerSettings JsonSerializerSettings { get { return _jsonSettings; } }
|
||||
|
||||
internal ArchetypeModel DeserializeJsonToArchetype(string sourceJson, PreValueCollection dataTypePreValues)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Archetype.Models
|
||||
|
||||
// Try Umbraco's PropertyValueConverters
|
||||
var converters = UmbracoContext.Current != null ? PropertyValueConvertersResolver.Current.Converters : Enumerable.Empty<IPropertyValueConverter>();
|
||||
if (converters.Any())
|
||||
if (!string.IsNullOrWhiteSpace(this.PropertyEditorAlias) && converters.Any())
|
||||
{
|
||||
var convertedAttempt = TryConvertWithPropertyValueConverters<T>(Value, converters);
|
||||
if (convertedAttempt.Success)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion("1.7.1")]
|
||||
[assembly: AssemblyFileVersion("1.7.1")]
|
||||
[assembly: AssemblyVersion("1.8")]
|
||||
[assembly: AssemblyFileVersion("1.8")]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Archetype.Extensions;
|
||||
using ClientDependency.Core;
|
||||
using Newtonsoft.Json;
|
||||
@@ -56,16 +57,15 @@ namespace Archetype.PropertyEditors
|
||||
if (property.Value == null || property.Value.ToString() == "")
|
||||
return string.Empty;
|
||||
|
||||
//LogHelper.Info<ArchetypeHelper>(property.Value.ToString());
|
||||
|
||||
var archetype = ArchetypeHelper.Instance.DeserializeJsonToArchetype(property.Value.ToString(), propertyType.DataTypeDefinitionId);
|
||||
|
||||
foreach (var fieldset in archetype.Fieldsets)
|
||||
{
|
||||
foreach (var propDef in fieldset.Properties)
|
||||
foreach (var propDef in fieldset.Properties.Where(p => p.DataTypeGuid != null))
|
||||
{
|
||||
try
|
||||
{
|
||||
if(propDef == null || propDef.DataTypeGuid == null) continue;
|
||||
var dtd = ArchetypeHelper.Instance.GetDataTypeByGuid(Guid.Parse(propDef.DataTypeGuid));
|
||||
var propType = new PropertyType(dtd) { Alias = propDef.Alias };
|
||||
var prop = new Property(propType, propDef.Value);
|
||||
@@ -85,15 +85,13 @@ namespace Archetype.PropertyEditors
|
||||
public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService)
|
||||
{
|
||||
if (property.Value == null || property.Value.ToString() == "")
|
||||
return string.Empty;
|
||||
|
||||
//LogHelper.Info<ArchetypeHelper>(property.Value.ToString());
|
||||
return string.Empty;;
|
||||
|
||||
var archetype = ArchetypeHelper.Instance.DeserializeJsonToArchetype(property.Value.ToString(), propertyType.DataTypeDefinitionId);
|
||||
|
||||
foreach (var fieldset in archetype.Fieldsets)
|
||||
{
|
||||
foreach (var propDef in fieldset.Properties)
|
||||
foreach (var propDef in fieldset.Properties.Where(p => p.DataTypeGuid != null))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -117,13 +115,11 @@ namespace Archetype.PropertyEditors
|
||||
if (editorValue.Value == null || editorValue.Value.ToString() == "")
|
||||
return string.Empty;
|
||||
|
||||
//LogHelper.Info<ArchetypeHelper>(editorValue.Value.ToString());
|
||||
|
||||
var archetype = ArchetypeHelper.Instance.DeserializeJsonToArchetype(editorValue.Value.ToString(), editorValue.PreValues);
|
||||
|
||||
foreach (var fieldset in archetype.Fieldsets)
|
||||
{
|
||||
foreach (var propDef in fieldset.Properties)
|
||||
{
|
||||
foreach (var propDef in fieldset.Properties.Where(p => p.DataTypeGuid != null))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, assetsService, angularHelper, notificationsService, $timeout, entityResource) {
|
||||
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, assetsService, angularHelper, notificationsService, $timeout, entityResource, archetypeService, archetypeLabelService, archetypeCacheService, archetypePropertyEditorResource) {
|
||||
|
||||
//$scope.model.value = "";
|
||||
$scope.model.hideLabel = $scope.model.config.hideLabel == 1;
|
||||
@@ -17,86 +17,59 @@
|
||||
|
||||
init();
|
||||
|
||||
//hold references to helper resources
|
||||
//hold references to helper resources
|
||||
$scope.resources = {
|
||||
entityResource: entityResource
|
||||
entityResource: entityResource,
|
||||
archetypePropertyEditorResource: archetypePropertyEditorResource
|
||||
}
|
||||
|
||||
//hold references to helper services
|
||||
$scope.services = {
|
||||
archetypeService: archetypeService,
|
||||
archetypeLabelService: archetypeLabelService,
|
||||
archetypeCacheService: archetypeCacheService
|
||||
}
|
||||
|
||||
//helper to get $eval the labelTemplate
|
||||
$scope.getFieldsetTitle = function(fieldsetConfigModel, fieldsetIndex) {
|
||||
if(!fieldsetConfigModel)
|
||||
return "";
|
||||
var fieldset = $scope.model.value.fieldsets[fieldsetIndex];
|
||||
var fieldsetConfig = $scope.getConfigFieldsetByAlias(fieldset.alias);
|
||||
var template = fieldsetConfigModel.labelTemplate;
|
||||
|
||||
if (template.length < 1)
|
||||
return fieldsetConfig.label;
|
||||
|
||||
var rgx = /{{(.*?)}}*/g;
|
||||
var results;
|
||||
var parsedTemplate = template;
|
||||
|
||||
while ((results = rgx.exec(template)) !== null) {
|
||||
// split the template in case it consists of multiple property aliases and/or functions
|
||||
var parts = results[1].split("|");
|
||||
var templateLabelValue = "";
|
||||
for(var i = 0; i < parts.length; i++) {
|
||||
// stop looking for a template label value if a previous template part already yielded a value
|
||||
if(templateLabelValue != "") {
|
||||
break;
|
||||
}
|
||||
|
||||
var part = parts[i];
|
||||
|
||||
//test for function
|
||||
var beginIndexOf = part.indexOf("(");
|
||||
var endIndexOf = part.indexOf(")");
|
||||
|
||||
if(beginIndexOf != -1 && endIndexOf != -1)
|
||||
{
|
||||
var functionName = part.substring(0, beginIndexOf);
|
||||
var propertyAlias = part.substring(beginIndexOf + 1, endIndexOf);
|
||||
templateLabelValue = executeFunctionByName(functionName, window, $scope.getPropertyValueByAlias(fieldset, propertyAlias), $scope);
|
||||
}
|
||||
else {
|
||||
propertyAlias = part;
|
||||
templateLabelValue = $scope.getPropertyValueByAlias(fieldset, propertyAlias);
|
||||
}
|
||||
}
|
||||
parsedTemplate = parsedTemplate.replace(results[0], templateLabelValue);
|
||||
}
|
||||
|
||||
return parsedTemplate;
|
||||
};
|
||||
|
||||
function executeFunctionByName(functionName, context) {
|
||||
var args = Array.prototype.slice.call(arguments).splice(2);
|
||||
|
||||
var namespaces = functionName.split(".");
|
||||
var func = namespaces.pop();
|
||||
|
||||
for(var i = 0; i < namespaces.length; i++) {
|
||||
context = context[namespaces[i]];
|
||||
}
|
||||
|
||||
if(context && context[func]) {
|
||||
return context[func].apply(this, args);
|
||||
}
|
||||
|
||||
return "";
|
||||
$scope.getFieldsetTitle = function (fieldsetConfigModel, fieldsetIndex) {
|
||||
return archetypeLabelService.getFieldsetTitle($scope, fieldsetConfigModel, fieldsetIndex);
|
||||
}
|
||||
|
||||
var draggedRteSettings;
|
||||
var rteClass = ".mce-tinymce";
|
||||
|
||||
//sort config
|
||||
$scope.sortableOptions = {
|
||||
axis: 'y',
|
||||
cursor: "move",
|
||||
handle: ".handle",
|
||||
start: function(ev, ui) {
|
||||
draggedRteSettings = {};
|
||||
ui.item.parent().find(rteClass).each(function () {
|
||||
// remove all RTEs in the dragged row and save their settings
|
||||
var $element = $(this);
|
||||
var wrapperId = $element.attr('id');
|
||||
var $textarea = $element.siblings('textarea');
|
||||
var textareaId = $textarea.attr('id');
|
||||
|
||||
draggedRteSettings[textareaId] = _.findWhere(tinyMCE.editors, { id: textareaId }).settings;
|
||||
tinyMCE.execCommand('mceRemoveEditor', false, wrapperId);
|
||||
});
|
||||
},
|
||||
update: function (ev, ui) {
|
||||
$scope.setDirty();
|
||||
},
|
||||
stop: function (ev, ui) {
|
||||
ui.item.parent().find(rteClass).each(function () {
|
||||
var $element = $(this);
|
||||
var wrapperId = $element.attr('id');
|
||||
var $textarea = $element.siblings('textarea');
|
||||
var textareaId = $textarea.attr('id');
|
||||
|
||||
draggedRteSettings[textareaId] = draggedRteSettings[textareaId] || _.findWhere(tinyMCE.editors, { id: textareaId }).settings;
|
||||
tinyMCE.execCommand('mceRemoveEditor', false, wrapperId);
|
||||
tinyMCE.init(draggedRteSettings[textareaId]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -127,6 +100,7 @@
|
||||
if (confirm('Are you sure you want to remove this?')) {
|
||||
$scope.setDirty();
|
||||
$scope.model.value.fieldsets.splice($index, 1);
|
||||
$scope.$broadcast("archetypeRemoveFieldset", {index: $index});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,6 +266,8 @@
|
||||
$scope.model.value.toString = stringify;
|
||||
}
|
||||
}
|
||||
// reset submit watcher counter on save
|
||||
$scope.activeSubmitWatcher = 0;
|
||||
});
|
||||
|
||||
//helper to count what is visible
|
||||
@@ -391,4 +367,17 @@
|
||||
{
|
||||
assetsService.loadCss($scope.model.config.customCssPath);
|
||||
}
|
||||
|
||||
// submit watcher handling:
|
||||
// because some property editors use the "formSubmitting" event to set/clean up their model.value,
|
||||
// we need to monitor the "formSubmitting" event from a custom property and broadcast our own event
|
||||
// to forcefully update the appropriate model.value's
|
||||
$scope.activeSubmitWatcher = 0;
|
||||
$scope.submitWatcherOnLoad = function () {
|
||||
$scope.activeSubmitWatcher++;
|
||||
return $scope.activeSubmitWatcher;
|
||||
}
|
||||
$scope.submitWatcherOnSubmit = function () {
|
||||
$scope.$broadcast("archetypeFormSubmitting");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,75 +1,33 @@
|
||||
angular.module("umbraco.directives").directive('archetypeProperty', function ($compile, $http, archetypePropertyEditorResource, umbPropEditorHelper, $timeout, $rootScope, $q, editorState) {
|
||||
|
||||
function getFieldsetByAlias(fieldsets, alias)
|
||||
{
|
||||
return _.find(fieldsets, function(fieldset){
|
||||
return fieldset.alias == alias;
|
||||
});
|
||||
}
|
||||
|
||||
function getPropertyIndexByAlias(properties, alias){
|
||||
for (var i in properties)
|
||||
{
|
||||
if (properties[i].alias == alias) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPropertyByAlias(fieldset, alias){
|
||||
return _.find(fieldset.properties, function(property){
|
||||
return property.alias == alias;
|
||||
});
|
||||
}
|
||||
|
||||
//helper that returns a JS ojbect from 'value' string or the original string
|
||||
function jsonOrString(value, developerMode, debugLabel){
|
||||
if(value && typeof value == 'string'){
|
||||
try{
|
||||
if(developerMode == '1'){
|
||||
console.log("Trying to parse " + debugLabel + ": " + value);
|
||||
}
|
||||
value = JSON.parse(value);
|
||||
}
|
||||
catch(exception)
|
||||
{
|
||||
if(developerMode == '1'){
|
||||
console.log("Failed to parse " + debugLabel + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(value && developerMode == '1'){
|
||||
console.log(debugLabel + " post-parsing: ");
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
angular.module("umbraco.directives").directive('archetypeProperty', function ($compile, $http, archetypePropertyEditorResource, umbPropEditorHelper, $timeout, $rootScope, $q, editorState, archetypeService, archetypeCacheService) {
|
||||
|
||||
var linker = function (scope, element, attrs, ngModelCtrl) {
|
||||
var configFieldsetModel = getFieldsetByAlias(scope.archetypeConfig.fieldsets, scope.fieldset.alias);
|
||||
var configFieldsetModel = archetypeService.getFieldsetByAlias(scope.archetypeConfig.fieldsets, scope.fieldset.alias);
|
||||
var view = "";
|
||||
var label = configFieldsetModel.properties[scope.propertyConfigIndex].label;
|
||||
var dataTypeGuid = configFieldsetModel.properties[scope.propertyConfigIndex].dataTypeGuid;
|
||||
var config = null;
|
||||
var alias = configFieldsetModel.properties[scope.propertyConfigIndex].alias;
|
||||
var defaultValue = configFieldsetModel.properties[scope.propertyConfigIndex].value;
|
||||
var propertyAlias = getUniquePropertyAlias(scope);
|
||||
propertyAliasParts = [];
|
||||
|
||||
var propertyAliasParts = [];
|
||||
var propertyAlias = archetypeService.getUniquePropertyAlias(scope, propertyAliasParts);
|
||||
|
||||
//try to convert the defaultValue to a JS object
|
||||
defaultValue = jsonOrString(defaultValue, scope.archetypeConfig.developerMode, "defaultValue");
|
||||
defaultValue = archetypeService.jsonOrString(defaultValue, scope.archetypeConfig.developerMode, "defaultValue");
|
||||
|
||||
//grab info for the selected datatype, prepare for view
|
||||
archetypePropertyEditorResource.getDataType(dataTypeGuid, scope.archetypeConfig.enableDeepDatatypeRequests, editorState.current.contentTypeAlias, scope.propertyEditorAlias, alias, editorState.current.id).then(function (data) {
|
||||
//transform preValues array into object expected by propertyeditor views
|
||||
var configObj = {};
|
||||
|
||||
_.each(data.preValues, function(p) {
|
||||
configObj[p.key] = p.value;
|
||||
});
|
||||
|
||||
config = configObj;
|
||||
|
||||
//caching for use by label templates later
|
||||
archetypeCacheService.addDatatypeToCache(data, dataTypeGuid);
|
||||
|
||||
//determine the view to use [...] and load it
|
||||
archetypePropertyEditorResource.getPropertyEditorMapping(data.selectedEditor).then(function(propertyEditor) {
|
||||
var pathToView = umbPropEditorHelper.getViewPath(propertyEditor.view);
|
||||
@@ -86,22 +44,22 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
|
||||
});
|
||||
});
|
||||
|
||||
scope.$on("formSubmitting", function (ev, args) {
|
||||
scope.$on("archetypeFormSubmitting", function (ev, args) {
|
||||
// validate all fieldset properties
|
||||
_.each(scope.fieldset.properties, function (property) {
|
||||
validateProperty(scope.fieldset, property);
|
||||
});
|
||||
|
||||
// set invalid state if the fieldset contains invalid properties
|
||||
// we need an unique validation key per fieldset in this ngModelCtrl scope, which leaves us with a potential problem:
|
||||
// if the user invalidates the last fieldset, attempts (and fails) to save and and subsequently deletes the invalid fieldset,
|
||||
// the validation key will persist on ngModelCtrl and thus the form will not submit.
|
||||
// to fix this problem, the controller probably needs to raise an event (in removeRow) that can be intercepted here to
|
||||
// clear the validation key.
|
||||
var validationKey = "validation-f" + scope.fieldsetIndex;
|
||||
ngModelCtrl.$setValidity(validationKey, scope.fieldset.isValid);
|
||||
});
|
||||
|
||||
scope.$on("archetypeRemoveFieldset", function (ev, args) {
|
||||
var validationKey = "validation-f" + args.index;
|
||||
ngModelCtrl.$setValidity(validationKey, true);
|
||||
});
|
||||
|
||||
|
||||
// called when the value of any property in a fieldset changes
|
||||
function propertyValueChanged(fieldset, property) {
|
||||
// it's the Umbraco way to hide the invalid state when altering an invalid property, even if the new value isn't valid either
|
||||
@@ -111,7 +69,7 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
|
||||
|
||||
// validate a property in a fieldset
|
||||
function validateProperty(fieldset, property) {
|
||||
var propertyConfig = getPropertyByAlias(configFieldsetModel, property.alias);
|
||||
var propertyConfig = archetypeService.getPropertyByAlias(configFieldsetModel, property.alias);
|
||||
if (propertyConfig) {
|
||||
// use property.value !== property.value to check for NaN values on numeric inputs
|
||||
if (propertyConfig.required && (property.value == null || property.value === "" || property.value !== property.value)) {
|
||||
@@ -139,25 +97,6 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
|
||||
}
|
||||
}
|
||||
|
||||
var propertyAliasParts = [];
|
||||
var getUniquePropertyAlias = function (currentScope) {
|
||||
if (currentScope.hasOwnProperty('fieldsetIndex') && currentScope.hasOwnProperty('property') && currentScope.hasOwnProperty('propertyConfigIndex'))
|
||||
{
|
||||
var currentPropertyAlias = "f" + currentScope.fieldsetIndex + "-" + currentScope.property.alias + "-p" + currentScope.propertyConfigIndex;
|
||||
propertyAliasParts.push(currentPropertyAlias);
|
||||
}
|
||||
else if (currentScope.hasOwnProperty('isPreValue')) // Crappy way to identify this is the umbraco property scope
|
||||
{
|
||||
var umbracoPropertyAlias = currentScope.$parent.$parent.property.alias; // Crappy way to get the umbraco host alias once we identify its scope
|
||||
propertyAliasParts.push(umbracoPropertyAlias);
|
||||
}
|
||||
|
||||
if (currentScope.$parent)
|
||||
getUniquePropertyAlias(currentScope.$parent);
|
||||
|
||||
return _.unique(propertyAliasParts).reverse().join("-");
|
||||
};
|
||||
|
||||
function loadView(view, config, defaultValue, alias, propertyAlias, scope, element, ngModelCtrl, propertyValueChanged) {
|
||||
if (view)
|
||||
{
|
||||
@@ -174,14 +113,15 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
|
||||
scope.model.config = {};
|
||||
|
||||
//ini the property value after test to make sure a prop exists in the renderModel
|
||||
var renderModelPropertyIndex = getPropertyIndexByAlias(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties, alias);
|
||||
scope.renderModelPropertyIndex = archetypeService.getPropertyIndexByAlias(archetypeService.getFieldset(scope).properties, alias);
|
||||
|
||||
if (!renderModelPropertyIndex)
|
||||
if (!scope.renderModelPropertyIndex)
|
||||
{
|
||||
scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties.push(JSON.parse('{"alias": "' + alias + '", "value": "' + defaultValue + '"}'));
|
||||
renderModelPropertyIndex = getPropertyIndexByAlias(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties, alias);
|
||||
archetypeService.getFieldset(scope).properties.push(JSON.parse('{"alias": "' + alias + '", "value": "' + defaultValue + '"}'));
|
||||
scope.renderModelPropertyIndex = archetypeService.getPropertyIndexByAlias(archetypeService.getFieldset(scope).properties, alias);
|
||||
}
|
||||
scope.model.value = scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties[renderModelPropertyIndex].value;
|
||||
scope.renderModel = {};
|
||||
scope.model.value = archetypeService.getFieldsetProperty(scope).value;
|
||||
|
||||
//set the config from the prevalues
|
||||
scope.model.config = config;
|
||||
@@ -201,17 +141,29 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
|
||||
}
|
||||
}
|
||||
|
||||
//console.log(scope.model.config);
|
||||
|
||||
//some items need an alias
|
||||
scope.model.alias = "archetype-property-" + propertyAlias;
|
||||
|
||||
//watch for changes since there is no two-way binding with the local model.value
|
||||
scope.$watch('model.value', function (newValue, oldValue) {
|
||||
scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties[renderModelPropertyIndex].value = newValue;
|
||||
archetypeService.getFieldsetProperty(scope).value = newValue;
|
||||
|
||||
// notify the linker that the property value changed
|
||||
propertyValueChanged(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex], scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties[renderModelPropertyIndex]);
|
||||
propertyValueChanged(archetypeService.getFieldset(scope), archetypeService.getFieldsetProperty(scope));
|
||||
});
|
||||
|
||||
scope.$on('archetypeFormSubmitting', function (ev, args) {
|
||||
// did the value change (if it did, it most likely did so during the "formSubmitting" event)
|
||||
var property = archetypeService.getFieldsetProperty(scope);
|
||||
|
||||
var currentValue = property.value;
|
||||
|
||||
if (currentValue != scope.model.value) {
|
||||
archetypeService.getFieldsetProperty(scope).value = scope.model.value;
|
||||
|
||||
// notify the linker that the property value changed
|
||||
propertyValueChanged(archetypeService.getFieldset(scope), archetypeService.getFieldsetProperty(scope));
|
||||
}
|
||||
});
|
||||
|
||||
element.html(data).show();
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
angular.module("umbraco.directives").directive('archetypeSubmitWatcher', function ($rootScope) {
|
||||
var linker = function (scope, element, attrs, ngModelCtrl) {
|
||||
// call the load callback on scope to obtain the ID of this submit watcher
|
||||
var id = scope.loadCallback();
|
||||
scope.$on("formSubmitting", function (ev, args) {
|
||||
// on the "formSubmitting" event, call the submit callback on scope to notify the Archetype controller to do it's magic
|
||||
if (id == scope.activeSubmitWatcher) {
|
||||
scope.submitCallback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: "E",
|
||||
replace: true,
|
||||
link: linker,
|
||||
template: "",
|
||||
scope: {
|
||||
loadCallback: '=',
|
||||
submitCallback: '=',
|
||||
activeSubmitWatcher: '='
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,41 +0,0 @@
|
||||
var ArchetypeLabels = (function() {
|
||||
|
||||
var isEntityLookupLoading = false;
|
||||
var entityNameLookupCache = [];
|
||||
|
||||
function getEntityById(scope, id, type) {
|
||||
|
||||
for (var i in entityNameLookupCache) {
|
||||
if (entityNameLookupCache[i].id == id) {
|
||||
return entityNameLookupCache[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isEntityLookupLoading) {
|
||||
isEntityLookupLoading = true;
|
||||
|
||||
scope.resources.entityResource.getById(id, type).then(function(entity) {
|
||||
entityNameLookupCache.push({id: id, value: entity.name});
|
||||
|
||||
isEntityLookupLoading = false;
|
||||
return entity.name;
|
||||
});
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
return {
|
||||
GetFirstDocumentEntityName: function ($scope, value) {
|
||||
if (value) {
|
||||
var id = value.split(",")[0];
|
||||
|
||||
if (id) {
|
||||
return getEntityById($scope, id, "Document");
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,70 @@
|
||||
var ArchetypeSampleLabelTemplates = (function() {
|
||||
|
||||
//public functions
|
||||
return {
|
||||
Entity: function (value, scope, args) {
|
||||
|
||||
if(!args.entityType) {
|
||||
args = {entityType: "Document", propertyName: "name"}
|
||||
}
|
||||
|
||||
if (value) {
|
||||
//if handed a csv list, take the first only
|
||||
var id = value.split(",")[0];
|
||||
|
||||
if (id) {
|
||||
var entity = scope.services.archetypeLabelService.getEntityById(scope, id, args.entityType);
|
||||
|
||||
if(entity) {
|
||||
return entity[args.propertyName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
},
|
||||
UrlPicker: function(value, scope, args) {
|
||||
|
||||
if(!args.propertyName) {
|
||||
args = {propertyName: "name"}
|
||||
}
|
||||
|
||||
var entity;
|
||||
|
||||
switch (value.type) {
|
||||
case "content":
|
||||
if(value.typeData.contentId) {
|
||||
entity = scope.services.archetypeLabelService.getEntityById(scope, value.typeData.contentId, "Document");
|
||||
}
|
||||
break;
|
||||
|
||||
case "media":
|
||||
if(value.typeData.mediaId) {
|
||||
entity = scope.services.archetypeLabelService.getEntityById(scope, value.typeData.mediaId, "Media");
|
||||
}
|
||||
break;
|
||||
|
||||
case "url":
|
||||
return value.typeData.url;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if(entity) {
|
||||
return entity[args.propertyName];
|
||||
}
|
||||
|
||||
return "";
|
||||
},
|
||||
Rte: function (value, scope, args) {
|
||||
|
||||
if(!args.contentLength) {
|
||||
args = {contentLength: 50}
|
||||
}
|
||||
|
||||
return $(value).text().substring(0, args.contentLength);
|
||||
}
|
||||
}
|
||||
})();
|
||||
+19
-6
@@ -2,11 +2,11 @@
|
||||
|
||||
.archetypeEditor {
|
||||
width: 98%;
|
||||
|
||||
|
||||
.open {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.dropdown-menu {
|
||||
top: auto;
|
||||
> li > a {
|
||||
@@ -25,7 +25,12 @@
|
||||
.icon {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
|
||||
.fieldsetIcon {
|
||||
float: left;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #dddddd;
|
||||
padding: 0;
|
||||
@@ -56,9 +61,10 @@
|
||||
.archetypeFieldsetLabel {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: 42px;
|
||||
|
||||
.label-sub {
|
||||
padding: 8px 0;
|
||||
padding: 8px 0 4px 0;
|
||||
display: inline-block;
|
||||
&.module-label {
|
||||
width: 100%;
|
||||
@@ -98,6 +104,7 @@
|
||||
|
||||
.caret {
|
||||
margin: 8px 1px 0 15px;
|
||||
position: absolute;
|
||||
|
||||
&.caret-right {
|
||||
border-bottom: 4px solid transparent;
|
||||
@@ -110,10 +117,15 @@
|
||||
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
margin-left: 5px;
|
||||
margin-left: 38px;
|
||||
white-space: nowrap;
|
||||
padding: 0;
|
||||
width: ~"calc(100% - 132px)";
|
||||
position: absolute;
|
||||
span {
|
||||
display: inline-block;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
&.dimmed {
|
||||
color: #d9d9d9;
|
||||
@@ -181,6 +193,7 @@
|
||||
|
||||
.archetypeAddButton:hover {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
.archetypeAddButtonText {
|
||||
text-decoration: underline;
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
angular.module('umbraco.services').factory('archetypeCacheService', function (archetypePropertyEditorResource) {
|
||||
//private
|
||||
|
||||
var isEntityLookupLoading = false;
|
||||
var entityCache = [];
|
||||
var isDatatypeLookupLoading = false;
|
||||
var datatypeCache = [];
|
||||
|
||||
return {
|
||||
getDataTypeFromCache: function(guid) {
|
||||
return _.find(datatypeCache, function (dt){
|
||||
return dt.dataTypeGuid == guid;
|
||||
});
|
||||
},
|
||||
|
||||
addDatatypeToCache: function(datatype, dataTypeGuid) {
|
||||
var cachedDatatype = this.getDataTypeFromCache(dataTypeGuid);
|
||||
|
||||
if(!cachedDatatype) {
|
||||
datatype.dataTypeGuid = dataTypeGuid;
|
||||
datatypeCache.push(datatype);
|
||||
}
|
||||
},
|
||||
|
||||
getDatatypeByGuid: function(guid) {
|
||||
var cachedDatatype = this.getDataTypeFromCache(guid);
|
||||
|
||||
if(cachedDatatype) {
|
||||
return cachedDatatype;
|
||||
}
|
||||
|
||||
//go get it from server, but this should already be pre-populated from the directive, but I suppose I'll leave this in in case used ad-hoc
|
||||
if (!isDatatypeLookupLoading) {
|
||||
isDatatypeLookupLoading = true;
|
||||
|
||||
archetypePropertyEditorResource.getDataType(guid).then(function(datatype) {
|
||||
|
||||
datatype.dataTypeGuid = guid;
|
||||
|
||||
datatypeCache.push(datatype);
|
||||
|
||||
isDatatypeLookupLoading = false;
|
||||
|
||||
return datatype;
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
getEntityById: function(scope, id, type) {
|
||||
var cachedEntity = _.find(entityCache, function (e){
|
||||
return e.id == id;
|
||||
});
|
||||
|
||||
if(cachedEntity) {
|
||||
return cachedEntity;
|
||||
}
|
||||
|
||||
//go get it from server
|
||||
if (!isEntityLookupLoading) {
|
||||
isEntityLookupLoading = true;
|
||||
|
||||
scope.resources.entityResource.getById(id, type).then(function(entity) {
|
||||
|
||||
entityCache.push(entity);
|
||||
|
||||
isEntityLookupLoading = false;
|
||||
|
||||
return entity;
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,238 @@
|
||||
angular.module('umbraco.services').factory('archetypeLabelService', function (archetypeCacheService) {
|
||||
//private
|
||||
|
||||
var isEntityLookupLoading = false;
|
||||
var entityCache = [];
|
||||
var isDatatypeLookupLoading = false;
|
||||
var datatypeCache = [];
|
||||
|
||||
function executeFunctionByName(functionName, context) {
|
||||
var args = Array.prototype.slice.call(arguments).splice(2);
|
||||
|
||||
var namespaces = functionName.split(".");
|
||||
var func = namespaces.pop();
|
||||
|
||||
for(var i = 0; i < namespaces.length; i++) {
|
||||
context = context[namespaces[i]];
|
||||
}
|
||||
|
||||
if(context && context[func]) {
|
||||
return context[func].apply(this, args);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function getNativeLabel(datatype, value, scope) {
|
||||
switch (datatype.selectedEditor) {
|
||||
case "Imulus.UrlPicker":
|
||||
return imulusUrlPicker(value, scope, {});
|
||||
case "Umbraco.TinyMCEv3":
|
||||
return coreTinyMce(value, scope, {});
|
||||
case "Umbraco.MultiNodeTreePicker":
|
||||
return coreMntp(value, scope, datatype);
|
||||
case "Umbraco.MediaPicker":
|
||||
return coreMediaPicker(value, scope, datatype);
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function coreMntp(value, scope, args) {
|
||||
var ids = value.split(',');
|
||||
var type = "Document";
|
||||
|
||||
switch(args.preValues[0].value.type) {
|
||||
case 'content':
|
||||
type = 'Document';
|
||||
break;
|
||||
case 'media':
|
||||
type = 'media';
|
||||
break;
|
||||
case 'member':
|
||||
type = 'member';
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var entityArray = [];
|
||||
|
||||
_.each(ids, function(id){
|
||||
if(id) {
|
||||
|
||||
var entity = archetypeCacheService.getEntityById(scope, id, type);
|
||||
|
||||
if(entity) {
|
||||
entityArray.push(entity.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return entityArray.join(', ');
|
||||
}
|
||||
|
||||
function coreMediaPicker(value, scope, args) {
|
||||
if(value) {
|
||||
var entity = archetypeCacheService.getEntityById(scope, value, "media");
|
||||
|
||||
if(entity) {
|
||||
return entity.name;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function imulusUrlPicker(value, scope, args) {
|
||||
|
||||
if(!args.propertyName) {
|
||||
args = {propertyName: "name"}
|
||||
}
|
||||
|
||||
var entity;
|
||||
|
||||
switch (value.type) {
|
||||
case "content":
|
||||
if(value.typeData.contentId) {
|
||||
entity = archetypeCacheService.getEntityById(scope, value.typeData.contentId, "Document");
|
||||
}
|
||||
break;
|
||||
|
||||
case "media":
|
||||
if(value.typeData.mediaId) {
|
||||
entity = archetypeCacheService.getEntityById(scope, value.typeData.mediaId, "Media");
|
||||
}
|
||||
break;
|
||||
|
||||
case "url":
|
||||
return value.typeData.url;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if(entity) {
|
||||
return entity[args.propertyName];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function coreTinyMce(value, scope, args) {
|
||||
|
||||
if(!args.contentLength) {
|
||||
args = {contentLength: 50}
|
||||
}
|
||||
|
||||
var suffix = "";
|
||||
var strippedText = $(value).text();
|
||||
|
||||
if(strippedText.length > args.contentLength) {
|
||||
suffix = "…";
|
||||
}
|
||||
|
||||
return strippedText.substring(0, args.contentLength) + suffix;
|
||||
}
|
||||
|
||||
return {
|
||||
getFieldsetTitle: function(scope, fieldsetConfigModel, fieldsetIndex) {
|
||||
|
||||
//console.log(scope.model.config);
|
||||
|
||||
if(!fieldsetConfigModel)
|
||||
return "";
|
||||
|
||||
var fieldset = scope.model.value.fieldsets[fieldsetIndex];
|
||||
var fieldsetConfig = scope.getConfigFieldsetByAlias(fieldset.alias);
|
||||
var template = fieldsetConfigModel.labelTemplate;
|
||||
|
||||
if (template.length < 1)
|
||||
return fieldsetConfig.label;
|
||||
|
||||
var rgx = /{{([^)].*)}}/g;
|
||||
var results;
|
||||
var parsedTemplate = template;
|
||||
|
||||
while ((results = rgx.exec(template)) !== null) {
|
||||
|
||||
// split the template in case it consists of multiple property aliases and/or functions
|
||||
var templates = results[0].replace("{{", '').replace("}}", '').split("|");
|
||||
var templateLabelValue = "";
|
||||
|
||||
for(var i = 0; i < templates.length; i++) {
|
||||
// stop looking for a template label value if a previous template part already yielded a value
|
||||
if(templateLabelValue != "") {
|
||||
break;
|
||||
}
|
||||
|
||||
var template = templates[i];
|
||||
|
||||
//test for function
|
||||
var beginParamsIndexOf = template.indexOf("(");
|
||||
var endParamsIndexOf = template.indexOf(")");
|
||||
|
||||
//if passed a function
|
||||
if(beginParamsIndexOf != -1 && endParamsIndexOf != -1)
|
||||
{
|
||||
var functionName = template.substring(0, beginParamsIndexOf);
|
||||
var propertyAlias = template.substring(beginParamsIndexOf + 1, endParamsIndexOf).split(',')[0];
|
||||
|
||||
var args = {};
|
||||
|
||||
var beginArgsIndexOf = template.indexOf(',');
|
||||
|
||||
if(beginArgsIndexOf != -1) {
|
||||
|
||||
var argsString = template.substring(beginArgsIndexOf + 1, endParamsIndexOf).trim();
|
||||
|
||||
var normalizedJsonString = argsString.replace(/(\w+)\s*:/g, '"$1":');
|
||||
|
||||
args = JSON.parse(normalizedJsonString);
|
||||
}
|
||||
|
||||
templateLabelValue = executeFunctionByName(functionName, window, scope.getPropertyValueByAlias(fieldset, propertyAlias), scope, args);
|
||||
}
|
||||
//normal {{foo}} syntax
|
||||
else {
|
||||
propertyAlias = template;
|
||||
var rawValue = scope.getPropertyValueByAlias(fieldset, propertyAlias);
|
||||
|
||||
templateLabelValue = rawValue;
|
||||
|
||||
//determine the type of editor
|
||||
var propertyConfig = _.find(fieldsetConfigModel.properties, function(property){
|
||||
return property.alias == propertyAlias;
|
||||
});
|
||||
|
||||
if(propertyConfig) {
|
||||
var datatype = archetypeCacheService.getDatatypeByGuid(propertyConfig.dataTypeGuid);
|
||||
|
||||
if(datatype) {
|
||||
|
||||
//try to get built-in label
|
||||
var label = getNativeLabel(datatype, templateLabelValue, scope);
|
||||
|
||||
if(label) {
|
||||
templateLabelValue = label;
|
||||
}
|
||||
else {
|
||||
templateLabelValue = templateLabelValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return templateLabelValue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
parsedTemplate = parsedTemplate.replace(results[0], templateLabelValue);
|
||||
}
|
||||
|
||||
return parsedTemplate;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
angular.module('umbraco.services').factory('archetypeService', function () {
|
||||
|
||||
//public
|
||||
return {
|
||||
//helper that returns a JS ojbect from 'value' string or the original string
|
||||
jsonOrString: function (value, developerMode, debugLabel){
|
||||
if(value && typeof value == 'string'){
|
||||
try{
|
||||
if(developerMode == '1'){
|
||||
console.log("Trying to parse " + debugLabel + ": " + value);
|
||||
}
|
||||
value = JSON.parse(value);
|
||||
}
|
||||
catch(exception)
|
||||
{
|
||||
if(developerMode == '1'){
|
||||
console.log("Failed to parse " + debugLabel + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(value && developerMode == '1'){
|
||||
console.log(debugLabel + " post-parsing: ");
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
getFieldsetByAlias: function (fieldsets, alias)
|
||||
{
|
||||
return _.find(fieldsets, function(fieldset){
|
||||
return fieldset.alias == alias;
|
||||
});
|
||||
},
|
||||
getPropertyIndexByAlias: function(properties, alias){
|
||||
for (var i in properties)
|
||||
{
|
||||
if (properties[i].alias == alias) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
},
|
||||
getPropertyByAlias: function (fieldset, alias){
|
||||
return _.find(fieldset.properties, function(property){
|
||||
return property.alias == alias;
|
||||
});
|
||||
},
|
||||
getUniquePropertyAlias: function (currentScope, propertyAliasParts) {
|
||||
if (currentScope.hasOwnProperty('fieldsetIndex') && currentScope.hasOwnProperty('property') && currentScope.hasOwnProperty('propertyConfigIndex'))
|
||||
{
|
||||
var currentPropertyAlias = "f" + currentScope.fieldsetIndex + "-" + currentScope.property.alias + "-p" + currentScope.propertyConfigIndex;
|
||||
propertyAliasParts.push(currentPropertyAlias);
|
||||
}
|
||||
else if (currentScope.hasOwnProperty('isPreValue')) // Crappy way to identify this is the umbraco property scope
|
||||
{
|
||||
var umbracoPropertyAlias = currentScope.$parent.$parent.property.alias; // Crappy way to get the umbraco host alias once we identify its scope
|
||||
propertyAliasParts.push(umbracoPropertyAlias);
|
||||
}
|
||||
|
||||
if (currentScope.$parent)
|
||||
this.getUniquePropertyAlias(currentScope.$parent, propertyAliasParts);
|
||||
|
||||
return _.unique(propertyAliasParts).reverse().join("-");
|
||||
},
|
||||
getFieldset: function(scope) {
|
||||
return scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex];
|
||||
},
|
||||
getFieldsetProperty: function (scope) {
|
||||
return this.getFieldset(scope).properties[scope.renderModelPropertyIndex];
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
<div ng-class="[(model.config.hidePropertyLabels == '1' ? 'controls-no-label' : 'controls')]">
|
||||
<archetype-property class="archetypeEditor" property="property" property-editor-alias="model.alias" fieldset-index="$parent.$index" fieldset="fieldset" archetype-config="model.config" property-config-index="$index" archetype-render-model="model.value" umbraco-form="form"></archetype-property>
|
||||
<archetype-submit-watcher active-submit-watcher="activeSubmitWatcher" load-callback="submitWatcherOnLoad" submit-callback="submitWatcherOnSubmit"></archetype-submit-watcher>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -48,7 +49,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
<div ng-show="showAddButton()">
|
||||
<a data-toggle="{{ model.config.fieldsets.length > 1 ? 'dropdown' : ''}}" ng-click="model.config.fieldsets.length == 1 ? addRow(model.config.fieldsets[0].alias, 0) : return" prevent-default>
|
||||
<a class="archetypeAddButton" data-toggle="{{ model.config.fieldsets.length > 1 ? 'dropdown' : ''}}" ng-click="model.config.fieldsets.length == 1 ? addRow(model.config.fieldsets[0].alias, 0) : return" prevent-default>
|
||||
<i class="icon icon-add dropdown-toggle"></i>
|
||||
<localize key="general_add" class="archetypeAddButtonText">Add</localize>
|
||||
</a>
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Archetype",
|
||||
"version": "1.7.1",
|
||||
"version": "1.8",
|
||||
"url": "http://github.com/imulus/archetype/",
|
||||
"author": "Imulus - Kevin Giszewski - Tom Fulton - Lee Kelleher - Matt Brailsford - Kenn Jacobsen - Et. Al.",
|
||||
"authorUrl": "http://imulus.com/",
|
||||
|
||||
+15
-12
@@ -1,15 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Archetype</id>
|
||||
<version><%= version %></version>
|
||||
<title><%= name %></title>
|
||||
<authors>imulus, kgiszewski, tomfulton</authors>
|
||||
<owners>imulus, kgiszewski, tomfulton</owners>
|
||||
<projectUrl>http://github.com/imulus/archetype</projectUrl>
|
||||
<description><![CDATA[Archetype for Umbraco]]></description>
|
||||
<tags>umbraco</tags>
|
||||
<iconUrl>http://github.com/imulus/archetype/raw/master/assets/logo.png</iconUrl>
|
||||
<licenseUrl><%= licenseUrl %></licenseUrl>
|
||||
</metadata>
|
||||
<metadata>
|
||||
<id>Archetype</id>
|
||||
<version><%= version %></version>
|
||||
<title><%= name %></title>
|
||||
<authors>imulus, kgiszewski, tomfulton</authors>
|
||||
<owners>imulus, kgiszewski, tomfulton</owners>
|
||||
<projectUrl>http://github.com/imulus/archetype</projectUrl>
|
||||
<description><![CDATA[Archetype for Umbraco]]></description>
|
||||
<tags>umbraco</tags>
|
||||
<iconUrl>http://github.com/imulus/archetype/raw/master/assets/logo.png</iconUrl>
|
||||
<licenseUrl><%= licenseUrl %></licenseUrl>
|
||||
<dependencies>
|
||||
<dependency id="UmbracoCms.Core" version="7.1.6" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
</package>
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
"grunt-msbuild": "~0.1.9",
|
||||
"grunt-dotnet-assembly-info": "~1.0.9",
|
||||
"load-grunt-tasks": "~0.4.0",
|
||||
"grunt-umbraco-package": "0.0.5"
|
||||
"grunt-umbraco-package": "0.0.6"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Reference in New Issue
Block a user