Compare commits

..

220 Commits

Author SHA1 Message Date
kgiszewski 852b7a92a7 Update for v7.2.2 locale issue 2015-02-26 10:37:27 -05:00
kgiszewski 5a4118a1cc Bump version and fix clone issue 2015-01-27 11:05:43 -05:00
kgiszewski 4b603bf97f Bump Version Number 2015-01-27 10:53:17 -05:00
kgiszewski c8884c8d92 Add Cloning 2015-01-27 10:51:22 -05:00
kgiszewski dd843ce2c6 Make deep requests not the default 2015-01-27 10:01:59 -05:00
kgiszewski 8036ab72d0 Merge branch 'alt-label-template' 2015-01-27 09:44:36 -05:00
kgiszewski b25d8bdc4b Merge branch 'fix/datatype-caching' 2015-01-27 09:42:36 -05:00
Nicholas-Westby 023d99cc88 Improved performance of publish operations: https://github.com/imulus/Archetype/issues/238 2015-01-26 12:59:19 -08:00
kjac 1cc0586c75 Support alternative property in label template
Allow fieldset label templates to contain alternative/fallback property
aliases and/or functions by seperating with "|" - e.g.
{{title|myFunction(text)}}
2015-01-10 11:16:00 +01:00
kjac a16b61f03f Merge remote-tracking branch 'upstream/master' 2015-01-10 08:26:41 +01:00
Tom Fulton 7ea01cad86 Remove caching for property datatype dropdowns 2014-12-03 21:46:13 -07:00
Mads Krohn aea65a531d Tweak dropdown position for new fields
See related issue
2014-11-02 12:56:12 +01:00
Kevin Giszewski 482cb5a149 beta = gtfo 2014-11-02 12:56:12 +01:00
Kevin Giszewski 81ac5fbddb Update lang files 2014-11-02 12:56:11 +01:00
Kevin Giszewski 801baf355b Bump version number to v1.6 2014-11-02 12:56:10 +01:00
Kevin Giszewski a3b531caa4 Tidy up the PR 2014-11-02 12:56:10 +01:00
doronuziel71 1d680c612e Fixed type-o 2014-11-02 12:56:09 +01:00
doronuziel71 cdea3c1aec Fixed type-o 2014-11-02 12:56:09 +01:00
doronuziel71 37fa9c40d6 Introduced override default propety converter 2014-11-02 12:56:08 +01:00
Kevin Giszewski 774ba46e13 Flip-flop scope and fieldset 2014-11-02 12:56:07 +01:00
Kevin Giszewski 280a97c8d1 Expose FS (fieldsets) and Property (alias/value) for helping with creating Archetype from code 2014-11-02 12:56:07 +01:00
Kevin Giszewski 7dd3848bdf Expose serializer for those wanting to create Archetypes from code 2014-11-02 12:56:06 +01:00
leekelleher add44e533a Courier: Turns out that creating a new instance of PropertyItemProvider was a hack.
Replaced with getting the item-provider from the existing collection.
2014-11-02 12:56:05 +01:00
leekelleher 870b848e3b Bug fix with the Courier resolver 2014-11-02 12:56:05 +01:00
leekelleher b262d8a86f Set the project's assembly references to not "Copy Local".
As these pollute the /bin output folder during build.
2014-11-02 12:56:04 +01:00
leekelleher 5dba1a0895 Fixed the type-name for the error log messages 2014-11-02 12:56:03 +01:00
leekelleher 8f4857aba1 Fixed issue with Courier serialization.
When Courier was deserializing, it was treating any nested Archetype as a `JObject`.
The newer serializer routines in Archetype core resolve the previous issue.
2014-11-02 12:56:03 +01:00
leekelleher cd95404a08 PersistenceManager.Default was obsoleted, replaced calls with ExecutionContext.DatabasePersistence 2014-11-02 12:56:02 +01:00
leekelleher 7e7a4aff58 Upgraded Courier assemblies. 2014-11-02 12:56:01 +01:00
Mads Krohn c9d8952b7f Tweak dropdown position for new fields
See related issue
2014-10-02 14:46:26 +02:00
Kevin Giszewski 890b5674a6 beta = gtfo 2014-09-26 09:27:31 -04:00
Kevin Giszewski 7f5dbd31c9 Update lang files 2014-09-26 09:13:31 -04:00
Kevin Giszewski a2255aa037 Bump version number to v1.6 2014-09-25 14:27:52 -04:00
Kevin Giszewski 415a84f5c0 Tidy up the PR 2014-09-25 14:21:16 -04:00
doronuziel71 3a0eba401a Fixed type-o 2014-09-17 19:18:47 +03:00
doronuziel71 991d56dac1 Fixed type-o 2014-09-17 19:17:58 +03:00
doronuziel71 f704088bcb Merge remote-tracking branch 'upstream/master' 2014-09-17 18:37:00 +03:00
doronuziel71 a599215620 Introduced override default propety converter 2014-09-16 23:32:16 +03:00
Kevin Giszewski a6e76cb398 Flip-flop scope and fieldset 2014-09-16 13:55:54 -04:00
Kevin Giszewski 4fd134ac74 Expose FS (fieldsets) and Property (alias/value) for helping with creating Archetype from code 2014-09-08 10:39:13 -04:00
Kevin Giszewski 22b87c0a37 Merge branch 'develop' of github.com:imulus/Archetype into develop 2014-09-08 10:00:28 -04:00
Kevin Giszewski d707b55362 Expose serializer for those wanting to create Archetypes from code 2014-09-08 10:00:05 -04:00
Kevin Giszewski 37a195109c Merge pull request #220 from leekelleher/feature/courier-upgrade
Courier: Fix for PropertyItemProvider reference
2014-09-04 08:52:10 -04:00
leekelleher 205919ccae Courier: Turns out that creating a new instance of PropertyItemProvider was a hack.
Replaced with getting the item-provider from the existing collection.
2014-09-04 11:05:41 +01:00
leekelleher 04e57b7d6b Bug fix with the Courier resolver 2014-09-02 16:52:41 +01:00
Kevin Giszewski 9e8cc0c556 Merge pull request #218 from leekelleher/feature/courier-upgrade
Bug fix with the Courier resolver
2014-09-02 11:52:27 -04:00
Kevin Giszewski 8fe90c3b86 Merge pull request #216 from leekelleher/feature/courier-upgrade
Courier upgrade (UaaS)
2014-09-02 08:58:20 -04:00
Kevin Giszewski 99581b0aeb Merge pull request #217 from leekelleher/develop
Housekeeping
2014-09-02 08:57:35 -04:00
leekelleher d8939c59a0 Set the project's assembly references to not "Copy Local".
As these pollute the /bin output folder during build.
2014-09-02 13:30:21 +01:00
leekelleher e49fe6ee17 Fixed the type-name for the error log messages 2014-09-02 13:27:29 +01:00
leekelleher ca52f0a216 Fixed issue with Courier serialization.
When Courier was deserializing, it was treating any nested Archetype as a `JObject`.
The newer serializer routines in Archetype core resolve the previous issue.
2014-09-02 13:24:40 +01:00
leekelleher 08d4e4b51d PersistenceManager.Default was obsoleted, replaced calls with ExecutionContext.DatabasePersistence 2014-09-02 13:20:29 +01:00
leekelleher e9c51ee96e Upgraded Courier assemblies. 2014-09-02 13:20:15 +01:00
Kevin Giszewski b5f281cae0 Prefix property aliases to avoid core css conflicts (BREAKING) 2014-08-26 10:43:37 -04:00
Kevin Giszewski 3bbb27f85e Fix error state LESS and other stuffs 2014-08-26 10:43:13 -04:00
Kevin Giszewski 247eea3477 Merge branch 'develop' 2014-08-26 10:05:18 -04:00
Kevin Giszewski 8635fa7301 Cleanup the LESS even if a little 2014-08-26 10:05:02 -04:00
Rasmus John Pedersen e49a8d947d fixed bug with custom view 2014-08-22 10:46:45 +02:00
Kevin Giszewski 3e2e43d342 Update langs and bump version number 2014-08-21 13:00:52 -04:00
Jeavon Leopold 78ba99a52e Change Archetype value conversion attempt to pass in the Source value to ConvertSourceToObject instead of the Data value 2014-08-18 17:14:17 +01:00
Kevin Giszewski 42efa1a3d4 Merge branch 'pr/200'
Conflicts:
	app/directives/archetypeproperty.js
2014-08-18 09:43:06 -04:00
Kevin Giszewski d2f4fce808 Add enable deep requests 2014-08-18 08:55:13 -04:00
Kevin Giszewski d76a5f58d4 Merge branch 'develop' 2014-08-13 11:29:12 -04:00
Kevin Giszewski f6457416cc Make sort icon black
- WS cleanup
2014-08-13 11:28:57 -04:00
Kevin Giszewski c841813a74 decouple entityResource from the function call 2014-08-13 11:15:29 -04:00
Kevin Giszewski bcc7be94e7 fix typo 2014-08-13 11:05:27 -04:00
Kevin Giszewski e200c22244 More caching 2014-08-12 19:15:08 -04:00
Kevin Giszewski 244db7f19d Add caching to $http.gets 2014-08-12 19:04:20 -04:00
Kevin Giszewski 31f3d00b76 Add label helpers 2014-08-12 17:15:16 -04:00
Kevin Giszewski 07125bae84 Add ability to pass function as template 2014-08-12 16:56:23 -04:00
kjac f2a8286f00 Fix #131 again
Simplified the validation and fixed the problem mentioned in #131 with
only the last field in a fieldset being validated.
2014-08-11 19:12:38 +02:00
Kevin Giszewski 5725c0770e Bump version number to v1.4.1 2014-08-06 09:22:08 -04:00
Kevin Giszewski 210fbb8230 Fix for #158 2014-08-06 09:20:17 -04:00
Kevin Giszewski c8e398c726 Merge pull request #195 from imulus/feature/fix193
Fix for #193
2014-08-06 08:55:47 -04:00
Kevin Giszewski bfa882fa01 Fix for #193 2014-08-06 08:55:10 -04:00
Kevin Giszewski 876aea4007 Merge branch 'pr/186' into develop 2014-08-06 08:45:55 -04:00
Jeroen Breuer 07750c7537 Run ConvertDataToSource before ConvertSourceToObject 2014-08-05 13:17:34 +02:00
Kevin Giszewski 17a1577d09 Merge branch 'master' of github.com:imulus/Archetype 2014-07-31 13:55:07 -04:00
Kevin Giszewski 987f383139 Merge pull request #184 from imulus/fix/class-conflicts
Prefix fieldset class names to help avoid conflicts
2014-07-31 13:54:58 -04:00
Kevin Giszewski dc14f11f83 Merge pull request #191 from jbreuer/patch-5
Fix 4 for #187
2014-07-31 13:54:48 -04:00
Kevin Giszewski 500f4c4dee Merge pull request #190 from jbreuer/patch-4
Fix 3 for #187
2014-07-31 13:53:41 -04:00
Kevin Giszewski a16451df1f Merge pull request #189 from jbreuer/patch-3
Fix 2 for #187
2014-07-31 13:53:34 -04:00
Kevin Giszewski 9ac7877174 Merge pull request #188 from jbreuer/patch-2
Fix 1 for #187
2014-07-31 13:53:10 -04:00
Kevin Giszewski 4d3bcb68b3 Merge branch 'pr/188' into develop 2014-07-31 13:44:43 -04:00
Kevin Giszewski 30074fe198 Merge branch 'pr/191' into pr/188 2014-07-31 13:37:01 -04:00
Kevin Giszewski 7f0bd45a9d Merge branch 'pr/190' into pr/188 2014-07-31 13:36:59 -04:00
Kevin Giszewski 6045eed5c5 Merge branch 'pr/189' into pr/188 2014-07-31 13:36:55 -04:00
Jeroen Breuer 57ffa69ff5 Added node id 2014-07-31 12:12:35 +02:00
Jeroen Breuer 6b61dc978a Added node id 2014-07-31 12:11:51 +02:00
Jeroen Breuer c20aa64af2 Added node id 2014-07-31 12:11:02 +02:00
Jeroen Breuer 25826958a3 Fix 4 for #187 2014-07-30 16:34:33 +02:00
Jeroen Breuer b5bfbb5c25 Fix 3 for #187 2014-07-30 16:33:01 +02:00
Jeroen Breuer 9afaa024c0 Fix 2 for #187 2014-07-30 16:30:42 +02:00
Jeroen Breuer c58dcd80ff Fix 1 for #187 2014-07-30 16:26:42 +02:00
Jeroen Breuer b7c16ee6ef Fix for #185 2014-07-29 16:24:14 +02:00
tomfulton 786c547e0b Prefix fieldset class names to help avoid conflicts 2014-07-24 06:35:33 -06:00
Kevin Giszewski fbf686f559 Bump Version Number to v1.4.0 2014-07-11 10:38:08 -04:00
Kevin Giszewski 42b4076700 Merge branch 'pr/174' 2014-07-11 10:19:00 -04:00
Kevin Giszewski 5feb415093 Update some dropdown css 2014-07-11 10:17:49 -04:00
Kevin Giszewski 79c85cf86b Merge branch 'master' into pr/174 2014-07-09 16:42:18 -04:00
Kevin Giszewski a0f65370c9 Few CSS tweaks 2014-07-09 16:40:29 -04:00
Kevin Giszewski 029d17c428 Merge branch 'master' of github.com:imulus/Archetype 2014-07-09 15:46:17 -04:00
Kevin Giszewski e262d7b0c9 Re-fix the 'hide label' issue
- appears to have been undone
2014-07-09 15:46:05 -04:00
kjac 44ea6c56f5 Use propertyAlias in fieldset validation
As described in #162 the umbracoPropertyAlias has been removed in favor
of a more unique propertyAlias. This propertyAlias should be used for
property identification in the validation.
2014-07-01 22:28:20 +02:00
leekelleher d7477eaf6d Moved the ArchetypePropertyModel.CreateDummyPropertyType to an extension method.
With a view to re-use in the Courier DataResolver (as it does the same function).
2014-07-01 21:46:25 +02:00
leekelleher c33649201f Separated out the extension methods into their own grouped classes.
Implements #172
2014-07-01 21:46:25 +02:00
leekelleher 3940955360 Code tidy-up; correct method naming; removed unused references 2014-07-01 21:46:24 +02:00
leekelleher 03f66a35f7 Refactored the DataResolver, as the underlying JSON value for the property had been modified (fields removed). 2014-07-01 21:46:24 +02:00
leekelleher b4b60dd89c Add the 'Archetype.Courier' project.
Includes the Courier DataResolver for Archetype.
2014-07-01 21:46:23 +02:00
leekelleher 4105912394 Code tidy-up: removed the "Models" namespace from the type name. 2014-07-01 21:46:22 +02:00
Kevin Giszewski 7b3d31f897 Merge pull request #173 from leekelleher/feature/issues/172
Separated out the extension methods into their own grouped classes
2014-07-01 11:52:43 -04:00
leekelleher 50861badf1 Moved the ArchetypePropertyModel.CreateDummyPropertyType to an extension method.
With a view to re-use in the Courier DataResolver (as it does the same function).
2014-07-01 16:49:20 +01:00
leekelleher fa682c3717 Separated out the extension methods into their own grouped classes.
Implements #172
2014-07-01 16:48:13 +01:00
Kevin Giszewski d18d1ff0b1 Merge pull request #171 from leekelleher/feature/courier-resolver
Includes Courier DataResolver project
2014-07-01 11:27:21 -04:00
leekelleher 247491187a Code tidy-up; correct method naming; removed unused references 2014-07-01 16:09:34 +01:00
leekelleher 80194786a1 Refactored the DataResolver, as the underlying JSON value for the property had been modified (fields removed). 2014-07-01 15:42:41 +01:00
Kevin Giszewski 72ee7b3d09 Merge pull request #170 from leekelleher/master
Code tidy-up: removed the "Models" namespace from the type name.
2014-07-01 10:20:18 -04:00
leekelleher 284b1d93dc Add the 'Archetype.Courier' project.
Includes the Courier DataResolver for Archetype.
2014-07-01 14:28:02 +01:00
leekelleher 7c5a3c34e2 Code tidy-up: removed the "Models" namespace from the type name. 2014-07-01 13:54:18 +01:00
Kevin Giszewski fa970750d1 Bump version number to v.1.3.1-beta 2014-06-30 11:22:34 -04:00
Kevin Giszewski aeeb3c7b40 Remove Serialization 2014-06-30 11:22:21 -04:00
Kevin Giszewski bdd3c2088c Bump version number to v1.3.0 2014-06-30 10:48:07 -04:00
Kevin Giszewski 80b41e4a5f Fix #168 2014-06-30 10:45:48 -04:00
Kevin Giszewski d60e7ba2f4 Merge branch 'master' into pr/166 2014-06-30 10:39:59 -04:00
Kevin Giszewski 4524320db2 Merge branch 'master' into pr/166 2014-06-30 09:47:10 -04:00
kjac 90ca77c9a9 Add localization to new config item 2014-06-28 12:51:36 +02:00
kjac 8332a841eb Implement #165 - enable/disable fieldsets 2014-06-28 12:42:36 +02:00
kjac d6a13b2335 Merge remote-tracking branch 'upstream/master' 2014-06-28 11:25:59 +02:00
cankoluman 987e5cf470 Issue #AR-8_line_endings: fix build 2014-06-27 14:27:48 +01:00
cankoluman f2e5b83795 Issue #AR-8_line_endings: fix line endings so we match the upstream 2014-06-27 14:16:54 +01:00
cankoluman 066e807847 Merge remote-tracking branch 'origin/dev/AR-6_legacy_nesting' into dev/AR-8_line_endings
Conflicts:
	app/Umbraco/Archetype.Tests/Serialization/UseCases/ArchetypeJsonConverterTest.cs
	app/Umbraco/Archetype.Tests/Serialization/UseCases/Complex/ArchetypeJsonConverterTest.cs
	app/Umbraco/Archetype.Tests/Serialization/UseCases/JsonTestModels.cs
	app/Umbraco/Umbraco.Archetype/Extensions/Extensions.cs
	app/Umbraco/Umbraco.Archetype/Properties/VersionInfo.cs
	app/Umbraco/Umbraco.Archetype/Serialization/ArchetypeJsonConverter.cs
	app/Umbraco/Umbraco.Archetype/Serialization/AsArchetypeAttribute.cs
	app/Umbraco/Umbraco.Archetype/Serialization/AsFieldsetAttribute.cs
	app/Umbraco/Umbraco.Archetype/Serialization/SerializationExtensions.cs
	config/meta.json
2014-06-27 12:47:52 +01:00
cankoluman d8378ed6bb Merge remote-tracking branch 'origin/dev/AR-1_serialization' into dev/AR-8_line_endings
Conflicts:
	app/Umbraco/Archetype.Tests/Serialization/UseCases/ArchetypeJsonConverterTest.cs
	app/Umbraco/Archetype.Tests/Serialization/UseCases/Complex/ArchetypeJsonConverterTest.cs
	app/Umbraco/Archetype.Tests/Serialization/UseCases/JsonTestModels.cs
	app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj
	app/Umbraco/Umbraco.Archetype/Extensions/Extensions.cs
	app/Umbraco/Umbraco.Archetype/Properties/VersionInfo.cs
	app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs
	app/Umbraco/Umbraco.Archetype/Serialization/ArchetypeJsonConverter.cs
	app/Umbraco/Umbraco.Archetype/Serialization/AsArchetypeAttribute.cs
	app/Umbraco/Umbraco.Archetype/Serialization/AsFieldsetAttribute.cs
	app/Umbraco/Umbraco.Archetype/Serialization/SerializationExtensions.cs
2014-06-27 12:42:40 +01:00
kjac 19ee2b890c Merge remote-tracking branch 'upstream/master' 2014-06-27 06:33:15 +02:00
Kevin Giszewski c953f12412 Merge branch 'pr/157' into pr/164 2014-06-26 15:58:31 -04:00
kjac 601f2c0d81 Fix issue #162 + improve nested validation highlighting
The fieldset.isValid property isn't necessarily initialized when the
view looks for it to determine fieldset validity. I've introduced a
validation method that counters this problem.
The validation method also ensures that any validation errors in nested
Archetypes are highlighted on the parent/root Archetype
2014-06-26 14:58:55 +02:00
kjac 283dd8af76 Merge remote-tracking branch 'upstream/master' 2014-06-26 14:23:40 +02:00
Tom Fulton c83942dc5c Update field labels to match new property alias scheme
Only for the first level, since focusing an Archetype isn't really a thing
2014-06-25 22:03:22 -04:00
Tom Fulton a0ff42a84f Merge branch 'master' into fix/unique-aliases
Conflicts:
	app/views/archetype.default.html
2014-06-25 21:49:24 -04:00
Tom Fulton ed97d586b4 Make property aliases even more unique
archetype-property-<umbracoPropertyAlias>-<fieldsetIndex>-<archetypePropertyAlias>-<archetypePropertyIndex>-<and so on...>
2014-06-25 21:46:46 -04:00
Kevin Giszewski 1bd09799b4 Fix for #160 2014-06-25 18:42:41 +02:00
Kevin Giszewski 0b77ddeef1 Fix 'hide property label' 2014-06-25 18:42:40 +02:00
kjac 2b2d0b4b0d Fix code formatting 2014-06-25 18:42:39 +02:00
kjac dc992293e1 Add default value overload to GetValue()
Fix issue #142
2014-06-25 18:42:39 +02:00
kjac 0bc1451a5c Fixing the unit tests
The call to DisposableTimer.DebugDuration() in
ArchetypeValueConverter.ConvertDataToSource() expects the propertyType
parameter to be not null, but the implementation of
ArchetypeValueConverter.ConvertDataToSource() allows the propertyType
parameter to be null. This breaks some of the unit tests.
I've added a null check in the call to DisposableTimer.DebugDuration()
to counter this issue.
2014-06-25 18:42:38 +02:00
Kevin Giszewski f052ed70a9 Merge pull request #161 from imulus/feature/fix-customviews
Fix for #160
2014-06-25 10:29:22 -04:00
Kevin Giszewski 0dedd7fb2d Fix for #160 2014-06-25 10:28:30 -04:00
Kevin Giszewski cb6455c34a Merge branch 'master' into develop 2014-06-25 08:35:07 -04:00
Kevin Giszewski f99ef697db Fix 'hide property label' 2014-06-25 08:34:54 -04:00
Tom Fulton aac015dc0b Refactor property aliases for uniqueness
Old: archetype-property-<umbracoPropertyAlias>-<fieldsetIndex>-<propertyIndex>
New: archetype-property-<umbracoPropertyAlias>-<archetypePropertyAlias>-<fieldsetIndex>

Basically, this adds the archetypePropertyAlias into the mix, to fix a case where you might have the same Archetype nested on a host Archetype twice  (ie box 1 links, box 2 links within the same Archetype - there was no uniqueness)

It also adds in the Property Alias in place of the Property "Index" (unintended side effect, but seems cool :))
2014-06-23 20:58:42 -04:00
Kevin Giszewski f7ef096ba6 Merge branch 'master' into develop 2014-06-20 08:41:49 -04:00
Kevin Giszewski a17e5b5372 Merge branch 'master' into develop 2014-06-20 08:27:04 -04:00
kjac 16a73e0c82 Fix code formatting 2014-06-20 11:06:33 +02:00
cankoluman a56864b731 Issue #AR-6_legacy_nesting: update version counter to match VersionInfo.cs 2014-06-20 09:59:15 +01:00
kjac 2f195dd588 Add default value overload to GetValue()
Fix issue #142
2014-06-20 10:58:21 +02:00
kjac 35309b863c Fixing the unit tests
The call to DisposableTimer.DebugDuration() in
ArchetypeValueConverter.ConvertDataToSource() expects the propertyType
parameter to be not null, but the implementation of
ArchetypeValueConverter.ConvertDataToSource() allows the propertyType
parameter to be null. This breaks some of the unit tests.
I've added a null check in the call to DisposableTimer.DebugDuration()
to counter this issue.
2014-06-20 10:56:29 +02:00
cankoluman da9085c244 Merge remote-tracking branch 'upstream/develop' into dev/AR-6_legacy_nesting
Conflicts:
	app/Umbraco/Archetype.Tests/Serialization/UseCases/ArchetypeJsonConverterTest.cs
	app/Umbraco/Archetype.Tests/Serialization/UseCases/Complex/ArchetypeJsonConverterTest.cs
	app/Umbraco/Archetype.Tests/Serialization/UseCases/JsonTestModels.cs
	app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj
	app/Umbraco/Umbraco.Archetype/Extensions/Extensions.cs
	app/Umbraco/Umbraco.Archetype/Properties/VersionInfo.cs
	app/Umbraco/Umbraco.Archetype/Serialization/ArchetypeJsonConverter.cs
	app/Umbraco/Umbraco.Archetype/Serialization/AsArchetypeAttribute.cs
	app/Umbraco/Umbraco.Archetype/Serialization/AsFieldsetAttribute.cs
	app/Umbraco/Umbraco.Archetype/Serialization/SerializationExtensions.cs
2014-06-20 09:35:13 +01:00
cankoluman 1d8703e211 Issue #AR-6_legacy_nesting: fix issue where legacy nested model deserialization failed after the empty fieldset fix,
- add legacy deserialization test
2014-06-18 11:04:25 +01:00
kjac 0ebf07d0f4 Merge remote-tracking branch 'upstream/master' 2014-06-18 06:25:55 +02:00
kjac 2b4cc2c429 Merge remote-tracking branch 'upstream/master' 2014-06-17 18:39:34 +02:00
Kevin Giszewski ec446b6800 Merge branch 'pr/137' into develop 2014-06-17 07:05:06 -04:00
cankoluman 67f21ee4d8 Merge branch 'dev/AR-1_serialization' into stable 2014-06-17 11:17:23 +01:00
cankoluman 0573d99218 Merge branch 'stable' into dev/AR-1_serialization 2014-06-17 11:16:28 +01:00
cankoluman a520d86ec4 Issue #AR-5_empty_json: Handle the case where the archetype json is empty:
{""fieldsets"": []}

Currently this throws an exception. Handle by setting returned model to null.
2014-06-17 11:13:25 +01:00
kjac 0048330863 Merge branch 'master' into issue131_optimized 2014-06-16 16:43:07 +02:00
kjac d07c16160a Merge remote-tracking branch 'upstream/master' 2014-06-16 16:42:25 +02:00
cankoluman 310771303c Merge branch 'dev/AR-1_serialization' into stable 2014-06-02 14:25:12 +01:00
kjac aafeebfc62 Merge remote-tracking branch 'upstream/master' 2014-05-29 11:16:01 +02:00
cankoluman b6d2b7e1dd Merge branch 'dev/AR-4_delinter_fixes' into dev/AR-1_serialization 2014-05-21 14:23:26 +01:00
cankoluman 1179147041 Issue #AR-4-delinter_fixes: simplify replace 2014-05-21 14:22:11 +01:00
cankoluman 0cfcaa3364 Issue #AR-4-delinter_fixes: change heuristic for space removal 2014-05-21 14:15:54 +01:00
cankoluman 14777a98dc Issue #AR-4-delinter_fixes: removed buggy escaped json tests 2014-05-20 16:22:47 +01:00
cankoluman a306424162 Issue #AR-4-delinter_fixes: fix issue where escaped new lines were being removed inside value quotes 2014-05-20 15:05:44 +01:00
cankoluman d124622089 Issue #AR-4-delinter_fixes: refactor delinter 2014-05-20 13:07:18 +01:00
cankoluman d9a25d1bb3 Issue #AR-4-delinter_fixes: fix all regexes except white space 2014-05-20 12:18:48 +01:00
cankoluman cda17ac754 Issue #AR-4-delinter_fixes: update remove new line 2014-05-20 10:39:09 +01:00
cankoluman d5329935aa Issue #AR-4-delinter_fixes: fixed all test failures due to jToken navigation errors.
To Do: fix erros due to incorrect space removal
2014-05-20 09:32:01 +01:00
cankoluman 1913f8bf14 Issue #AR-4-delinter_fixes: create single entry point for deserialization - 15 tests failing now 2014-05-19 16:25:20 +01:00
cankoluman 6f2eaa9859 Issue #AR-4-delinter_fixes: trying to fix delinter regex 2014-05-19 16:08:00 +01:00
cankoluman 31074ec9db Issue #AR-4-delinter_fixes: trying to sort out issue with \r\n being replaced inside values 2014-05-16 17:19:05 +01:00
cankoluman 512ecbdb05 Issue #AR-1_serialization: fixes after merge of upstream master 2014-05-15 17:02:06 +01:00
cankoluman 9a97e9102e Merge branch 'master' into dev/AR-1_serialization
Conflicts:
	app/Umbraco/Archetype.Tests/Archetype.Tests.csproj
	app/Umbraco/Umbraco.Archetype.sln
	app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj
	app/Umbraco/Umbraco.Archetype/Extensions/Extensions.cs
	app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs
2014-05-15 16:48:08 +01:00
cankoluman e9b2f4aeee Merge remote-tracking branch 'upstream/master' 2014-05-15 16:43:25 +01:00
cankoluman bdb7f247c3 Issue #AR-1_serialization: add delinter to SerializeForPersistence() 2014-05-15 16:23:48 +01:00
cankoluman 08c09a8820 Issue #AR-1_serialization: moved Delinter so serialization namespace,
- fix small issue with space detection in fieldset delinter
2014-05-15 16:13:29 +01:00
cankoluman ac84c35f67 Issue #AR-1_serialization: fix issue where property alias was incorrectly set from type alias 2014-05-15 15:06:41 +01:00
cankoluman bff8bcc562 Issue #AR-1_serialization: fix overflow issue affecting deserialization in recursively nested models 2014-05-15 14:55:12 +01:00
cankoluman 8fc209abc1 Issue #AR-1_serialization: move delinter tests into serialization tests 2014-05-15 12:42:15 +01:00
cankoluman a6a961d52a Issue #AR-1_serialization: added additional unescape model tests 2014-05-15 12:38:11 +01:00
cankoluman b289892727 Issue #AR-1_serialization: initial commit of delinter 2014-05-15 12:25:44 +01:00
cankoluman 4051734313 Issue #AR-1_serialization: got json escape test to work, added json unescape extension and tests,
To Do: migrate  test code from ArcheTypePropertyEditor if possible.
2014-05-14 12:28:37 +01:00
cankoluman ae242feed6 Issue #AR-1_serialization: add test to try to create escaped json - this still produces unescaped json.
However,
		    internal virtual PropertyEditor GetPropertyEditor(IDataTypeDefinition dtd)
		    {
		        return dtd.Id == 0
                    ? new ArchetypePropertyEditor()
                    : PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
		    }

would produce nested json. But this spec looks incorrect.
2014-05-13 15:44:33 +01:00
cankoluman f1df0f2ad9 Issue #AR-1_serialization: add tests comparing models generated object serializer and archetype.SerializeForPersistence() pathwways.
Note: SerializeForPersistence() does not generate escaped json when used on its own.
All tests passing.
2014-05-13 10:20:12 +01:00
cankoluman 475fe7c81f Issue #AR-1_serialization: fix error in IsConverter when PropertyEditorAlias is null,
- relax property token navigation so that if a nested token is not found, we return null.
2014-05-12 17:15:20 +01:00
cankoluman 9b1b3d1793 Merge branch 'dev/AR-3_ienumerable_support' into dev/AR-1_serialization 2014-05-09 16:58:23 +01:00
cankoluman f1f8b7db22 Merge branch 'dev/AR-1_serialization' into dev/AR-3_ienumerable_support 2014-05-09 16:56:49 +01:00
cankoluman 475bca3c05 Merge branch 'master' into dev/AR-1_serialization 2014-05-09 16:53:51 +01:00
cankoluman 77c501f2dd Merge remote-tracking branch 'upstream/master' 2014-05-09 16:52:55 +01:00
cankoluman 5db9bb972b Issue #AR-3_IEnumerable_support: separate use case tests 2014-05-09 16:51:33 +01:00
cankoluman f931e4a31f Issue #AR-3_IEnumerable_support: fix incorrect hard-coded json, some changes to tests. 2014-05-09 16:42:30 +01:00
cankoluman bc246b947f Issue #AR-3_IEnumerable_support: add nested model regression tests 2014-05-09 15:42:58 +01:00
cankoluman ec642fa69f Issue #AR-3_IEnumerable_support: fix issue with property extraction 2014-05-09 15:27:19 +01:00
cankoluman 1ba1fa2d83 Issue #AR-3_IEnumerable_support: added compound model regression tests 2014-05-09 14:42:31 +01:00
cankoluman 7c02539751 Issue #AR-3_IEnumerable_support: re-factor regression tests 2014-05-09 13:05:04 +01:00
cankoluman bc6fff6f73 Issue #AR-3_IEnumerable_support: regression testing - fixed issue where the default fieldset name was not assigned properly during dynamic model generation 2014-05-09 11:14:39 +01:00
cankoluman 911a74e43e Issue #AR-3_IEnumerable_support: regression testing - fixes to [AsFieldset] handling,
- use ExpandoObject for all dynamically generated models
- add additional JToken parsers
- To Do: deal with multiple item fieldset
2014-05-08 16:56:51 +01:00
cankoluman 934df00281 Issue #AR-3_IEnumerable_support: start on regression tests. 2014-05-07 17:03:08 +01:00
cankoluman df8d3a8888 Issue #AR-3_IEnumerable_support: clean-up 2014-05-07 15:37:57 +01:00
cankoluman e341732f83 Issue #AR-3_IEnumerable_support: move complex model tests to sub-folder 2014-05-07 14:24:35 +01:00
cankoluman 6c5a5c8393 Issue #AR-3_IEnumerable_support: add missing tests 2014-05-07 14:17:14 +01:00
cankoluman 5e23d845d5 Issue #AR-3_IEnumerable_support: apply naming convention to unit tests 2014-05-07 14:11:26 +01:00
cankoluman 11befe727c Issue #AR-3_IEnumerable_support: all tests passing - but branching logic is difficult. 2014-05-07 13:01:07 +01:00
cankoluman ed9ba7d41f Issue #AR-3_IEnumerable_support: add IEnumerable deserialization - tests pass.
However, some regression errors in compex model use case
2014-05-06 16:54:08 +01:00
cankoluman 1ae967e002 Issue #AR-3_IEnumerable_support: add IEnumerable serialization support - Captions serialization tests passing.
- needs cleaning up.
2014-05-06 15:01:50 +01:00
cankoluman 72303c1c83 Issue #AR-3_IEnumerable_support: fix json for simple list model - simple list model passes 2014-05-06 12:13:37 +01:00
cankoluman bc6580995a Issue #AR-3_IEnumerable_support: re-factor tests, add Enumerable tests - all failing as baseline. 2014-05-06 11:39:10 +01:00
cankoluman 52ff09f089 Merge remote-tracking branch 'origin/dev/AR-2_property_value_converters' into dev/AR-1_serialization 2014-05-01 16:51:16 +01:00
cankoluman 34e65ba57e Issue #AR-1_property_value_converters: switched to using Archetype's native GetValue<T> when getting property values,
- added umbracoSettings.config to the test project: conversion of decimal numbers, e.g. '12345.34' triggers
'NormalizeNumberDecimalSeparator' which in turn requires via 'DefaultShortStringHelper' that the umbracoSettings.config file is loaded. We added this to make sure tests deserializing decimal numbers pass.
2014-05-01 16:13:19 +01:00
cankoluman 87da7e1243 Issue #AR-1_serialization: fix tests that were failing due to changes in line-end encodings. 2014-05-01 14:24:26 +01:00
cankoluman ed86255cf0 Merge branch 'master' into dev/AR-1_serialization
Conflicts:
	app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj
	app/Umbraco/Umbraco.Archetype/Properties/VersionInfo.cs
2014-05-01 14:17:39 +01:00
cankoluman 518f68951d Merge remote-tracking branch 'upstream/master' 2014-05-01 14:12:17 +01:00
69 changed files with 1642 additions and 2230 deletions
+1
View File
@@ -58,6 +58,7 @@ module.exports = function(grunt) {
'app/directives/archetypecustomview.js',
'app/directives/localize.js',
'app/services/localization.js',
'app/helpers/labelhelpers.js',
'app/resources/propertyeditor.js'
],
dest: '<%= basePath %>/js/archetype.js'
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FE8BE437-8B11-4E49-9B02-F45994E6D723}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Archetype.Courier</RootNamespace>
<AssemblyName>Archetype.Courier</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="businesslogic">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\businesslogic.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="cms">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\cms.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="interfaces">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\interfaces.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\log4net.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.6.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Xml" />
<Reference Include="umbraco">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Umbraco.Core">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Umbraco.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Umbraco.Courier.Core">
<HintPath>lib\Umbraco.Courier.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Umbraco.Courier.DataResolvers">
<HintPath>lib\Umbraco.Courier.DataResolvers.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Umbraco.Courier.Providers">
<HintPath>lib\Umbraco.Courier.Providers.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.providers">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.providers.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\Umbraco.Archetype\Properties\VersionInfo.cs">
<Link>Properties\VersionInfo.cs</Link>
</Compile>
<Compile Include="DataResolvers\ArchetypeDataResolver.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Umbraco.Archetype\Archetype.Umbraco.csproj">
<Project>{7d185d41-4228-4978-acb8-83f9a48ad94f}</Project>
<Name>Archetype.Umbraco</Name>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -0,0 +1,168 @@
using System;
using System.Collections.Generic;
using System.Linq;
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.ProviderModel;
using Umbraco.Courier.DataResolvers;
using Umbraco.Courier.ItemProviders;
namespace Archetype.Courier.DataResolvers
{
public class ArchetypeDataResolver : PropertyDataResolverProvider
{
private enum Direction
{
Extracting,
Packaging
}
public override string EditorAlias
{
get
{
return Archetype.Constants.PropertyEditorAlias;
}
}
public override void ExtractingDataType(DataType item)
{
// No longer need to extract the DataType (int) Ids as Archetype now references the Guid [LK]
}
public override void ExtractingProperty(Item item, ContentProperty propertyData)
{
ReplacePropertyDataIds(item, propertyData, Direction.Extracting);
}
public override void PackagingDataType(DataType item)
{
AddDataTypeDependencies(item);
}
public override void PackagingProperty(Item item, ContentProperty propertyData)
{
ReplacePropertyDataIds(item, propertyData, Direction.Packaging);
}
private void AddDataTypeDependencies(DataType item)
{
if (item.Prevalues != null && item.Prevalues.Count > 0)
{
var prevalue = item.Prevalues[0];
if (prevalue.Alias.InvariantEquals(Archetype.Constants.PreValueAlias) && !string.IsNullOrWhiteSpace(prevalue.Value))
{
var config = JsonConvert.DeserializeObject<ArchetypePreValue>(prevalue.Value);
if (config != null && config.Fieldsets != null)
{
foreach (var property in config.Fieldsets.SelectMany(x => x.Properties))
{
item.Dependencies.Add(property.DataTypeGuid.ToString(), ProviderIDCollection.dataTypeItemProviderGuid);
}
item.Prevalues[0].Value = JsonConvert.SerializeObject(config, Formatting.None);
}
}
}
}
private void ReplacePropertyDataIds(Item item, ContentProperty propertyData, Direction direction)
{
if (propertyData != null && propertyData.Value != null)
{
var dataTypeId = ExecutionContext.DatabasePersistence.GetNodeId(propertyData.DataType, NodeObjectTypes.DataType);
var fakePropertyType = this.CreateDummyPropertyType(dataTypeId, this.EditorAlias);
var converter = new ArchetypeValueConverter();
var archetype = (ArchetypeModel)converter.ConvertDataToSource(fakePropertyType, propertyData.Value, false);
if (archetype != null)
{
// get the `PropertyItemProvider` from the collection.
var propertyItemProvider = ItemProviderCollection.Instance.GetProvider(ProviderIDCollection.propertyDataItemProviderGuid, this.ExecutionContext);
foreach (var property in archetype.Fieldsets.SelectMany(x => x.Properties))
{
if (property == null || string.IsNullOrWhiteSpace(property.PropertyEditorAlias))
continue;
// create a 'fake' item for Courier to process
var fakeItem = new ContentPropertyData()
{
ItemId = item.ItemId,
Name = string.Format("{0} [{1}: Nested {2} ({3})]", new[] { item.Name, this.EditorAlias, property.PropertyEditorAlias, property.Alias }),
Data = new List<ContentProperty>
{
new ContentProperty
{
Alias = property.Alias,
DataType = ExecutionContext.DatabasePersistence.GetUniqueId(property.DataTypeId, NodeObjectTypes.DataType),
PropertyEditorAlias = property.PropertyEditorAlias,
Value = property.Value
}
}
};
if (direction == Direction.Packaging)
{
try
{
// run the 'fake' item through Courier's data resolvers
ResolutionManager.Instance.PackagingItem(fakeItem, propertyItemProvider);
}
catch (Exception ex)
{
LogHelper.Error<ArchetypeDataResolver>(string.Concat("Error packaging data value: ", fakeItem.Name), ex);
}
// pass up the dependencies and resources
item.Dependencies.AddRange(fakeItem.Dependencies);
item.Resources.AddRange(fakeItem.Resources);
}
else if (direction == Direction.Extracting)
{
try
{
// run the 'fake' item through Courier's data resolvers
ResolutionManager.Instance.ExtractingItem(fakeItem, propertyItemProvider);
}
catch (Exception ex)
{
LogHelper.Error<ArchetypeDataResolver>(string.Concat("Error extracting data value: ", fakeItem.Name), ex);
}
}
if (fakeItem.Data != null && fakeItem.Data.Any())
{
var firstDataType = fakeItem.Data.FirstOrDefault();
if (firstDataType != null)
{
// set the resolved property data value
property.Value = firstDataType.Value;
// (if packaging) add a dependency for the property's data-type
if (direction == Direction.Packaging)
item.Dependencies.Add(firstDataType.DataType.ToString(), ProviderIDCollection.dataTypeItemProviderGuid);
}
}
}
// serialize the Archetype back to a string
propertyData.Value = archetype.SerializeForPersistence();
}
}
}
private PublishedPropertyType CreateDummyPropertyType(int dataTypeId, string propertyEditorAlias)
{
return new PublishedPropertyType(null, new PropertyType(new DataTypeDefinition(-1, propertyEditorAlias) { Id = dataTypeId }));
}
}
}
@@ -0,0 +1,14 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Archetype.Courier")]
[assembly: AssemblyDescription("A set of tools to support Archetype with Umbraco Courier")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Umbrella Inc Ltd")]
[assembly: AssemblyProduct("Archetype.Courier")]
[assembly: AssemblyCopyright("Copyright \xa9 Lee Kelleher, Umbrella Inc Ltd 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("6F05C431-ABBF-4D77-9D3D-5AF6C8E318AF")]
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AutoMapper" version="3.0.0" targetFramework="net45" />
<package id="ClientDependency" version="1.7.1.2" targetFramework="net45" />
<package id="ClientDependency-Mvc" version="1.7.0.4" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.6" targetFramework="net45" />
<package id="ImageProcessor" version="1.8.7.0" targetFramework="net45" />
<package id="ImageProcessor.Web" version="3.2.1.0" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="2.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="4.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="4.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="4.0.20710.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="2.0.20710.0" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" />
<package id="MySql.Data" version="6.6.5" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.2" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="UmbracoCms.Core" version="7.1.2" targetFramework="net45" />
<package id="xmlrpcnet" version="2.5.0" targetFramework="net45" />
</packages>
@@ -33,139 +33,167 @@
<ItemGroup>
<Reference Include="AutoMapper">
<HintPath>..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="AutoMapper.Net4">
<HintPath>..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.Net4.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="businesslogic, Version=1.0.5242.22740, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\businesslogic.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ClientDependency.Core">
<HintPath>..\packages\ClientDependency.1.7.1.2\lib\ClientDependency.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ClientDependency.Core.Mvc">
<HintPath>..\packages\ClientDependency-Mvc.1.7.0.4\lib\ClientDependency.Core.Mvc.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="cms, Version=1.0.5242.22741, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\cms.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="controls, Version=1.0.5242.22742, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\controls.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="CookComputing.XmlRpcV2">
<HintPath>..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Examine, Version=0.1.55.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Examine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="HtmlAgilityPack">
<HintPath>..\packages\HtmlAgilityPack.1.4.6\lib\Net45\HtmlAgilityPack.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ImageProcessor, Version=1.9.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ImageProcessor.1.9.0.0\lib\ImageProcessor.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ImageProcessor.Web, Version=3.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ImageProcessor.Web.3.2.3.0\lib\net45\ImageProcessor.Web.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="interfaces, Version=1.0.5242.22737, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\interfaces.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\log4net.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Lucene.Net">
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.ApplicationBlocks.Data, Version=1.0.1559.20655, Culture=neutral">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Microsoft.ApplicationBlocks.Data.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Microsoft.Web.Helpers.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Mvc.FixedDisplayModes">
<HintPath>..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.1\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="MiniProfiler">
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Moq">
<HintPath>..\packages\Moq.4.2.1312.1622\lib\net40\Moq.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.6.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SQLCE4Umbraco, Version=1.0.5242.22741, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\SQLCE4Umbraco.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\System.Data.SqlServerCe.dll</HintPath>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.4.0.30506.0\lib\net40\System.Net.Http.Formatting.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.4.0.30506.0\lib\net40\System.Web.Http.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll</HintPath>
<Private>True</Private>
<Private>False</Private>
</Reference>
<Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
@@ -176,56 +204,63 @@
<Reference Include="TidyNet, Version=1.0.0.0, Culture=neutral">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\TidyNet.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco, Version=1.0.5242.22743, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Umbraco.Core, Version=1.0.5242.22738, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Umbraco.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.DataLayer, Version=1.0.5242.22740, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.DataLayer.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.editorControls, Version=1.0.5242.22746, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.editorControls.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.MacroEngines, Version=1.0.5242.22747, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.MacroEngines.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.providers, Version=1.0.5242.22742, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.providers.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Umbraco.Web.UI, Version=1.0.5242.22748, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Umbraco.Web.UI.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.XmlSerializers, Version=1.0.5242.22743, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.XmlSerializers.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UmbracoExamine, Version=0.6.0.22741, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\UmbracoExamine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UrlRewritingNet.UrlRewriter, Version=2.0.60829.1, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\UrlRewritingNet.UrlRewriter.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Models\FieldsetTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PropertyValueConverter\PropertyValueConverterTests.cs" />
<Compile Include="Serialization\ArchetypeJsonConverterComplexModelTest.cs" />
<Compile Include="Serialization\ArchetypeJsonConverterTest.cs" />
<Compile Include="Serialization\JsonTestStrings.cs" />
<Compile Include="Serialization\JsonTestModels.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
@@ -236,11 +271,20 @@
<ProjectReference Include="..\Umbraco.Archetype\Archetype.Umbraco.csproj">
<Project>{7D185D41-4228-4978-ACB8-83F9A48AD94F}</Project>
<Name>Archetype.Umbraco</Name>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
@@ -34,6 +34,18 @@ namespace Archetype.Tests.Models
Assert.That(propertyValue == "Box 1 Title");
}
[Test]
public void Can_Get_Fieldset_Property_Default_Value_By_Alias()
{
var converter = new ArchetypeValueConverter();
var result = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(null, _sampleJson, false);
var fieldset = result.Fieldsets.First();
var propertyValue = fieldset.GetValue<string>("noSuchProperty", "noSuchProperty default value");
Assert.That(propertyValue == "noSuchProperty default value");
}
[Test]
public void Can_Convert_Property_Value_Types()
{
@@ -45,7 +57,7 @@ namespace Archetype.Tests.Models
Assert.That(fieldset.GetValue<int>("link") == 3175);
Assert.That(fieldset.GetValue<bool>("show") == true);
Assert.That(fieldset.GetValue<string>("blurb") == "A blurb here");
}
}
[Test]
public void Returns_String_When_No_Type_Specified()
@@ -59,6 +71,5 @@ namespace Archetype.Tests.Models
Assert.That(property is string);
Assert.That(property == "3175");
}
}
}
@@ -1,216 +0,0 @@
using System.Linq;
using Archetype.PropertyConverters;
using Newtonsoft.Json;
using NUnit.Framework;
namespace Archetype.Tests.Serialization
{
[TestFixture]
public class ArchetypeJsonConverterComplexModelTest
{
private TextList _textList;
private Captions _captions;
private PageDetails _pageDetails;
private SlideShow _slides;
private Seo _seo;
private TextPageList _textPages;
private PageList _pages;
[SetUp]
public void SetUp()
{
InitComplexModels();
InitComplexTreeModel();
}
#region complex nested model tests
[Test]
public void PageDetailsModel_Serializes_To_Archetype_Property()
{
var result = JsonConvert.SerializeObject(_pageDetails, Formatting.Indented);
Assert.AreEqual(JsonTestStrings._PAGE_DETAILS_JSON, result);
}
[Test]
public void ConvertComplexModelToArchetype()
{
var converter = new ArchetypeValueConverter();
var json = JsonConvert.SerializeObject(_pageDetails, Formatting.Indented);
var archetype = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(null, json, false);
Assert.NotNull(archetype);
}
[Test]
public void DeserializeComplexModelFromArchetype()
{
var result = JsonConvert.DeserializeObject<PageDetails>(JsonTestStrings._PAGE_DETAILS_JSON);
Assert.NotNull(result);
Assert.IsInstanceOf<PageDetails>(result);
Assert.AreEqual("2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453", result.Pages);
Assert.AreEqual("First Page", result.Captions.TextStringArray.ElementAt(0).TextString);
Assert.AreEqual("Second Page", result.Captions.TextStringArray.ElementAt(1).TextString);
Assert.AreEqual("Third Page", result.Captions.TextStringArray.ElementAt(2).TextString);
Assert.AreEqual("Fourth Page", result.Captions.TextStringArray.ElementAt(3).TextString);
}
[Test]
public void SerializeThenDeserializeComplexModelFromArchetype()
{
var json = JsonConvert.SerializeObject(_pageDetails);
var result = JsonConvert.DeserializeObject<PageDetails>(json);
Assert.NotNull(result);
Assert.IsInstanceOf<PageDetails>(result);
Assert.AreEqual(_pageDetails.Pages, result.Pages);
Assert.AreEqual(_pageDetails.Captions.TextStringArray.ElementAt(0).TextString, result.Captions.TextStringArray.ElementAt(0).TextString);
Assert.AreEqual(_pageDetails.Captions.TextStringArray.ElementAt(1).TextString, result.Captions.TextStringArray.ElementAt(1).TextString);
Assert.AreEqual(_pageDetails.Captions.TextStringArray.ElementAt(2).TextString, result.Captions.TextStringArray.ElementAt(2).TextString);
Assert.AreEqual(_pageDetails.Captions.TextStringArray.ElementAt(3).TextString, result.Captions.TextStringArray.ElementAt(3).TextString);
}
#endregion
#region complex nested tree model tests
[Test]
public void ConvertComplexNestedModelToArchetype()
{
var converter = new ArchetypeValueConverter();
var json = JsonConvert.SerializeObject(_pages, Formatting.Indented);
var archetype = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(null, json, false);
Assert.NotNull(archetype);
}
[Test]
public void PagesModel_Serializes_To_Archetype_Property()
{
var result = JsonConvert.SerializeObject(_pages, Formatting.Indented);
Assert.AreEqual(JsonTestStrings._PAGES_JSON, result);
}
[Test]
public void DeserializeComplexTreeModelFromArchetype()
{
var result = JsonConvert.DeserializeObject<PageList>(JsonTestStrings._PAGES_JSON);
Assert.NotNull(result);
Assert.IsInstanceOf<PageList>(result);
Assert.AreEqual("1,2,3,4,5,6,7,8", result.Pages.ElementAt(0).Media.Slides);
Assert.AreEqual("1,2,3,4,5,6,7,8", result.Pages.ElementAt(1).Media.Slides);
Assert.AreEqual("1,2,3,4,5,6,7,8", result.Pages.ElementAt(2).Media.Slides);
Assert.AreEqual("Test Meta Title", result.Pages.ElementAt(0).Seo.MetaTitle);
Assert.AreEqual("Test Meta Description", result.Pages.ElementAt(0).Seo.MetaDescription);
Assert.AreEqual("Test Meta Title", result.Pages.ElementAt(1).Seo.MetaTitle);
Assert.AreEqual("Test Meta Description", result.Pages.ElementAt(1).Seo.MetaDescription);
Assert.AreEqual("Test Meta Title", result.Pages.ElementAt(2).Seo.MetaTitle);
Assert.AreEqual("Test Meta Description", result.Pages.ElementAt(2).Seo.MetaDescription);
Assert.AreEqual("Home Page Body", result.Pages.ElementAt(0).BodyText);
Assert.AreEqual("Home Page", result.Pages.ElementAt(0).PageTitle);
Assert.AreEqual("About us Page Body", result.Pages.ElementAt(1).BodyText);
Assert.AreEqual("About us Page", result.Pages.ElementAt(1).PageTitle);
Assert.AreEqual("Contact us Page Body", result.Pages.ElementAt(2).BodyText);
Assert.AreEqual("Contact us Page", result.Pages.ElementAt(2).PageTitle);
}
[Test]
public void SerializeThenDeserializeComplexTreeModelFromArchetype()
{
var json = JsonConvert.SerializeObject(_pages);
var result = JsonConvert.DeserializeObject<PageList>(json);
Assert.NotNull(result);
Assert.IsInstanceOf<PageList>(result);
Assert.AreEqual(_pages.Pages.ElementAt(0).Media.Slides, result.Pages.ElementAt(0).Media.Slides);
Assert.AreEqual(_pages.Pages.ElementAt(1).Media.Slides, result.Pages.ElementAt(1).Media.Slides);
Assert.AreEqual(_pages.Pages.ElementAt(2).Media.Slides, result.Pages.ElementAt(2).Media.Slides);
Assert.AreEqual(_pages.Pages.ElementAt(0).Seo.MetaTitle, result.Pages.ElementAt(0).Seo.MetaTitle);
Assert.AreEqual(_pages.Pages.ElementAt(0).Seo.MetaDescription, result.Pages.ElementAt(0).Seo.MetaDescription);
Assert.AreEqual(_pages.Pages.ElementAt(1).Seo.MetaTitle, result.Pages.ElementAt(1).Seo.MetaTitle);
Assert.AreEqual(_pages.Pages.ElementAt(1).Seo.MetaDescription, result.Pages.ElementAt(1).Seo.MetaDescription);
Assert.AreEqual(_pages.Pages.ElementAt(2).Seo.MetaTitle, result.Pages.ElementAt(2).Seo.MetaTitle);
Assert.AreEqual(_pages.Pages.ElementAt(2).Seo.MetaDescription, result.Pages.ElementAt(2).Seo.MetaDescription);
Assert.AreEqual(_pages.Pages.ElementAt(0).BodyText, result.Pages.ElementAt(0).BodyText);
Assert.AreEqual(_pages.Pages.ElementAt(0).PageTitle, result.Pages.ElementAt(0).PageTitle);
Assert.AreEqual(_pages.Pages.ElementAt(1).BodyText, result.Pages.ElementAt(1).BodyText);
Assert.AreEqual(_pages.Pages.ElementAt(1).PageTitle, result.Pages.ElementAt(1).PageTitle);
Assert.AreEqual(_pages.Pages.ElementAt(2).BodyText, result.Pages.ElementAt(2).BodyText);
Assert.AreEqual(_pages.Pages.ElementAt(2).PageTitle, result.Pages.ElementAt(2).PageTitle);
}
#endregion
#region utility methods
private void InitComplexModels()
{
_textList = new TextList
{
new TextItem{TextString = "First Page"},
new TextItem{TextString = "Second Page"},
new TextItem{TextString = "Third Page"},
new TextItem{TextString = "Fourth Page"}
};
_captions = new Captions {TextStringArray = _textList};
_pageDetails = new PageDetails
{
Captions = _captions,
Pages = "2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453"
};
}
private void InitComplexTreeModel()
{
_slides = new SlideShow{Slides = "1,2,3,4,5,6,7,8"};
_seo = new Seo{MetaDescription = "Test Meta Description", MetaTitle = "Test Meta Title"};
_textPages = new TextPageList
{
new TextPage()
{
PageTitle = "Home Page",
BodyText = "Home Page Body",
Media = _slides,
Seo = _seo
},
new TextPage()
{
PageTitle = "About us Page",
BodyText = "About us Page Body",
Media = _slides,
Seo = _seo
},
new TextPage()
{
PageTitle = "Contact us Page",
BodyText = "Contact us Page Body",
Media = _slides,
Seo = _seo
}
};
_pages = new PageList
{
Pages = _textPages
};
}
#endregion
}
}
@@ -1,367 +0,0 @@
using System;
using Archetype.PropertyConverters;
using Newtonsoft.Json;
using NUnit.Framework;
namespace Archetype.Tests.Serialization
{
[TestFixture]
public class ArchetypeJsonConverterTest
{
private ContactDetails _contactDetails;
private CompanyDetails _companyDetails;
private AnnualStatement _annualStatement;
private MergerDetails _mergerDetails;
private UrlPicker _webSite;
[SetUp]
public void SetUp()
{
_webSite = new UrlPicker
{
Url = "http://test.com",
Title = "The Test Company",
OpenInNewWindow = true
};
_mergerDetails = new MergerDetails
{
MergerDate = new DateTime(2014,6,7,8,9,10),
MergerValue = 12345676890.12m
};
_contactDetails = new ContactDetails
{
Address = "Test Address",
Email = "test@test.com",
Fax = "000",
Mobile = "000",
Name = "Test",
Telephone = "111",
WebSite = _webSite
};
_companyDetails = new CompanyDetails
{
Region = "Test Region",
ContactDetails = _contactDetails
};
_annualStatement = new AnnualStatement
{
FiscalYearStart = new DateTime(2013, 9, 1),
FiscalYearEnd = new DateTime(2014, 8, 31),
TotalShares = 345678,
Sales = 123456700.89,
Profit = 1123456.78m
};
}
#region serialization tests
[Test]
public void MergerDetailsModel_Serializes_To_Archetype_Property()
{
var result = JsonConvert.SerializeObject(_mergerDetails, Formatting.Indented);
Assert.AreEqual(JsonTestStrings._MERGER_DETAILS_JSON, result);
}
[Test]
public void ContactDetailsModel_Serializes_To_Archetype_Property()
{
var result = JsonConvert.SerializeObject(_contactDetails, Formatting.Indented);
Assert.AreEqual(JsonTestStrings._CONTACT_DETAILS_JSON, result);
}
[Test]
public void CompanyDetailsModel_Fieldset_Serializes_As_Expected()
{
var result = JsonConvert.SerializeObject(_companyDetails, Formatting.Indented);
Assert.AreEqual(JsonTestStrings._COMPANY_DETAILS_JSON, result);
}
[Test]
public void AnnualStatementModel_Fieldset_Serializes_As_Expected()
{
var result = JsonConvert.SerializeObject(_annualStatement, Formatting.Indented);
Assert.AreEqual(JsonTestStrings._ANNUAL_STATEMENT_JSON, result);
}
[Test]
public void NullValues_Serialize_To_Empty_String()
{
var result = JsonConvert.SerializeObject(new ContactDetails());
Assert.AreEqual(JsonTestStrings._NULL_VALUES_JSON, result);
}
[Test]
public void ConvertModelToArchetype()
{
var model = new ContactDetails
{
Address = "addr",
Email = "email"
};
var converter = new ArchetypeValueConverter();
var json = JsonConvert.SerializeObject(model);
var archetype = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(null, json, false);
Assert.NotNull(archetype);
}
[Test]
public void ConvertNumericAndDateModelToArchetype()
{
var converter = new ArchetypeValueConverter();
var json = JsonConvert.SerializeObject(_annualStatement);
var archetype = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(null, json, false);
Assert.NotNull(archetype);
}
[Test]
public void ConvertCompoundModelToArchetype()
{
var item1 = new ContactDetails
{
Address = "addr",
Email = "email"
};
var item2 = new ContactDetails
{
Address = "addr1",
Name = "email2"
};
var model = new AllContactDetails
{
UserDetails = item1,
AdminDetails = item2
};
var converter = new ArchetypeValueConverter();
var json = JsonConvert.SerializeObject(model, Formatting.Indented);
var archetype = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(null, json, false);
Assert.NotNull(archetype);
}
[Test]
public void ConvertEnumerableModelToArchetype()
{
var item1 = new ContactDetails
{
Address = "addr",
Email = "email"
};
var item2 = new ContactDetails
{
Address = "addr1",
Name = "email2"
};
var model = new ContactDetailsList
{
item1,
item2
};
var converter = new ArchetypeValueConverter();
var json = JsonConvert.SerializeObject(model, Formatting.Indented);
var archetype = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(null, json, false);
Assert.NotNull(archetype);
}
[Test]
public void ConvertNestedModelToArchetype()
{
var model = new CompanyDetails
{
Region = "Test Region",
ContactDetails = new ContactDetails
{
Address = "addr1",
Name = "email2"
}
};
var converter = new ArchetypeValueConverter();
var json = JsonConvert.SerializeObject(model, Formatting.Indented);
var archetype = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(null, json, false);
Assert.NotNull(archetype);
}
#endregion
#region deserialization tests
[Test]
public void DeserializeModelFromArchetype()
{
var result = JsonConvert.DeserializeObject<ContactDetails>(JsonTestStrings._CONTACT_DETAILS_JSON);
Assert.NotNull(result);
Assert.IsInstanceOf<ContactDetails>(result);
Assert.AreEqual("Test Address", result.Address);
Assert.AreEqual("test@test.com", result.Email);
Assert.AreEqual("000", result.Fax);
Assert.AreEqual("000", result.Mobile);
Assert.AreEqual("Test", result.Name);
Assert.AreEqual("111", result.Telephone);
Assert.AreEqual(_webSite.Content, result.WebSite.Content);
Assert.AreEqual(_webSite.Media, result.WebSite.Media);
Assert.AreEqual(_webSite.OpenInNewWindow, result.WebSite.OpenInNewWindow);
Assert.AreEqual(_webSite.Title, result.WebSite.Title);
Assert.AreEqual(_webSite.Url, result.WebSite.Url);
}
[Test]
public void DeserializeNumericAndDateModelFromArchetype()
{
var result = JsonConvert.DeserializeObject<AnnualStatement>(JsonTestStrings._ANNUAL_STATEMENT_JSON);
Assert.NotNull(result);
Assert.IsInstanceOf<AnnualStatement>(result);
Assert.AreEqual(new DateTime(2013, 9, 1), result.FiscalYearStart);
Assert.AreEqual(new DateTime(2014, 8, 31), result.FiscalYearEnd);
Assert.IsNull(result.DividendPaymentDate);
Assert.AreEqual(345678, result.TotalShares);
Assert.AreEqual(123456700.89, result.Sales);
Assert.AreEqual(1123456.78m, result.Profit);
}
[Test]
public void DeserializeNumericAndDateModel_NullableDate_HasValue_FromArchetype()
{
var annualStatement = new AnnualStatement
{
FiscalYearStart = new DateTime(2013, 9, 1),
FiscalYearEnd = new DateTime(2014, 8, 31),
DividendPaymentDate = new DateTime(2014,9,15,10,15,30),
TotalShares = 345678,
Sales = 123456700.89,
Profit = 1123456.78m
};
var json = JsonConvert.SerializeObject(annualStatement);
var result = JsonConvert.DeserializeObject<AnnualStatement>(json);
Assert.NotNull(result);
Assert.IsInstanceOf<AnnualStatement>(result);
Assert.AreEqual(annualStatement.FiscalYearStart, result.FiscalYearStart);
Assert.AreEqual(annualStatement.FiscalYearEnd, result.FiscalYearEnd);
Assert.AreEqual(annualStatement.DividendPaymentDate, result.DividendPaymentDate);
Assert.AreEqual(annualStatement.TotalShares, result.TotalShares);
Assert.AreEqual(annualStatement.Sales, result.Sales);
Assert.AreEqual(annualStatement.Profit, result.Profit);
}
[Test]
public void DeserializeCompoundModelFromArchetype()
{
var item1 = new ContactDetails
{
Address = "addr",
Email = "email"
};
var item2 = new ContactDetails
{
Address = "addr1",
Name = "email2"
};
var model = new AllContactDetails
{
UserDetails = item1,
AdminDetails = item2
};
var json = JsonConvert.SerializeObject(model, Formatting.Indented);
var result = JsonConvert.DeserializeObject<AllContactDetails>(json);
Assert.NotNull(result);
Assert.IsInstanceOf<AllContactDetails>(result);
Assert.AreEqual(item1.Address, result.UserDetails.Address);
Assert.AreEqual(item1.Email, result.UserDetails.Email);
Assert.AreEqual(item2.Address, result.AdminDetails.Address);
Assert.AreEqual(item2.Name, result.AdminDetails.Name);
}
[Test]
public void DeserializeEnumerableModelFromArchetype()
{
var item1 = new ContactDetails
{
Address = "addr",
Email = "email"
};
var item2 = new ContactDetails
{
Address = "addr1",
Name = "email2"
};
var model = new ContactDetailsList
{
item1,
item2
};
var json = JsonConvert.SerializeObject(model, Formatting.Indented);
var result = JsonConvert.DeserializeObject<ContactDetailsList>(json);
Assert.NotNull(result);
Assert.IsInstanceOf<ContactDetailsList>(result);
Assert.AreEqual(result.Count, 2);
Assert.AreEqual(item1.Address, result[0].Address);
Assert.AreEqual(item1.Email, result[0].Email);
Assert.AreEqual(item2.Address, result[1].Address);
Assert.AreEqual(item2.Name, result[1].Name);
}
[Test]
public void DeserializeNestedModelFromArchetype()
{
var model = new CompanyDetails
{
Region = "Test Region",
ContactDetails = new ContactDetails
{
Address = "addr1",
Name = "email2"
}
};
var json = JsonConvert.SerializeObject(model, Formatting.Indented);
var result = JsonConvert.DeserializeObject<CompanyDetails>(json);
Assert.NotNull(result);
Assert.IsInstanceOf<CompanyDetails>(result);
Assert.AreEqual(model.Region, result.Region);
Assert.AreEqual(model.ContactDetails.Address, result.ContactDetails.Address);
Assert.AreEqual(model.ContactDetails.Name, result.ContactDetails.Name);
}
#endregion
}
}
@@ -1,179 +0,0 @@
using System;
using System.Collections.Generic;
using Archetype.Serialization;
using Newtonsoft.Json;
namespace Archetype.Tests.Serialization
{
#region json test Models
[AsArchetype("urlPicker")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class UrlPicker
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("content")]
public int? Content { get; set; }
[JsonProperty("media")]
public int? Media { get; set; }
[JsonProperty("openInNewWindow")]
public bool OpenInNewWindow { get; set; }
}
[AsArchetype("contactDetails")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class ContactDetails
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("address")]
public string Address { get; set; }
[JsonProperty("telephone")]
public string Telephone { get; set; }
[JsonProperty("mobile")]
public string Mobile { get; set; }
[JsonProperty("fax")]
public string Fax { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("webSite")]
public UrlPicker WebSite { get; set; }
}
[AsArchetype("companyDetails")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class CompanyDetails
{
[JsonProperty("region")]
public string Region { get; set; }
[JsonProperty("contactDetails")]
public ContactDetails ContactDetails { get; set; }
}
[AsArchetype("allContactDetails")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class AllContactDetails
{
public ContactDetails UserDetails { get; set; }
public ContactDetails AdminDetails { get; set; }
}
[AsArchetype("contactDetailsList")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class ContactDetailsList : List<ContactDetails>
{
}
[AsArchetype("annualStatement")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class AnnualStatement
{
public DateTime FiscalYearStart { get; set; }
public DateTime FiscalYearEnd { get; set; }
public DateTime? DividendPaymentDate { get; set; }
public Int32 TotalShares { get; set; }
public Double Sales { get; set; }
public Decimal Profit { get; set; }
}
[AsArchetype("mergerDetails")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class MergerDetails
{
public DateTime MergerDate { get; set; }
[JsonIgnore]
public decimal MergerValue { get; set; }
}
#endregion
#region complex nested model
[AsArchetype("pages")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class PageDetails
{
[JsonProperty("pages")]
public string Pages { get; set; }
[AsFieldset]
[JsonProperty("captions")]
public Captions Captions { get; set; }
}
[AsArchetype("captions")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class Captions
{
[JsonProperty("captions")]
public TextList TextStringArray { get; set; }
}
[AsArchetype("textstringArray")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class TextList : List<TextItem>
{
}
[AsArchetype("textstringArray")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class TextItem
{
[JsonProperty("textstring")]
public string TextString { get; set; }
}
#endregion
#region complex nested tree model
public abstract class PageBase
{
public string PageTitle { get; set; }
public string BodyText { get; set; }
}
[AsArchetype("slideShow")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class SlideShow
{
public string Slides { get; set; }
}
[AsArchetype("seo")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class Seo
{
public string MetaTitle { get; set; }
public string MetaDescription { get; set; }
}
[AsArchetype("TextPage")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class TextPage : PageBase
{
[AsFieldset]
public SlideShow Media { get; set; }
[AsFieldset]
public Seo Seo { get; set; }
}
[AsArchetype("TextPageList")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class TextPageList : List<TextPage>
{
}
[AsArchetype("Pages")]
[JsonConverter(typeof(ArchetypeJsonConverter))]
public class PageList
{
public TextPageList Pages { get; set; }
}
#endregion
}
@@ -1,435 +0,0 @@
namespace Archetype.Tests.Serialization
{
public class JsonTestStrings
{
public const string _MERGER_DETAILS_JSON =
@"{
""fieldsets"": [
{
""alias"": ""mergerDetails"",
""properties"": [
{
""alias"": ""MergerDate"",
""value"": ""07/06/2014 08:09:10""
}
]
}
]
}";
public const string _ANNUAL_STATEMENT_JSON =
@"{
""fieldsets"": [
{
""alias"": ""annualStatement"",
""properties"": [
{
""alias"": ""FiscalYearStart"",
""value"": ""01/09/2013 00:00:00""
},
{
""alias"": ""FiscalYearEnd"",
""value"": ""31/08/2014 00:00:00""
},
{
""alias"": ""DividendPaymentDate"",
""value"": """"
},
{
""alias"": ""TotalShares"",
""value"": ""345678""
},
{
""alias"": ""Sales"",
""value"": ""123456700.89""
},
{
""alias"": ""Profit"",
""value"": ""1123456.78""
}
]
}
]
}";
public const string _CONTACT_DETAILS_JSON =
@"{
""fieldsets"": [
{
""alias"": ""contactDetails"",
""properties"": [
{
""alias"": ""name"",
""value"": ""Test""
},
{
""alias"": ""address"",
""value"": ""Test Address""
},
{
""alias"": ""telephone"",
""value"": ""111""
},
{
""alias"": ""mobile"",
""value"": ""000""
},
{
""alias"": ""fax"",
""value"": ""000""
},
{
""alias"": ""email"",
""value"": ""test@test.com""
},
{
""alias"": ""webSite"",
""value"": {
""fieldsets"": [
{
""alias"": ""urlPicker"",
""properties"": [
{
""alias"": ""title"",
""value"": ""The Test Company""
},
{
""alias"": ""url"",
""value"": ""http://test.com""
},
{
""alias"": ""content"",
""value"": """"
},
{
""alias"": ""media"",
""value"": """"
},
{
""alias"": ""openInNewWindow"",
""value"": ""1""
}
]
}
]
}
}
]
}
]
}";
public const string _COMPANY_DETAILS_JSON =
@"{
""fieldsets"": [
{
""alias"": ""companyDetails"",
""properties"": [
{
""alias"": ""region"",
""value"": ""Test Region""
},
{
""alias"": ""contactDetails"",
""value"": {
""fieldsets"": [
{
""alias"": ""contactDetails"",
""properties"": [
{
""alias"": ""name"",
""value"": ""Test""
},
{
""alias"": ""address"",
""value"": ""Test Address""
},
{
""alias"": ""telephone"",
""value"": ""111""
},
{
""alias"": ""mobile"",
""value"": ""000""
},
{
""alias"": ""fax"",
""value"": ""000""
},
{
""alias"": ""email"",
""value"": ""test@test.com""
},
{
""alias"": ""webSite"",
""value"": {
""fieldsets"": [
{
""alias"": ""urlPicker"",
""properties"": [
{
""alias"": ""title"",
""value"": ""The Test Company""
},
{
""alias"": ""url"",
""value"": ""http://test.com""
},
{
""alias"": ""content"",
""value"": """"
},
{
""alias"": ""media"",
""value"": """"
},
{
""alias"": ""openInNewWindow"",
""value"": ""1""
}
]
}
]
}
}
]
}
]
}
}
]
}
]
}";
public const string _PAGE_DETAILS_JSON =
@"{
""fieldsets"": [
{
""alias"": ""pages"",
""properties"": [
{
""alias"": ""pages"",
""value"": ""2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453""
}
]
},
{
""alias"": ""captions"",
""properties"": [
{
""alias"": ""captions"",
""value"": {
""fieldsets"": [
{
""alias"": ""textstringArray"",
""properties"": [
{
""alias"": ""textstring"",
""value"": ""First Page""
}
]
},
{
""alias"": ""textstringArray"",
""properties"": [
{
""alias"": ""textstring"",
""value"": ""Second Page""
}
]
},
{
""alias"": ""textstringArray"",
""properties"": [
{
""alias"": ""textstring"",
""value"": ""Third Page""
}
]
},
{
""alias"": ""textstringArray"",
""properties"": [
{
""alias"": ""textstring"",
""value"": ""Fourth Page""
}
]
}
]
}
}
]
}
]
}";
public const string _PAGES_JSON =
@"{
""fieldsets"": [
{
""alias"": ""Pages"",
""properties"": [
{
""alias"": ""Pages"",
""value"": {
""fieldsets"": [
{
""alias"": ""TextPage"",
""properties"": [
{
""alias"": ""Media"",
""value"": {
""fieldsets"": [
{
""alias"": ""slideShow"",
""properties"": [
{
""alias"": ""Slides"",
""value"": ""1,2,3,4,5,6,7,8""
}
]
}
]
}
},
{
""alias"": ""Seo"",
""value"": {
""fieldsets"": [
{
""alias"": ""seo"",
""properties"": [
{
""alias"": ""MetaTitle"",
""value"": ""Test Meta Title""
},
{
""alias"": ""MetaDescription"",
""value"": ""Test Meta Description""
}
]
}
]
}
},
{
""alias"": ""PageTitle"",
""value"": ""Home Page""
},
{
""alias"": ""BodyText"",
""value"": ""Home Page Body""
}
]
},
{
""alias"": ""TextPage"",
""properties"": [
{
""alias"": ""Media"",
""value"": {
""fieldsets"": [
{
""alias"": ""slideShow"",
""properties"": [
{
""alias"": ""Slides"",
""value"": ""1,2,3,4,5,6,7,8""
}
]
}
]
}
},
{
""alias"": ""Seo"",
""value"": {
""fieldsets"": [
{
""alias"": ""seo"",
""properties"": [
{
""alias"": ""MetaTitle"",
""value"": ""Test Meta Title""
},
{
""alias"": ""MetaDescription"",
""value"": ""Test Meta Description""
}
]
}
]
}
},
{
""alias"": ""PageTitle"",
""value"": ""About us Page""
},
{
""alias"": ""BodyText"",
""value"": ""About us Page Body""
}
]
},
{
""alias"": ""TextPage"",
""properties"": [
{
""alias"": ""Media"",
""value"": {
""fieldsets"": [
{
""alias"": ""slideShow"",
""properties"": [
{
""alias"": ""Slides"",
""value"": ""1,2,3,4,5,6,7,8""
}
]
}
]
}
},
{
""alias"": ""Seo"",
""value"": {
""fieldsets"": [
{
""alias"": ""seo"",
""properties"": [
{
""alias"": ""MetaTitle"",
""value"": ""Test Meta Title""
},
{
""alias"": ""MetaDescription"",
""value"": ""Test Meta Description""
}
]
}
]
}
},
{
""alias"": ""PageTitle"",
""value"": ""Contact us Page""
},
{
""alias"": ""BodyText"",
""value"": ""Contact us Page Body""
}
]
}
]
}
}
]
}
]
}";
public const string _NULL_VALUES_JSON = @"{""fieldsets"":[{""alias"":""contactDetails"",""properties"":[{""alias"":""name"",""value"":""""},{""alias"":""address"",""value"":""""},{""alias"":""telephone"",""value"":""""},{""alias"":""mobile"",""value"":""""},{""alias"":""fax"",""value"":""""},{""alias"":""email"",""value"":""""},{""alias"":""webSite"",""value"":""""}]}]}";
}
}
+9 -1
View File
@@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<configSections>
<sectionGroup name="umbracoConfiguration">
<section name="settings" type="Umbraco.Core.Configuration.UmbracoSettings.UmbracoSettingsSection, Umbraco.Core" requirePermission="false" />
</sectionGroup>
</configSections>
<umbracoConfiguration>
<settings configSource="config\umbracoSettings.config" />
</umbracoConfiguration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+46 -9
View File
@@ -33,119 +33,145 @@
<ItemGroup>
<Reference Include="AutoMapper">
<HintPath>..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="AutoMapper.Net4">
<HintPath>..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.Net4.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="businesslogic">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\businesslogic.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ClientDependency.Core">
<HintPath>..\packages\ClientDependency.1.7.1.2\lib\ClientDependency.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ClientDependency.Core.Mvc">
<HintPath>..\packages\ClientDependency-Mvc.1.7.0.4\lib\ClientDependency.Core.Mvc.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="cms">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\cms.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="controls">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\controls.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="CookComputing.XmlRpcV2">
<HintPath>..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Examine">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Examine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="HtmlAgilityPack">
<HintPath>..\packages\HtmlAgilityPack.1.4.6\lib\Net45\HtmlAgilityPack.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ImageProcessor">
<HintPath>..\packages\ImageProcessor.1.9.0.0\lib\ImageProcessor.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ImageProcessor.Web">
<HintPath>..\packages\ImageProcessor.Web.3.2.3.0\lib\net45\ImageProcessor.Web.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="interfaces">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\interfaces.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\log4net.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Lucene.Net">
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.ApplicationBlocks.Data">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Microsoft.ApplicationBlocks.Data.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Web.Helpers">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Microsoft.Web.Helpers.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Mvc.FixedDisplayModes">
<HintPath>..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.0\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="MiniProfiler">
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.6.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SQLCE4Umbraco">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\SQLCE4Umbraco.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\System.Data.SqlServerCe.dll</HintPath>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.4.0.30506.0\lib\net40\System.Net.Http.Formatting.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.4.0.20710.0\lib\net40\System.Web.Http.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.20710.0\lib\net40\System.Web.Http.WebHost.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.Razor.2.0.20710.0\lib\net40\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<Private>False</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
@@ -155,36 +181,47 @@
<Reference Include="System.Xml" />
<Reference Include="TidyNet">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\TidyNet.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Umbraco.Core">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Umbraco.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.DataLayer">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.DataLayer.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.editorControls">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.editorControls.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.MacroEngines">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.MacroEngines.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.providers">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.providers.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Umbraco.Web.UI">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\Umbraco.Web.UI.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="umbraco.XmlSerializers">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.XmlSerializers.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UmbracoExamine">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\UmbracoExamine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UrlRewritingNet.UrlRewriter">
<HintPath>..\packages\UmbracoCms.Core.7.1.2\lib\UrlRewritingNet.UrlRewriter.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
+6
View File
@@ -14,6 +14,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Archetype.Tests", "Archetyp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseSizer", "DatabaseSizer\DatabaseSizer.csproj", "{0114C963-C514-49C1-B7AB-DCB1825F498C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Archetype.Courier", "Archetype.Courier\Archetype.Courier.csproj", "{FE8BE437-8B11-4E49-9B02-F45994E6D723}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -32,6 +34,10 @@ Global
{0114C963-C514-49C1-B7AB-DCB1825F498C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0114C963-C514-49C1-B7AB-DCB1825F498C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0114C963-C514-49C1-B7AB-DCB1825F498C}.Release|Any CPU.Build.0 = Release|Any CPU
{FE8BE437-8B11-4E49-9B02-F45994E6D723}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE8BE437-8B11-4E49-9B02-F45994E6D723}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE8BE437-8B11-4E49-9B02-F45994E6D723}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE8BE437-8B11-4E49-9B02-F45994E6D723}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -38,5 +38,16 @@ namespace Archetype.Api
var dataTypeDisplay = Mapper.Map<IDataTypeDefinition, DataTypeDisplay>(dataType);
return new { selectedEditor = dataTypeDisplay.SelectedEditor, preValues = dataTypeDisplay.PreValues };
}
public object GetByGuid(Guid guid, string contentTypeAlias, string propertyTypeAlias, string archetypeAlias, int nodeId)
{
var dataType = Services.DataTypeService.GetDataTypeDefinitionById(guid);
if (dataType == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
var dataTypeDisplay = Mapper.Map<IDataTypeDefinition, DataTypeDisplay>(dataType);
return new { selectedEditor = dataTypeDisplay.SelectedEditor, preValues = dataTypeDisplay.PreValues, contentTypeAlias = contentTypeAlias, propertyTypeAlias = propertyTypeAlias, archetypeAlias = archetypeAlias, nodeId = nodeId };
}
}
}
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
@@ -232,7 +232,9 @@
<Compile Include="Constants.cs" />
<Compile Include="Events\ExpireCache.cs" />
<Compile Include="Extensions\ArchetypeHelper.cs" />
<Compile Include="Extensions\Extensions.cs" />
<Compile Include="Extensions\HtmlHelperExtensions.cs" />
<Compile Include="Extensions\ArchetypePropertyModelExtensions.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Models\ArchetypeModel.cs" />
<Compile Include="Models\ArchetypePreValue.cs" />
<Compile Include="Models\ArchetypePreValueFieldset.cs" />
@@ -242,10 +244,6 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\VersionInfo.cs" />
<Compile Include="PropertyConverters\ArchetypeValueConverter.cs" />
<Compile Include="Serialization\AsArchetypeAttribute.cs" />
<Compile Include="Serialization\ArchetypeJsonConverter.cs" />
<Compile Include="Serialization\AsFieldsetAttribute.cs" />
<Compile Include="Serialization\SerializationExtensions.cs" />
<Compile Include="PropertyEditors\ArchetypePropertyEditor.cs" />
</ItemGroup>
<ItemGroup>
@@ -26,11 +26,11 @@ namespace Archetype.Extensions
_app = ApplicationContext.Current;
}
internal Models.ArchetypeModel DeserializeJsonToArchetype(string sourceJson, PreValueCollection dataTypePreValues)
internal ArchetypeModel DeserializeJsonToArchetype(string sourceJson, PreValueCollection dataTypePreValues)
{
try
{
var archetype = JsonConvert.DeserializeObject<Models.ArchetypeModel>(sourceJson, _jsonSettings);
var archetype = JsonConvert.DeserializeObject<ArchetypeModel>(sourceJson, _jsonSettings);
try
{
@@ -46,15 +46,15 @@ namespace Archetype.Extensions
}
catch
{
return new Models.ArchetypeModel();
return new ArchetypeModel();
}
}
internal Models.ArchetypeModel DeserializeJsonToArchetype(string sourceJson, int dataTypeId, PublishedContentType hostContentType = null)
internal ArchetypeModel DeserializeJsonToArchetype(string sourceJson, int dataTypeId, PublishedContentType hostContentType = null)
{
try
{
var archetype = JsonConvert.DeserializeObject<Models.ArchetypeModel>(sourceJson, _jsonSettings);
var archetype = JsonConvert.DeserializeObject<ArchetypeModel>(sourceJson, _jsonSettings);
try
{
@@ -70,10 +70,19 @@ namespace Archetype.Extensions
}
catch
{
return new Models.ArchetypeModel();
return new ArchetypeModel();
}
}
internal bool IsPropertyValueConverterOverridden(int dataTypeId)
{
var prevalues = GetArchetypePreValueFromDataTypeId(dataTypeId);
if (prevalues == null)
return false;
return prevalues.OverrideDefaultPropertyValueConverter;
}
private ArchetypePreValue GetArchetypePreValueFromDataTypeId(int dataTypeId)
{
return _app.ApplicationCache.RuntimeCache.GetCacheItem(
@@ -101,7 +110,7 @@ namespace Archetype.Extensions
return preValue;
}
private IDataTypeDefinition GetDataTypeByGuid(Guid guid)
internal IDataTypeDefinition GetDataTypeByGuid(Guid guid)
{
return (IDataTypeDefinition)ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem(
Constants.CacheKey_DataTypeByGuid + guid,
@@ -113,7 +122,7 @@ namespace Archetype.Extensions
/// </summary>
/// <param name="archetype">The Archetype to add the additional metadata to</param>
/// <param name="preValue">The configuration of the Archetype</param>
private void RetrieveAdditionalProperties(ref Models.ArchetypeModel archetype, ArchetypePreValue preValue, PublishedContentType hostContentType = null)
private void RetrieveAdditionalProperties(ref ArchetypeModel archetype, ArchetypePreValue preValue, PublishedContentType hostContentType = null)
{
foreach (var fieldset in preValue.Fieldsets)
{
@@ -140,7 +149,7 @@ namespace Archetype.Extensions
/// </summary>
/// <param name="archetype">The Archetype to add the additional metadata to</param>
/// <param name="preValue">The configuration of the Archetype</param>
private void RetrieveAdditionalProperties(ref Models.ArchetypePreValue preValue)
private void RetrieveAdditionalProperties(ref ArchetypePreValue preValue)
{
foreach (var fieldset in preValue.Fieldsets)
{
@@ -0,0 +1,20 @@
using Archetype.Models;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
namespace Archetype.Extensions
{
public static class ArchetypePropertyModelExtensions
{
public static bool IsArchetype(this ArchetypePropertyModel prop)
{
return prop.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditorAlias);
}
internal static PublishedPropertyType CreateDummyPropertyType(this ArchetypePropertyModel prop)
{
return new PublishedPropertyType(prop.HostContentType, new PropertyType(new DataTypeDefinition(-1, prop.PropertyEditorAlias) { Id = prop.DataTypeId }));
}
}
}
@@ -1,32 +1,14 @@
using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Web;
using Archetype.Models;
using Umbraco.Core.Logging;
namespace Archetype.Extensions
{
public static class Extensions
public static class HtmlHelperExtensions
{
//lifted from the core as it is marked 'internal'
public static bool DetectIsJson(this string input)
{
input = input.Trim();
return input.StartsWith("{") && input.EndsWith("}")
|| input.StartsWith("[") && input.EndsWith("]");
}
public static bool IsArchetype(this ArchetypePropertyModel prop)
{
return prop.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditorAlias);
}
public static IHtmlString RenderArchetypePartials(this HtmlHelper htmlHelper, ArchetypeModel archetypeModel)
{
return RenderPartials(htmlHelper, archetypeModel, null, null);
@@ -44,10 +26,10 @@ namespace Archetype.Extensions
public static IHtmlString RenderArchetypePartials(this HtmlHelper htmlHelper, ArchetypeModel archetypeModel, string partialPath, ViewDataDictionary viewDataDictionary)
{
return RenderPartials(htmlHelper, archetypeModel, partialPath, viewDataDictionary);
return htmlHelper.RenderPartials(archetypeModel, partialPath, viewDataDictionary);
}
private static IHtmlString RenderPartials(HtmlHelper htmlHelper, ArchetypeModel archetypeModel, string partialPath, ViewDataDictionary viewDataDictionary)
private static IHtmlString RenderPartials(this HtmlHelper htmlHelper, ArchetypeModel archetypeModel, string partialPath, ViewDataDictionary viewDataDictionary)
{
var context = HttpContext.Current;
@@ -57,7 +39,7 @@ namespace Archetype.Extensions
}
var sb = new StringBuilder();
var pathToPartials = "~/Views/Partials/Archetype/";
if (!string.IsNullOrEmpty(partialPath))
{
@@ -81,4 +63,4 @@ namespace Archetype.Extensions
return new HtmlString(sb.ToString());
}
}
}
}
@@ -0,0 +1,13 @@
namespace Archetype.Extensions
{
public static class StringExtensions
{
//lifted from the core as it is marked 'internal'
public static bool DetectIsJson(this string input)
{
input = input.Trim();
return input.StartsWith("{") && input.EndsWith("}")
|| input.StartsWith("[") && input.EndsWith("]");
}
}
}
@@ -10,6 +10,9 @@ namespace Archetype.Models
[JsonProperty("alias")]
public string Alias { get; set; }
[JsonProperty("disabled")]
public bool Disabled { get; set; }
[JsonProperty("properties")]
public IEnumerable<ArchetypePropertyModel> Properties;
@@ -29,12 +32,36 @@ namespace Archetype.Models
{
var property = GetProperty(propertyAlias);
if (property == null || property.Value == null || string.IsNullOrEmpty(property.Value.ToString()))
if (IsEmptyProperty(property))
{
return default(T);
}
return property.GetValue<T>();
}
// issue 142: support default T value supplied by caller
// this code would look nicer if the two GetValue<T>() methods had one common implementation.
// however, this would require GetValue<T>(string propertyAlias) to call the common implementation
// with a default(T) value, which could in theory result in a performance hit, if T for some reason
// is costly to instantiate.
public T GetValue<T>(string propertyAlias, T defaultValue)
{
var property = GetProperty(propertyAlias);
if (IsEmptyProperty(property))
{
return defaultValue;
}
return property.GetValue<T>();
}
private bool IsEmptyProperty(ArchetypePropertyModel property)
{
return (property == null || property.Value == null || string.IsNullOrEmpty(property.Value.ToString()));
}
public bool HasProperty(string propertyAlias)
{
return GetProperty(propertyAlias) != null;
@@ -1,7 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -11,7 +11,7 @@ namespace Archetype.Models
public class ArchetypeModel : IEnumerable<ArchetypeFieldsetModel>
{
[JsonProperty("fieldsets")]
internal IEnumerable<ArchetypeFieldsetModel> Fieldsets { get; set; }
public IEnumerable<ArchetypeFieldsetModel> Fieldsets { get; set; }
public ArchetypeModel()
{
@@ -20,7 +20,7 @@ namespace Archetype.Models
public IEnumerator<ArchetypeFieldsetModel> GetEnumerator()
{
return this.Fieldsets.GetEnumerator();
return this.Fieldsets.Where(f => f.Disabled == false).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
@@ -28,17 +28,17 @@ namespace Archetype.Models
return this.GetEnumerator();
}
internal string SerializeForPersistence()
public string SerializeForPersistence()
{
var json = JObject.Parse(JsonConvert.SerializeObject(this));
var json = JObject.Parse(JsonConvert.SerializeObject(this, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }));
var propertiesToRemove = new String[] { "propertyEditorAlias", "dataTypeId", "dataTypeGuid", "hostContentType" };
json.Descendants().OfType<JProperty>()
.Where(p => propertiesToRemove.Contains(p.Name))
.ToList()
.ForEach(x => x.Remove());
return json.ToString(Formatting.None);
.ForEach(x => x.Remove());
return json.ToString(Formatting.None);
}
}
}
@@ -20,6 +20,12 @@ namespace Archetype.Models
[JsonProperty("enableCollapsing")]
public bool EnableCollapsing { get; set; }
[JsonProperty("enableCloning")]
public bool EnableCloning { get; set; }
[JsonProperty("enableDisabling")]
public bool EnableDisabling { get; set; }
[JsonProperty("hideFieldsetControls")]
public bool HideFieldsetControls { get; set; }
@@ -47,7 +53,13 @@ namespace Archetype.Models
[JsonProperty("customViewPath")]
public string CustomViewPath { get; set; }
[JsonProperty("enableDeepDatatypeRequests")]
public bool EnableDeepDatatypeRequests { get; set; }
[JsonProperty("developerMode")]
public bool DeveloperMode { get; set; }
[JsonProperty("overrideDefaultPropertyValueConverter")]
public bool OverrideDefaultPropertyValueConverter { get; set; }
}
}
@@ -1,20 +1,21 @@
using System.Collections.Generic;
using System.Linq;
using Archetype.Extensions;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Web;
namespace Archetype.Models
{
public class ArchetypePropertyModel {
public class ArchetypePropertyModel
{
[JsonProperty("alias")]
public string Alias { get; internal set; }
public string Alias { get; set; }
[JsonProperty("value")]
public object Value { get; internal set; }
public object Value { get; set; }
[JsonProperty("propertyEditorAlias")]
public string PropertyEditorAlias { get; internal set; }
@@ -54,7 +55,7 @@ namespace Archetype.Models
private Attempt<T> TryConvertWithPropertyValueConverters<T>(object value, IEnumerable<IPropertyValueConverter> converters)
{
var properyType = CreateDummyPropertyType(DataTypeId, PropertyEditorAlias);
var properyType = this.CreateDummyPropertyType();
// In umbraco, there are default value converters that try to convert the
// value if all else fails. The problem is, they are also in the list of
@@ -72,6 +73,13 @@ namespace Archetype.Models
if (value2 is T)
return Attempt<T>.Succeed((T)value2);
// If ConvertDataToSource failed try ConvertSourceToObject.
var value3 = converter.ConvertSourceToObject(properyType, value2, false);
// If the value is of type T, just return it
if (value3 is T)
return Attempt<T>.Succeed((T)value3);
// Value is not final value type, so try a regular type conversion aswell
var convertAttempt = value2.TryConvertTo<T>();
if (convertAttempt.Success)
@@ -80,14 +88,5 @@ namespace Archetype.Models
return Attempt<T>.Fail();
}
private PublishedPropertyType CreateDummyPropertyType(int dataTypeId, string propertyEditorAlias)
{
return new PublishedPropertyType(this.HostContentType,
new PropertyType(new DataTypeDefinition(-1, propertyEditorAlias)
{
Id = dataTypeId
}));
}
}
}
@@ -7,7 +7,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Imulus")]
[assembly: AssemblyProduct("Archetype")]
[assembly: AssemblyCopyright("Copyright \xa9 Imulus 2014")]
[assembly: AssemblyCopyright("MIT Licensed")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -1,4 +1,4 @@
using System.Reflection;
[assembly: AssemblyVersion("1.2.1")]
[assembly: AssemblyFileVersion("1.2.1-beta")]
[assembly: AssemblyVersion("1.7.1")]
[assembly: AssemblyFileVersion("1.7.1")]
@@ -1,3 +1,4 @@
using System;
using Archetype.Extensions;
using Archetype.Models;
using Umbraco.Core;
@@ -11,7 +12,6 @@ namespace Archetype.PropertyConverters
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class ArchetypeValueConverter : PropertyValueConverterBase
{
public ServiceContext Services
{
get { return ApplicationContext.Current.Services; }
@@ -19,7 +19,12 @@ namespace Archetype.PropertyConverters
public override bool IsConverter(PublishedPropertyType propertyType)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditorAlias);
var isArcheTypePropertyEditor = !String.IsNullOrEmpty(propertyType.PropertyEditorAlias)
&& propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditorAlias);
if (!isArcheTypePropertyEditor)
return false;
return !ArchetypeHelper.Instance.IsPropertyValueConverterOverridden(propertyType.DataTypeId);
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
@@ -34,7 +39,7 @@ namespace Archetype.PropertyConverters
if (!sourceString.DetectIsJson())
return defaultValue;
using (var timer = DisposableTimer.DebugDuration<ArchetypeValueConverter>(string.Format("ConvertDataToSource ({0})", propertyType.PropertyTypeAlias)))
using (var timer = DisposableTimer.DebugDuration<ArchetypeValueConverter>(string.Format("ConvertDataToSource ({0})", propertyType != null ? propertyType.PropertyTypeAlias : "null")))
{
var archetype = ArchetypeHelper.Instance.DeserializeJsonToArchetype(sourceString,
(propertyType != null ? propertyType.DataTypeId : -1),
@@ -1,143 +1,159 @@
using System;
using System.Collections.Generic;
using Archetype.Extensions;
using ClientDependency.Core;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Editors;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Web.PropertyEditors;
namespace Archetype.PropertyEditors
{
[PropertyEditorAsset(ClientDependencyType.Javascript, "/App_Plugins/Archetype/js/archetype.js")]
[PropertyEditor("Imulus.Archetype", "Archetype", "/App_Plugins/Archetype/views/archetype.html", ValueType = "JSON")]
public class ArchetypePropertyEditor : PropertyEditor
{
#region Pre Value Editor
protected override PreValueEditor CreatePreValueEditor()
{
return new ArchetypePreValueEditor();
}
internal class ArchetypePreValueEditor : PreValueEditor
{
[PreValueField("archetypeConfig", "Config", "/App_Plugins/Archetype/views/archetype.config.html",
Description = "(Required) Describe your Archetype.")]
public string Config { get; set; }
[PreValueField("hideLabel", "Hide Label", "boolean",
Description = "Hide the Umbraco property title and description, making the Archetype span the entire page width")]
public bool HideLabel { get; set; }
}
#endregion
#region Value Editor
protected override PropertyValueEditor CreateValueEditor()
{
return new ArchetypePropertyValueEditor(base.CreateValueEditor());
}
internal class ArchetypePropertyValueEditor : PropertyValueEditorWrapper
{
protected JsonSerializerSettings _jsonSettings;
public ArchetypePropertyValueEditor(PropertyValueEditor wrapped)
: base(wrapped) { }
public override string ConvertDbToString(Property property, PropertyType propertyType, IDataTypeService dataTypeService)
{
if (property.Value == null || 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)
{
try
{
var dtd = dataTypeService.GetDataTypeDefinitionById(Guid.Parse(propDef.DataTypeGuid));
var propType = new PropertyType(dtd) { Alias = propDef.Alias };
var prop = new Property(propType, propDef.Value);
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
propDef.Value = propEditor.ValueEditor.ConvertDbToString(prop, propType, dataTypeService);
}
catch (Exception ex)
{
LogHelper.Error<ArchetypeHelper>(ex.Message, ex);
}
}
}
return archetype.SerializeForPersistence();
}
public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService)
{
if (property.Value == null || 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)
{
try
{
var dtd = dataTypeService.GetDataTypeDefinitionById(Guid.Parse(propDef.DataTypeGuid));
var propType = new PropertyType(dtd) { Alias = propDef.Alias };
var prop = new Property(propType, propDef.Value);
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
propDef.Value = propEditor.ValueEditor.ConvertDbToEditor(prop, propType, dataTypeService);
}
catch (Exception ex)
{
LogHelper.Error<ArchetypeHelper>(ex.Message, ex);
}
}
}
return archetype;
}
public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue)
{
if (editorValue.Value == null || editorValue.Value.ToString() == "")
return string.Empty;
var archetype = ArchetypeHelper.Instance.DeserializeJsonToArchetype(editorValue.Value.ToString(), editorValue.PreValues);
foreach (var fieldset in archetype.Fieldsets)
{
foreach (var propDef in fieldset.Properties)
{
try
{
var dtd = ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById(Guid.Parse(propDef.DataTypeGuid));
var preValues = ApplicationContext.Current.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dtd.Id);
var propData = new ContentPropertyData(propDef.Value, preValues, new Dictionary<string, object>());
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
propDef.Value = propEditor.ValueEditor.ConvertEditorToDb(propData, propDef.Value);
}
catch (Exception ex)
{
LogHelper.Error<ArchetypeHelper>(ex.Message, ex);
}
}
}
return archetype.SerializeForPersistence();
}
}
#endregion
}
}
using System;
using System.Collections.Generic;
using Archetype.Extensions;
using ClientDependency.Core;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Editors;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Web.PropertyEditors;
namespace Archetype.PropertyEditors
{
[PropertyEditorAsset(ClientDependencyType.Javascript, "/App_Plugins/Archetype/js/archetype.js")]
[PropertyEditor(Constants.PropertyEditorAlias, "Archetype", "/App_Plugins/Archetype/views/archetype.html", ValueType = "JSON")]
public class ArchetypePropertyEditor : PropertyEditor
{
#region Pre Value Editor
protected override PreValueEditor CreatePreValueEditor()
{
return new ArchetypePreValueEditor();
}
internal class ArchetypePreValueEditor : PreValueEditor
{
[PreValueField("archetypeConfig", "Config", "/App_Plugins/Archetype/views/archetype.config.html",
Description = "(Required) Describe your Archetype.")]
public string Config { get; set; }
[PreValueField("hideLabel", "Hide Label", "boolean",
Description = "Hide the Umbraco property title and description, making the Archetype span the entire page width")]
public bool HideLabel { get; set; }
}
#endregion
#region Value Editor
protected override PropertyValueEditor CreateValueEditor()
{
return new ArchetypePropertyValueEditor(base.CreateValueEditor());
}
internal class ArchetypePropertyValueEditor : PropertyValueEditorWrapper
{
protected JsonSerializerSettings _jsonSettings;
public ArchetypePropertyValueEditor(PropertyValueEditor wrapped)
: base(wrapped) { }
public override string ConvertDbToString(Property property, PropertyType propertyType, IDataTypeService dataTypeService)
{
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)
{
try
{
var dtd = ArchetypeHelper.Instance.GetDataTypeByGuid(Guid.Parse(propDef.DataTypeGuid));
var propType = new PropertyType(dtd) { Alias = propDef.Alias };
var prop = new Property(propType, propDef.Value);
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
propDef.Value = propEditor.ValueEditor.ConvertDbToString(prop, propType, dataTypeService);
}
catch (Exception ex)
{
LogHelper.Error<ArchetypePropertyValueEditor>(ex.Message, ex);
}
}
}
return archetype.SerializeForPersistence();
}
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());
var archetype = ArchetypeHelper.Instance.DeserializeJsonToArchetype(property.Value.ToString(), propertyType.DataTypeDefinitionId);
foreach (var fieldset in archetype.Fieldsets)
{
foreach (var propDef in fieldset.Properties)
{
try
{
var dtd = ArchetypeHelper.Instance.GetDataTypeByGuid(Guid.Parse(propDef.DataTypeGuid));
var propType = new PropertyType(dtd) { Alias = propDef.Alias };
var prop = new Property(propType, propDef.Value);
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
propDef.Value = propEditor.ValueEditor.ConvertDbToEditor(prop, propType, dataTypeService);
}
catch (Exception ex)
{
LogHelper.Error<ArchetypePropertyValueEditor>(ex.Message, ex);
}
}
}
return archetype;
}
public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue)
{
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)
{
try
{
var dtd = ArchetypeHelper.Instance.GetDataTypeByGuid(Guid.Parse(propDef.DataTypeGuid));
var preValues = ApplicationContext.Current.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dtd.Id);
var propData = new ContentPropertyData(propDef.Value, preValues, new Dictionary<string, object>());
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
propDef.Value = propEditor.ValueEditor.ConvertEditorToDb(propData, propDef.Value);
}
catch (Exception ex)
{
LogHelper.Error<ArchetypePropertyValueEditor>(ex.Message, ex);
}
}
}
return archetype.SerializeForPersistence();
}
internal virtual PropertyEditor GetPropertyEditor(IDataTypeDefinition dtd)
{
if (dtd.Id != 0)
return PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
return dtd.PropertyEditorAlias.Equals(Constants.PropertyEditorAlias)
? new ArchetypePropertyEditor()
: (PropertyEditor)new TextboxPropertyEditor();
}
}
#endregion
}
}
@@ -1,354 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Archetype.Serialization
{
public class ArchetypeJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var models = GenerateModels(value);
if (models.Count < 1)
return;
if (models.Count == 1 && models[0] == null)
return;
var jObj = new JObject
{
{
"fieldsets",
new JArray( new JRaw(SerializeModels(models)))
}
};
writer.WriteRaw(ApplyFormatting(jObj.ToString(), writer.Formatting));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jToken = JToken.ReadFrom(reader);
if (jToken == null)
return null;
var obj = Activator.CreateInstance(objectType);
if (null != obj as IEnumerable<object>
&& jToken["fieldsets"] != null && jToken["fieldsets"].Any())
{
return DeserializeEnumerableObject(obj, jToken);
}
return null == jToken as JArray
? DeserializeObject(obj, jToken)
: PopulateProperties(obj, jToken);
}
public override bool CanConvert(Type objectType)
{
return IsValueArchetypeDatatype(objectType);
}
#region private methods
private string ApplyFormatting(string json, Formatting formatting)
{
return JToken.Parse(json).ToString(formatting);
}
private IList GenerateModels(object value)
{
var models = value as IList;
if (null != models)
return models;
var properties = GetSerialiazableProperties(value).ToList();
if (!PropertyLayoutHasFieldsets(properties))
return new List<object>() { value };
var dynamicModel = new ExpandoObject() as IDictionary<string, object>;
foreach (var pInfo in properties.Where(pInfo => !HasAsFieldsetAttribute(pInfo)))
{
dynamicModel.Add(GetJsonPropertyName(pInfo), pInfo.GetValue(value));
}
var fieldsetModels = properties.Where(HasAsFieldsetAttribute)
.Select(pInfo => pInfo.GetValue(value));
models = new List<object>
{
dynamicModel,
};
models = ((IEnumerable<object>)models).Concat(fieldsetModels).ToList();
return models;
}
private object DeserializeEnumerableObject(object obj, JToken jToken)
{
var model = obj as IEnumerable<object>;
var itemType = model.GetType().BaseType.GetGenericArguments().First();
foreach (var fs in jToken["fieldsets"].Where(fs => fs["alias"].ToString().Equals(GetFieldsetName(itemType))))
{
var item = JsonConvert.DeserializeObject(
fs["properties"].ToString(), itemType, GetArchetypeDatatypeConverter());
obj.GetType().GetMethod("Add").Invoke(obj, new[] { item });
}
return obj;
}
private object DeserializeObject(object obj, JToken jToken)
{
var properties = GetSerialiazableProperties(obj).ToList();
var asFieldset = properties.Where(HasAsFieldsetAttribute).ToList();
foreach (var propInfo in asFieldset)
{
var propAlias = GetJsonPropertyName(propInfo);
var fsJToken = GetFieldsetProperties(propInfo.PropertyType, jToken);
var propJToken =
fsJToken.Single(p => p.SelectToken("alias").ToString().Equals(propAlias));
if (propJToken == null)
continue;
var propValue = IsValueArchetypeDatatype(propInfo.PropertyType)
? JsonConvert.DeserializeObject(fsJToken.ToString(), propInfo.PropertyType,
GetArchetypeDatatypeConverter())
: GetDeserializedPropertyValue(fsJToken, propInfo.PropertyType); ;
propInfo.SetValue(obj, propValue);
}
return PopulateProperties(obj, GetFieldsetProperties(obj.GetType(), jToken));
}
private JToken GetFieldsetProperties(Type objType, JToken jToken)
{
var objAlias = GetFieldsetName(objType);
return
jToken["fieldsets"].Single(p => p.SelectToken("alias").ToString().Equals(objAlias)).SelectToken("properties");
}
private object PopulateProperties(object obj, JToken jToken)
{
var properties = GetSerialiazableProperties(obj);
foreach (var propertyInfo in properties)
{
var propAlias = GetJsonPropertyName(propertyInfo);
var propJToken = jToken.SingleOrDefault(p => p.SelectToken("alias").ToString().Equals(propAlias));
if (propJToken == null)
continue;
var propValue = GetPropertyValue(propertyInfo, propJToken);
propertyInfo.SetValue(obj, propValue);
}
return obj;
}
private object GetPropertyValue(PropertyInfo propertyInfo, JToken propJToken)
{
return IsValueArchetypeDatatype(propertyInfo.PropertyType)
? JsonConvert.DeserializeObject(propJToken["value"].ToString(), propertyInfo.PropertyType,
GetArchetypeDatatypeConverter())
: GetDeserializedPropertyValue(propJToken["value"], propertyInfo.PropertyType);
}
private bool PropertyLayoutHasFieldsets(IEnumerable<PropertyInfo> properties)
{
return properties.Any(HasAsFieldsetAttribute);
}
private static bool HasAsFieldsetAttribute(PropertyInfo pInfo)
{
return pInfo
.GetCustomAttributes(typeof(AsFieldsetAttribute), true).Length > 0;
}
private IEnumerable SerializeModels(IEnumerable models)
{
var fieldsetJson = (from object model in models where null != model select SerializeModel(model)).ToList();
return String.Join(",", fieldsetJson);
}
private string SerializeModel(object value)
{
if (value == null)
return null;
var jObj = IsExpandoObject(value)
? GetJObjectFromExpandoObject(value as IDictionary<string, object>)
: GetJObject(value);
var fieldsetJson = new StringBuilder();
var fieldsetWriter = new StringWriter(fieldsetJson);
using (var jsonWriter = new JsonTextWriter(fieldsetWriter))
{
jObj.WriteTo(jsonWriter);
}
return fieldsetJson.ToString();
}
private bool IsExpandoObject(object value)
{
return value.GetType().Name.Equals(typeof (ExpandoObject).Name);
}
private JObject GetJObjectFromExpandoObject(IEnumerable<KeyValuePair<string, object>> obj)
{
var property = obj.ElementAt(0);
var alias = property.Key;
var value = property.Value;
var jObj = new JObject
{
{
"alias",
new JValue(alias)
}
};
var fsProperties = new List<JObject>
{
new JObject {new JProperty("alias", alias), new JProperty("value", value)}
};
jObj.Add("properties", new JRaw(JsonConvert.SerializeObject(fsProperties)));
return jObj;
}
private JObject GetJObject(object obj)
{
var jObj = new JObject
{
{
"alias",
new JValue(GetFieldsetName(obj.GetType()))
}
};
var properties = GetSerialiazableProperties(obj);
var fsProperties = new List<JObject>();
foreach (var propertyInfo in properties)
{
var fsProperty = new JObject();
var jProperty = new JProperty("alias", GetJsonPropertyName(propertyInfo));
fsProperty.Add(jProperty);
var propValue = propertyInfo.GetValue(obj, null);
fsProperty.Add(
new JProperty("value",
IsValueArchetypeDatatype(propValue)
? new JRaw(JsonConvert.SerializeObject(propValue,
GetArchetypeDatatypeConverter()))
: new JValue(GetSerializedPropertyValue(propValue))));
fsProperties.Add(fsProperty);
}
jObj.Add("properties", new JRaw(JsonConvert.SerializeObject(fsProperties)));
return jObj;
}
private IEnumerable<PropertyInfo> GetSerialiazableProperties(object obj)
{
return obj.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(prop => !Attribute.IsDefined(prop, typeof(JsonIgnoreAttribute)));
}
private string GetJsonPropertyName(PropertyInfo property)
{
var attributes = property.GetCustomAttributes(true);
var jsonPropAttribute = (JsonPropertyAttribute)attributes.FirstOrDefault(attr => attr is JsonPropertyAttribute);
return jsonPropAttribute != null ? jsonPropAttribute.PropertyName : property.Name;
}
private string GetFieldsetName(Type type)
{
var attributes = type.GetCustomAttributes(true);
var archetypeDatatypeAttribute = (AsArchetypeAttribute)attributes.FirstOrDefault(attr => attr is AsArchetypeAttribute);
return archetypeDatatypeAttribute != null ? archetypeDatatypeAttribute.FieldsetName : type.Name;
}
private bool IsValueArchetypeDatatype(object value)
{
return value != null &&
IsValueArchetypeDatatype(value.GetType());
}
private bool IsValueArchetypeDatatype(Type type)
{
return type.GetCustomAttributes(typeof(AsArchetypeAttribute), true).Length > 0;
}
private JsonConverter GetArchetypeDatatypeConverter()
{
return (JsonConverter)Activator.CreateInstance(GetType());
}
private string GetSerializedPropertyValue(object propValue)
{
if (propValue == null)
return String.Empty;
if (propValue is bool)
return (bool)propValue ? GetSerializedPropertyValue(1) : GetSerializedPropertyValue(0);
return String.Format("{0}", propValue);
}
private object GetDeserializedPropertyValue(JToken jToken, Type type)
{
if (String.IsNullOrEmpty(jToken.ToString()))
return GetDefault(type);
var localType = Nullable.GetUnderlyingType(type) ?? type;
if (localType == typeof(bool))
return jToken.ToString() == "1";
return localType == typeof(DateTime)
? Convert.ToDateTime(jToken.ToString())
: jToken.ToObject(localType);
}
private object GetDefault(Type type)
{
return type.IsValueType ? Activator.CreateInstance(type) : null;
}
#endregion
}
}
@@ -1,14 +0,0 @@
using System;
namespace Archetype.Serialization
{
public class AsArchetypeAttribute : Attribute
{
public string FieldsetName { get; set; }
public AsArchetypeAttribute(string fieldsetname)
{
FieldsetName = fieldsetname;
}
}
}
@@ -1,8 +0,0 @@
using System;
namespace Archetype.Serialization
{
public class AsFieldsetAttribute : Attribute
{
}
}
@@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Umbraco.Core.Models;
using Umbraco.Web;
namespace Archetype.Serialization
{
public static class SerializationExtensions
{
//temporary
public static string GetPropertyDataValue(this IPublishedContent contentPage, string propertyAlias)
{
if (contentPage == null || !contentPage.HasProperty(propertyAlias))
return null;
return (string)contentPage.Properties.Single(p => p.PropertyTypeAlias == propertyAlias).DataValue;
}
public static T GetModelFromArchetype<T>(this IPublishedContent content,
string cmsFieldAlias, bool returnInstanceIfNull = false)
where T : class, new()
{
var archetypeJson = content.GetPropertyDataValue(cmsFieldAlias);
return JsonConvert.DeserializeObject<T>(archetypeJson) ??
(returnInstanceIfNull ? Activator.CreateInstance<T>() : default(T));
}
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
//define empty items
var newPropertyModel = '{"alias": "", "remove": false, "collapse": false, "label": "", "helpText": "", "dataTypeGuid": "0cc0eba1-9960-42c9-bf9b-60e150b429ae", "value": ""}';
var newFieldsetModel = '{"alias": "", "remove": false, "collapse": false, "labelTemplate": "", "icon": "", "label": "", "properties": [' + newPropertyModel + ']}';
var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "startWithAddButton": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "fieldsets": [' + newFieldsetModel + ']}');
var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "startWithAddButton": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "enableCloning": false, "enableDisabling": true, "enableDeepDatatypeRequests": false, "fieldsets": [' + newFieldsetModel + ']}');
//ini the model
$scope.model.value = $scope.model.value || defaultFieldsetConfigModel;
+120 -12
View File
@@ -1,4 +1,4 @@
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, assetsService, angularHelper, notificationsService, $timeout) {
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, assetsService, angularHelper, notificationsService, $timeout, entityResource) {
//$scope.model.value = "";
$scope.model.hideLabel = $scope.model.config.hideLabel == 1;
@@ -11,8 +11,17 @@
//ini the model
$scope.model.value = $scope.model.value || getDefaultModel($scope.model.config);
// store the umbraco property alias to help generate unique IDs. Hopefully there's a better way to get this in the future :)
$scope.umbracoHostPropertyAlias = $scope.$parent.$parent.model.alias;
init();
//hold references to helper resources
$scope.resources = {
entityResource: entityResource
}
//helper to get $eval the labelTemplate
$scope.getFieldsetTitle = function(fieldsetConfigModel, fieldsetIndex) {
if(!fieldsetConfigModel)
@@ -29,14 +38,55 @@
var parsedTemplate = template;
while ((results = rgx.exec(template)) !== null) {
var propertyAlias = results[1];
var propertyValue = $scope.getPropertyValueByAlias(fieldset, propertyAlias);
parsedTemplate = parsedTemplate.replace(results[0], propertyValue);
// 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 "";
}
//sort config
$scope.sortableOptions = {
axis: 'y',
@@ -52,10 +102,8 @@
//handles a fieldset add
$scope.addRow = function (fieldsetAlias, $index) {
if ($scope.canAdd())
{
if ($scope.model.config.fieldsets)
{
if ($scope.canAdd()) {
if ($scope.model.config.fieldsets) {
var newFieldset = getEmptyRenderFieldset($scope.getConfigFieldsetByAlias(fieldsetAlias));
if (typeof $index != 'undefined')
@@ -83,9 +131,30 @@
}
}
$scope.cloneRow = function ($index) {
if ($scope.canClone() && typeof $index != 'undefined') {
var newFieldset = angular.copy($scope.model.value.fieldsets[$index]);
if(newFieldset) {
$scope.model.value.fieldsets.splice($index + 1, 0, newFieldset);
$scope.setDirty();
newFieldset.collapse = $scope.model.config.enableCollapsing ? true : false;
$scope.focusFieldset(newFieldset);
}
}
}
$scope.enableDisable = function (fieldset) {
fieldset.disabled = !fieldset.disabled;
// explicitly set the form as dirty when manipulating the enabled/disabled state of a fieldset
$scope.setDirty();
}
//helpers for determining if a user can do something
$scope.canAdd = function ()
{
$scope.canAdd = function () {
if ($scope.model.config.maxFieldsets)
{
return countVisible() < $scope.model.config.maxFieldsets;
@@ -95,19 +164,37 @@
}
//helper that returns if an item can be removed
$scope.canRemove = function ()
{
$scope.canRemove = function () {
return countVisible() > 1
|| ($scope.model.config.maxFieldsets == 1 && $scope.model.config.fieldsets.length > 1)
|| $scope.model.config.startWithAddButton;
}
$scope.canClone = function () {
if (!$scope.model.config.enableCloning) {
return false;
}
if ($scope.model.config.maxFieldsets)
{
return countVisible() < $scope.model.config.maxFieldsets;
}
return true;
}
//helper that returns if an item can be sorted
$scope.canSort = function ()
{
return countVisible() > 1;
}
//helper that returns if an item can be disabled
$scope.canDisable = function () {
return $scope.model.config.enableDisabling;
}
//helpers for determining if the add button should be shown
$scope.showAddButton = function () {
return $scope.model.config.startWithAddButton
@@ -263,6 +350,27 @@
return (typeof property == 'undefined') ? true : property.isValid;
}
//helper to lookup validity when given a fieldset
$scope.getFieldsetValidity = function (fieldset) {
if (fieldset.isValid == false) {
return false;
}
// recursive validation of nested fieldsets
var nestedFieldsetsValid = true;
_.each(fieldset.properties, function (property) {
if (property != null && property.value != null && property.propertyEditorAlias == "Imulus.Archetype") {
_.each(property.value.fieldsets, function (inner) {
if ($scope.getFieldsetValidity(inner) == false) {
nestedFieldsetsValid = false;
}
});
}
});
return nestedFieldsetsValid;
}
// helper to force the current form into the dirty state
$scope.setDirty = function () {
if($scope.form) {
+4 -17
View File
@@ -1,22 +1,12 @@
angular.module("umbraco.directives").directive('archetypeCustomView', function ($compile, $http) {
var linker = function (scope, element, attrs) {
var config = scope.archetype.config.archetypeConfig;
var view = "/App_plugins/Archetype/views/archetype.default.html";
if(config.customViewPath) {
view = config.customViewPath;
if(scope.model.config.customViewPath) {
view = scope.model.config.customViewPath;
}
$http.get(view).then(function(data) {
scope.model = {};
scope.model.value = scope.archetype.value;
scope.model.config = scope.archetype.config;
scope.$watch('model.value', function (newValue, oldValue) {
scope.archetype.value = newValue;
});
$http.get(view, { cache: true }).then(function(data) {
element.html(data.data).show();
@@ -27,9 +17,6 @@ angular.module("umbraco.directives").directive('archetypeCustomView', function (
return {
restrict: "A",
replace: true,
link: linker,
scope: {
archetype: "="
}
link: linker
}
});
+78 -58
View File
@@ -1,4 +1,4 @@
angular.module("umbraco.directives").directive('archetypeProperty', function ($compile, $http, archetypePropertyEditorResource, umbPropEditorHelper, $timeout, $rootScope, $q) {
angular.module("umbraco.directives").directive('archetypeProperty', function ($compile, $http, archetypePropertyEditorResource, umbPropEditorHelper, $timeout, $rootScope, $q, editorState) {
function getFieldsetByAlias(fieldsets, alias)
{
@@ -55,17 +55,14 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
var config = null;
var alias = configFieldsetModel.properties[scope.propertyConfigIndex].alias;
var defaultValue = configFieldsetModel.properties[scope.propertyConfigIndex].value;
var umbracoPropertyAlias = scope.umbracoPropertyAlias;
// initialize container for invalid fieldset property identifiers (store on ngModelCtrl to separate Archetype validations, e.g. when there two Archetype properties on the same document)
if(ngModelCtrl.invalidProperties == null) {
ngModelCtrl.invalidProperties = [];
}
var propertyAlias = getUniquePropertyAlias(scope);
propertyAliasParts = [];
//try to convert the defaultValue to a JS object
defaultValue = jsonOrString(defaultValue, scope.archetypeConfig.developerMode, "defaultValue");
//grab info for the selected datatype, prepare for view
archetypePropertyEditorResource.getDataType(dataTypeGuid).then(function (data) {
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) {
@@ -85,80 +82,86 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
var mergedConfig = _.extend(defaultConfigObj, config);
loadView(pathToView, mergedConfig, defaultValue, alias, umbracoPropertyAlias, scope, element, ngModelCtrl, validateProperty);
loadView(pathToView, mergedConfig, defaultValue, alias, propertyAlias, scope, element, ngModelCtrl, propertyValueChanged);
});
});
scope.$on("formSubmitting", function (ev, args) {
// "hard" validate to highlight any erroneous entries
// validate all fieldset properties
_.each(scope.fieldset.properties, function (property) {
validateProperty(scope.fieldset, property, true);
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("formSubmitted", function (ev, args) {
// reset the nested fieldset validation state after submit
ngModelCtrl.invalidProperties = [];
});
// need to pass the property fieldset here to clear any invalid state of the fieldset when validating a single 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
function validateProperty(fieldset, property, markAsInvalid) {
var valid = true;
fieldset.isValid = 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
property.isValid = true;
setFieldsetValidity(fieldset);
}
// validate a property in a fieldset
function validateProperty(fieldset, property) {
var propertyConfig = 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)) {
valid = false;
property.isValid = false;
}
// issue 116: RegEx validate property value
// Only validate the property value if anything has been entered - RegEx is considered a supplement to "required".
if (valid == true && propertyConfig.regEx && property.value) {
if (property.isValid == true && propertyConfig.regEx && property.value) {
var regEx = new RegExp(propertyConfig.regEx);
if (regEx.test(property.value) == false) {
valid = false;
property.isValid = false;
}
}
// only mark the property as invalid when doing a "hard" validation
if (valid == false && markAsInvalid == true) {
property.isValid = false;
}
}
// handle nested fieldset validation by storing the identifier of all invalid fieldset properties
var fieldsetIdentifier = scope.umbracoPropertyAlias + "_" + scope.fieldsetIndex;
var propertyIdentifier = fieldsetIdentifier + "_" + property.alias;
var propertyIdentifierIndex = ngModelCtrl.invalidProperties.indexOf(propertyIdentifier);
if (valid == false) {
if (propertyIdentifierIndex == -1) {
ngModelCtrl.invalidProperties.push(propertyIdentifier);
}
}
else {
if (propertyIdentifierIndex != -1) {
ngModelCtrl.invalidProperties.splice(propertyIdentifierIndex, 1);
}
}
if (markAsInvalid) {
// mark the entire fieldset as invalid if there are any invalid properties in the fieldset, otherwise mark it as valid
fieldset.isValid =
_.find(ngModelCtrl.invalidProperties, function (item) {
return item.indexOf(fieldsetIdentifier) == 0
}) == null;
}
setFieldsetValidity(fieldset);
}
// set invalid state if one or more fieldsets contain invalid properties
ngModelCtrl.$setValidity('validation', ngModelCtrl.invalidProperties.length == 0);
function setFieldsetValidity(fieldset) {
// mark the entire fieldset as invalid if there are any invalid properties in the fieldset, otherwise mark it as valid
fieldset.isValid =
_.find(fieldset.properties, function (property) {
return property.isValid == false
}) == null;
}
}
function loadView(view, config, defaultValue, alias, umbracoPropertyAlias, scope, element, ngModelCtrl, validateProperty) {
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)
{
$http.get(view).success(function (data) {
$http.get(view, { cache: true }).success(function (data) {
if (data) {
if (scope.archetypeConfig.developerMode == '1')
{
@@ -183,16 +186,32 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
//set the config from the prevalues
scope.model.config = config;
/*
Property Specific Hacks
Preference is to not do these, but unless we figure out core issues, this is quickest fix.
*/
//MNTP *single* hack
if(scope.model.config.maxNumber && scope.model.config.multiPicker)
{
if(scope.model.config.maxNumber == "1")
{
scope.model.config.multiPicker = "0";
}
}
//console.log(scope.model.config);
//some items need an alias
scope.model.alias = "archetype-property-" + umbracoPropertyAlias + "-" + scope.fieldsetIndex + "-" + scope.propertyConfigIndex;
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;
// call validation method for the property when the value changes
// use "soft" validation to mimic the default umbraco validation style (show error highlights on submit, not while entering data)
validateProperty(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex], scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties[renderModelPropertyIndex], false);
// notify the linker that the property value changed
propertyValueChanged(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex], scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties[renderModelPropertyIndex]);
});
element.html(data).show();
@@ -216,6 +235,7 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
scope: {
property: '=',
propertyConfigIndex: '=',
propertyEditorAlias: '=',
archetypeConfig: '=',
fieldset: '=',
fieldsetIndex: '=',
@@ -224,4 +244,4 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
umbracoForm: '='
}
}
});
});
+1 -1
View File
@@ -12,7 +12,7 @@ angular.module("umbraco.directives").directive('archetypeLocalize', function (ar
return {
restrict: "E",
rep1ace: true,
replace: true,
link: linker,
scope: {
key: '@'
+41
View File
@@ -0,0 +1,41 @@
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 "";
}
}
})();
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Egenskaber",
"labelTemplate": "Label skabelon",
"select": "Vælg",
"icon": "Ikon"
"icon": "Ikon",
"enableDisabling": "Aktivér fieldset-deaktivering?",
"enableDisablingDescription": "Tillad brugere at aktivere/deaktivere individuelle fieldsets.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+43
View File
@@ -0,0 +1,43 @@
{
"label": "Label",
"alias": "Alias",
"hideFieldsetControls": "Skjul fieldsets?",
"hideFieldsetControlsDescription": "Skjuler kontrollerne tilføj/fjern/sortér.",
"toggleAdvanced": "Slå avancerede muligheder til/fra",
"toggleAdvancedDescription": "Vis avancerede muligheder.",
"hidePropertyLabels": "Skjul labels på egenskaber?",
"hidePropertyLabelsDescription": "Skjuler labels på egenskaber.",
"maxFieldsets": "Maks antal fieldsets",
"maxFieldsetsDescription": "Hvor mange fieldsets er tilladt? Hvis der skrives '1' vil deaktivere kontrollerne. Som standard er det ubegrænset.",
"enableMultipleFieldsets": "Aktivér flere Fieldsets?",
"enableMultipleFieldsetsDescription": "Tillader flere typer af fieldsets i denne archetype.",
"hideFieldsetToolbar": "Skjul Fieldset værktøjslinie?",
"hideFieldsetToolbarDescription": "Skjuler den fieldset værktøjslinie der fremkommer når der findes mere end ét fieldset.",
"customWrapperClass": "Egen Wrapper Class",
"customWrapperClassDescription": "(Mulighed) Angiv din egen CSS class som tilføjes på wrapper div'en.",
"cssFile": "CSS fil",
"cssFileDescription": "(Mulighed) Tilføj en sti til din egen CSS fil der skal inkluderes på siden.",
"jsFile": "JavaScript fil",
"jsFileDescription": "(Mulighed) Tilføj en sti til din egen JavaScript fil der skal inkluderes på siden.",
"toggleDeveloperMode": "Slå udvikler muligheder til/fra.",
"toggleDeveloperModeDescription": "Aktivér på udvikler muligheder.",
"configModel": "Konfigurationsmodel",
"configModelDescription": "Vær forsigt med at redigere teksten for neden, den kontrollerer skemaet for denne archetype.",
"helpText": "Hjælpe tekst",
"defaultValue": "Standard værdi",
"dataType": "Datatype",
"required": "Påkrævet",
"regEx": "RegEx validering",
"properties": "Egenskaber",
"labelTemplate": "Label skabelon",
"select": "Vælg",
"icon": "Ikon",
"enableDisabling": "Aktivér fieldset-deaktivering?",
"enableDisablingDescription": "Tillad brugere at aktivere/deaktivere individuelle fieldsets.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+43
View File
@@ -0,0 +1,43 @@
{
"label": "Label",
"alias": "Alias",
"hideFieldsetControls": "Hide Fieldset Controls?",
"hideFieldsetControlsDescription": "Hides the fieldset add/remove/sort controls.",
"toggleAdvanced": "Toggle Advanced Options",
"toggleAdvancedDescription": "Show advanced options.",
"hidePropertyLabels": "Hide Property Labels?",
"hidePropertyLabelsDescription": "Hides the property labels.",
"maxFieldsets": "Max Fieldsets",
"maxFieldsetsDescription": "How many Fieldsets are allowed? Entering '1' will disable the controls. Default is unlimited.",
"enableMultipleFieldsets": "Enable Multiple Fieldsets?",
"enableMultipleFieldsetsDescription": "Allows multiple types of fieldsets within this archetype.",
"hideFieldsetToolbar": "Hide Fieldset Toolbar?",
"hideFieldsetToolbarDescription": "Hides the fieldset toolbar that appears when more than one fieldset model appears.",
"customWrapperClass": "Custom Wrapper Class",
"customWrapperClassDescription": "(Optional) Enter a custom CSS class that will be applied to the wrapper div.",
"cssFile": "CSS File",
"cssFileDescription": "(Optional) Enter a path for a custom CSS file to be included on the page.",
"jsFile": "JS File",
"jsFileDescription": "(Optional) Enter a path for a custom JS file to be included on the page.",
"toggleDeveloperMode": "Toggle Developer Mode",
"toggleDeveloperModeDescription": "Turn on for developer options.",
"configModel": "Config Model",
"configModelDescription": "Be careful editing the text below, it controls the schema for this archetype.",
"helpText": "Help Text",
"defaultValue": "Default Value",
"dataType": "DataType",
"required": "Required",
"regEx": "RegEx Validation",
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+43
View File
@@ -0,0 +1,43 @@
{
"label": "Label",
"alias": "Alias",
"hideFieldsetControls": "Hide Fieldset Controls?",
"hideFieldsetControlsDescription": "Hides the fieldset add/remove/sort controls.",
"toggleAdvanced": "Toggle Advanced Options",
"toggleAdvancedDescription": "Show advanced options.",
"hidePropertyLabels": "Hide Property Labels?",
"hidePropertyLabelsDescription": "Hides the property labels.",
"maxFieldsets": "Max Fieldsets",
"maxFieldsetsDescription": "How many Fieldsets are allowed? Entering '1' will disable the controls. Default is unlimited.",
"enableMultipleFieldsets": "Enable Multiple Fieldsets?",
"enableMultipleFieldsetsDescription": "Allows multiple types of fieldsets within this archetype.",
"hideFieldsetToolbar": "Hide Fieldset Toolbar?",
"hideFieldsetToolbarDescription": "Hides the fieldset toolbar that appears when more than one fieldset model appears.",
"customWrapperClass": "Custom Wrapper Class",
"customWrapperClassDescription": "(Optional) Enter a custom CSS class that will be applied to the wrapper div.",
"cssFile": "CSS File",
"cssFileDescription": "(Optional) Enter a path for a custom CSS file to be included on the page.",
"jsFile": "JS File",
"jsFileDescription": "(Optional) Enter a path for a custom JS file to be included on the page.",
"toggleDeveloperMode": "Toggle Developer Mode",
"toggleDeveloperModeDescription": "Turn on for developer options.",
"configModel": "Config Model",
"configModelDescription": "Be careful editing the text below, it controls the schema for this archetype.",
"helpText": "Help Text",
"defaultValue": "Default Value",
"dataType": "DataType",
"required": "Required",
"regEx": "RegEx Validation",
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+43
View File
@@ -0,0 +1,43 @@
{
"label": "Label",
"alias": "Alias",
"hideFieldsetControls": "Hide Fieldset Controls?",
"hideFieldsetControlsDescription": "Hides the fieldset add/remove/sort controls.",
"toggleAdvanced": "Toggle Advanced Options",
"toggleAdvancedDescription": "Show advanced options.",
"hidePropertyLabels": "Hide Property Labels?",
"hidePropertyLabelsDescription": "Hides the property labels.",
"maxFieldsets": "Max Fieldsets",
"maxFieldsetsDescription": "How many Fieldsets are allowed? Entering '1' will disable the controls. Default is unlimited.",
"enableMultipleFieldsets": "Enable Multiple Fieldsets?",
"enableMultipleFieldsetsDescription": "Allows multiple types of fieldsets within this archetype.",
"hideFieldsetToolbar": "Hide Fieldset Toolbar?",
"hideFieldsetToolbarDescription": "Hides the fieldset toolbar that appears when more than one fieldset model appears.",
"customWrapperClass": "Custom Wrapper Class",
"customWrapperClassDescription": "(Optional) Enter a custom CSS class that will be applied to the wrapper div.",
"cssFile": "CSS File",
"cssFileDescription": "(Optional) Enter a path for a custom CSS file to be included on the page.",
"jsFile": "JS File",
"jsFileDescription": "(Optional) Enter a path for a custom JS file to be included on the page.",
"toggleDeveloperMode": "Toggle Developer Mode",
"toggleDeveloperModeDescription": "Turn on for developer options.",
"configModel": "Config Model",
"configModelDescription": "Be careful editing the text below, it controls the schema for this archetype.",
"helpText": "Help Text",
"defaultValue": "Default Value",
"dataType": "DataType",
"required": "Required",
"regEx": "RegEx Validation",
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+9 -1
View File
@@ -31,5 +31,13 @@
"properties": "Properties",
"labelTemplate": "Label Template",
"select": "Select",
"icon": "Icon"
"icon": "Icon",
"enableDisabling": "Enable Fieldset Disabling?",
"enableDisablingDescription": "Allows fieldsets to be individually enabled/disabled.",
"deepDatatypeRequest":"Enable Deep Datatype Requests?",
"deepDatatypeRequestDescription":"Allows for easier datatype interception at the cost of caching performance.",
"overrideDefaultConverterDescription":"Check this if you wish to use your own custom property value converter.",
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning."
}
+268 -262
View File
@@ -1,106 +1,209 @@
.archetypeEditor {
width: 98%;
/* TODO: clean this up */
.archetypeEditor {
width: 98%;
.open {
position: relative;
}
.dropdown-menu {
top: auto;
> li > a {
border-radius: 6px;
}
}
}
.archetypeEditor fieldset{
border: 1px solid #dddddd;
padding: 0;
margin-bottom: 5px;
background-color: #f1f1f1;
clear: both;
display: inline-block;
width: 100%;
}
.controls-no-label {
padding: 10px;
}
.archetypeEditor .archetypeFieldsetLabel {
position: relative;
width: 100%%;
a+ul.dropdown-menu {
margin-left: 0;
}
.label-sub {
padding: 8px 0;
.icon {
color: #333;
}
fieldset {
border: 1px solid #dddddd;
padding: 0;
margin-bottom: 5px;
background-color: #f1f1f1;
clear: both;
display: inline-block;
&.module-label {
width: 100%;
.archetypeProperty {
clear: both;
overflow: visible;
margin-top: 3px;
label {
padding-left: 5px !important;
span {
color: #343434;
}
&.dimmed span {
color: #d9d9d9;
}
}
}
.archetypeFieldsetLabel {
position: relative;
width: 100%;
}
}
.dropdown-menu {
padding: 0;
border-radius: 0;
box-shadow: none;
margin-top: -10px;
margin-left: -200px;
}
.label-sub {
padding: 8px 0;
display: inline-block;
&.module-label {
width: 100%;
}
}
span {
font-weight: bold;
.dropdown-menu {
position: relative;
padding: 0;
border-radius: 0;
box-shadow: none;
margin-top: -10px;
}
&.menu-label { font-weight: normal; }
}
label:hover {
cursor: default;
}
&.enableCollapsing:hover {
cursor: pointer;
label {
span {
text-decoration: underline;
font-weight: bold;
&.menu-label { font-weight: normal; }
}
&:hover {
label:hover {
cursor: default;
}
&.enableCollapsing:hover {
cursor: pointer;
label {
span {
text-decoration: underline;
}
&:hover {
cursor: pointer;
}
}
}
.caret {
margin: 8px 1px 0 15px;
&.caret-right {
border-bottom: 4px solid transparent;
border-top: 4px solid transparent;
border-left: 4px solid #000000;
content: "";
margin-top: 6px;
}
}
label {
margin-bottom: 0;
margin-left: 5px;
padding: 0;
span {
display: inline-block;
}
&.dimmed {
color: #d9d9d9;
}
}
.archetypeEditorControls {
float: none;
position: absolute;
right: 15px;
top: 0;
}
}
.archetypePropertyError {
margin-bottom: 5px;
padding-top: 3px;
padding-bottom: 3px;
label {
span {
color: #b94a48;
font-weight: bold;
}
}
}
.archetypeCollapser {
clear: both;
height: 100%;
padding-top: 12px;
background-color: #fff;
border-top: 1px solid silver;
border-radius: 0 0 0 5px;
form {
margin-left:20px;
.control-label {
padding-top: 0 !important;
}
}
.archetypeFieldsetHelpText {
clear:both;
margin-bottom: 3px;
font-size: 12px;
}
}
}
.caret {
margin: 8px 1px 0 15px;
.archetypeDeveloperModel
{
font-family: monospace;
width: 98%;
min-height: 100px;
margin-bottom: 10px;
border: 1px solid red;
}
&.caret-right {
border-bottom: 4px solid transparent;
border-top: 4px solid transparent;
border-left: 4px solid #000000;
content: "";
margin-top: 6px;
.archetypeFieldsetError {
border: 1px solid #b94a48;
}
.archetypeAddButton:hover {
text-decoration: none;
.archetypeAddButtonText {
text-decoration: underline;
}
}
label{
margin-bottom: 0;
margin-left: 5px;
padding: 0;
.multiPropertyTextbox {
margin-bottom: 3px;
}
ul {
list-style: none;
margin-left: 0;
}
.show-validation.ng-invalid .control-group.error .control-label {
span {
display: inline-block;
color: #343434;
}
}
}
.archetypeEditor .archetypeCollapser{
clear: both;
height: 100%;
padding-top: 12px;
background-color: #fff;
border-top: 1px solid silver;
border-radius: 0 0 0 5px;
}
.archetypeEditor .multiPropertyTextbox{
margin-bottom: 3px;
}
.archetypeEditor ul{
list-style: none;
margin-left: 0;
}
.archetypeEditor,
.archetypeConfig {
.archetypeEditor, .archetypeConfig {
.archetypeEditorControls {
float: right;
@@ -109,213 +212,130 @@
&.handle {
cursor: move;
}
&.dimmed {
color: #d9d9d9;
}
}
}
}
.archetypeEditor .archetypeEditorControls {
float: none;
position: absolute;
right: 15px;
top: 0;
}
.archetypeConfig .archetypeEditorControls {
float: right;
}
.archetypeEditor form {
margin-left:20px;
.control-label {
padding-top: 0 !important;
}
}
.archetypeEditor .archetypeProperty{
clear: both;
overflow: hidden;
margin-top: 3px;
}
.archetypeEditor .archetypeDeveloperModel
{
font-family: monospace;
width: 98%;
min-height: 100px;
margin-bottom: 10px;
border: 1px solid red;
}
.archetypeEditor .archetypeFieldsetToolbar {
margin-bottom: 10px;
overflow: hidden;
li {
float: left;
padding: 2px 4px;
margin-right: 10px;
border: 1px solid #ddd;
cursor: pointer;
}
}
.archetypeEditor .archetypeFieldsetHeaderText{
clear:both;
margin-bottom: 3px;
font-size: 12px;
}
.archetypeEditor .archetypeFieldsetFooterText{
clear:both;
margin-bottom: 3px;
font-size: 12px;
}
.archetypeEditor .archetypeFieldsetHelpText{
clear:both;
margin-bottom: 3px;
font-size: 12px;
}
.archetypeConfig {
margin-bottom: 20px;
}
.archetypeConfig ul{
list-style: none;
}
.archetypeConfig li{
background-color: #fff;
}
.archetypeConfig label{
width: 120px;
}
.archetypeConfig .archetypeFieldsetWrapper{
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
}
.archetypeConfig .archetypeFieldsetOption{
margin-bottom: 15px;
input[type=text]{
max-width: 300px;
}
}
.archetypeConfig .archetypeDeveloperModel {
font-family: monospace;
width: 88%;
margin: 5px 10px 10px;
height: 130px;
}
.archetypeConfig .archetypePropertiesWrapper {
border: 1px solid #ddd;
padding: 8px;
margin: -40px 10px 10px 140px;
max-width: 475px;
ul {
padding: 0;
margin: 0;
list-style: none;
}
li {
background-color: #fff;
}
label {
width: 120px;
}
.archetypeEditorControls {
float: right;
}
.archetypeFieldsets {
margin-left: 0;
}
.archetypeFieldsetWrapper {
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
background-color: #eee;
}
input[type=text] {
max-width: 190px;
width: auto;
}
.archetypeFieldsetTitle {
cursor: pointer;
overflow: hidden;
}
select {
max-width: 160px;
.archetypeFieldsetOption {
margin-bottom: 15px;
input[type=text]{
max-width: 300px;
}
}
li:last-child {
margin-bottom: 0;
.archetypeDeveloperModel {
font-family: monospace;
width: 88%;
margin: 5px 10px 10px;
height: 130px;
}
}
.archetypeConfig .archetypeFieldsets {
margin-left: 0;
}
.archetypeConfig .archetypeFieldsetTitle {
cursor: pointer;
overflow: hidden;
}
.archetypeConfig .archetypeOptions label{
width: 400px;
}
.archetypeConfig .archetypeAdvancedOptions {
margin-top: 15px;
div {
margin-bottom: 10px;
}
label {
.archetypeOptions label{
width: 400px;
}
}
.archetypeConfig .archetypeMaxFieldsets{
border: 1px solid #ddd;
width: 40px;
text-align: right;
}
.archetypePropertiesWrapper {
border: 1px solid #ddd;
padding: 8px;
margin: -40px 10px 10px 140px;
max-width: 475px;
.archetypeConfig .archetypePropertyTitle {
cursor: pointer;
overflow: hidden;
}
ul {
padding: 0;
margin: 0;
}
.archetypeConfig .archetypePropertyCollapser{
margin-top: 10px;
div {
margin-bottom: 10px;
}
}
li {
padding: 10px;
margin-bottom: 10px;
background-color: #eee;
.archetypeEditor .archetypeFieldsetError{
border: 1px solid #b94a48;
}
input[type=text] {
max-width: 190px;
width: auto;
}
.archetypeEditor .archetypeProperty {
label {
span {
color: #343434;
select {
max-width: 160px;
}
}
li:last-child {
margin-bottom: 0;
}
}
}
.archetypeEditor .archetypePropertyError{
margin-bottom: 5px;
padding-top: 3px;
padding-bottom: 3px;
label {
span {
color: #b94a48;
font-weight: bold;
.archetypeAdvancedOptions {
margin-top: 15px;
div {
margin-bottom: 10px;
}
label {
width: 400px;
}
}
}
.archetypeEditor .archetypeAddButton:hover {
text-decoration: none;
.archetypeMaxFieldsets{
border: 1px solid #ddd;
width: 40px;
text-align: right;
}
.archetypeAddButtonText {
text-decoration: underline;
.archetypePropertyTitle {
cursor: pointer;
overflow: hidden;
}
.archetypePropertyCollapser {
margin-top: 10px;
div {
margin-bottom: 10px;
}
}
.archetypeFieldsetCollapser {
margin-top: 15px;
}
.fieldsetIcon {
margin-right: 10px;
}
}
@@ -323,17 +343,3 @@
visibility: visible !important;
background-color: #d0e7f1 !important;
}
.archetypeConfig .archetypeFieldsetCollapser {
margin-top: 15px;
}
.archetypeConfig .fieldsetIcon {
margin-right: 10px;
}
.archetypeEditor .show-validation.ng-invalid .control-group.error .control-label {
span {
color: #343434;
}
}
+13 -6
View File
@@ -6,14 +6,21 @@ angular.module('umbraco.resources').factory('archetypePropertyEditorResource', f
$http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetAll"), 'Failed to retrieve datatypes from tree service'
);
},
getDataType: function(guid) {
return umbRequestHelper.resourcePromise(
$http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetByGuid?guid=" + guid), 'Failed to retrieve datatype'
);
getDataType: function (guid, useDeepDatatypeLookup, contentTypeAlias, propertyTypeAlias, archetypeAlias, nodeId) {
if(useDeepDatatypeLookup) {
return umbRequestHelper.resourcePromise(
$http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetByGuid?guid=" + guid + "&contentTypeAlias=" + contentTypeAlias + "&propertyTypeAlias=" + propertyTypeAlias + "&archetypeAlias=" + archetypeAlias + "&nodeId=" + nodeId), 'Failed to retrieve datatype'
);
}
else {
return umbRequestHelper.resourcePromise(
$http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetByGuid?guid=" + guid , { cache: true }), 'Failed to retrieve datatype'
);
}
},
getPropertyEditorMapping: function(alias) {
return umbRequestHelper.resourcePromise(
$http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetAllPropertyEditors"), 'Failed to retrieve datatype mappings'
$http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetAllPropertyEditors", { cache: true }), 'Failed to retrieve datatype mappings'
).then(function (data) {
var result = _.find(data, function(d) {
return d.alias === alias;
@@ -26,4 +33,4 @@ angular.module('umbraco.resources').factory('archetypePropertyEditorResource', f
});
}
}
});
});
+1 -1
View File
@@ -24,7 +24,7 @@ angular.module('umbraco.services').factory('archetypeLocalizationService', funct
initLocalizedResources:function () {
var deferred = $q.defer();
userService.getCurrentUser().then(function(user){
$http.get("/App_plugins/Archetype/langs/" + user.locale + ".js")
$http.get("/App_plugins/Archetype/langs/" + user.locale + ".js", { cache: true })
.then(function(response){
service.resourceFileLoaded = true;
service.dictionary = response.data;
+18 -2
View File
@@ -106,8 +106,16 @@
<input type="checkbox" id="archetypeAdvancedOptionsMultipleFieldsets" ng-model="archetypeConfigRenderModel.enableMultipleFieldsets"/>
</div>
<div>
<label for="archetypeAdvancedOptionsCollapsing"><archetype-localize key="enableCollapsing">Enable Collapsing?</archetype-localize><small><archetype-localize key="enableCollapsingDescription">Allows multiple types of fieldsets within this archetype.</archetype-localize></small></label>
<label for="archetypeAdvancedOptionsCollapsing"><archetype-localize key="enableCollapsing">Enable Collapsing?</archetype-localize><small><archetype-localize key="enableCollapsingDescription">Enable fieldset collapsing.</archetype-localize></small></label>
<input type="checkbox" id="archetypeAdvancedOptionsCollapsing" ng-model="archetypeConfigRenderModel.enableCollapsing"/>
</div>
<div>
<label for="archetypeAdvancedOptionsCloning"><archetype-localize key="enableCloning">Enable Cloning?</archetype-localize><small><archetype-localize key="enableCloningDescription">Enable fieldset cloning.</archetype-localize></small></label>
<input type="checkbox" id="archetypeAdvancedOptionsCloning" ng-model="archetypeConfigRenderModel.enableCloning"/>
</div>
<div>
<label for="archetypeAdvancedOptionsDisabling"><archetype-localize key="enableDisabling">Enable Fieldset Disabling?</archetype-localize><small><archetype-localize key="enableDisablingDescription">Allows fieldsets to be individually enabled/disabled.</archetype-localize></small></label>
<input type="checkbox" id="archetypeAdvancedOptionsDisabling" ng-model="archetypeConfigRenderModel.enableDisabling" />
</div>
<div>
<label for="archetypeAdvancedOptionsFieldsetToolbar"><archetype-localize key="hideFieldsetToolbar">Hide Fieldset Toolbar?</archetype-localize><small><archetype-localize key="hideFieldsetToolbarDescription">Hides the fieldset toolbar that appears when more than one fieldset model appears.</archetype-localize></small></label>
@@ -130,9 +138,17 @@
<input type="text" id="archetypeAdvancedOptionsCustomView" ng-model="archetypeConfigRenderModel.customViewPath"/>
</div>
<div>
<label for="archetypeAdvancedOptionsDeveloperMode"><archetype-localize key="toggleDeveloperMode">Toggle Developer Mode</archetype-localize><small><archetype-localize key="toggleDeveloperModeDescription">Toggle Developer Mode</archetype-localize></small></label>
<label for="archetypeAdvancedOptionsDeepDatatypeRequest"><archetype-localize key="deepDatatypeRequest">Enable Deep Datatype Requests?</archetype-localize><small><archetype-localize key="deepDatatypeRequestDescription">Allows for easier datatype interception at the cost of caching performance.</archetype-localize></small></label>
<input type="checkbox" id="archetypeAdvancedOptionsDeepDatatypeRequest" ng-model="archetypeConfigRenderModel.enableDeepDatatypeRequests"/>
</div>
<div>
<label for="archetypeAdvancedOptionsDeveloperMode"><archetype-localize key="toggleDeveloperMode">Enable Developer Mode?</archetype-localize><small><archetype-localize key="toggleDeveloperModeDescription">Toggle Developer Mode</archetype-localize></small></label>
<input type="checkbox" id="archetypeAdvancedOptionsDeveloperMode" ng-model="archetypeConfigRenderModel.developerMode"/>
</div>
<div>
<label for="archetypeOverrideDefaultConverter"><archetype-localize key="overrideDefaultConverter">Override Default Property Value Converter?</archetype-localize><small><archetype-localize key="overrideDefaultConverterDescription">Check this if you wish to use your own custom property value converter.</archetype-localize></small></label>
<input type="checkbox" id="archetypeOverrideDefaultConverter" ng-model="archetypeConfigRenderModel.overrideDefaultPropertyValueConverter" />
</div>
<div>
<label for="archetypeAdvancedOptionsConfigModel"><archetype-localize key="configModel">Config Model</archetype-localize><small><archetype-localize key="configModelDescription">Be careful editing the text below, it controls the schema for this archetype.</archetype-localize></small></label>
<textarea class="archetypeDeveloperModel" id="archetypeAdvancedOptionsConfigModel" ng-model="archetypeConfigRenderModel"></textarea>
+10 -8
View File
@@ -1,13 +1,13 @@
<div class="archetypeEditor ng-class:model.config.customCssClass" ng-controller="Imulus.ArchetypeController">
<div class="archetypeEditor ng-class:model.config.customCssClass">
<textarea class="archetypeDeveloperModel" ng-show="model.config.developerMode" ng-model="model.value"></textarea>
<ul ui-sortable="sortableOptions" ng-model="model.value.fieldsets" ng-show="!showAddButton()">
<li ng-repeat="fieldset in model.value.fieldsets">
<fieldset ng-class="[fieldset.alias, (!fieldset.isValid ? 'archetypeFieldsetError' : '')]" ng-init="fieldsetConfigModel = getConfigFieldsetByAlias(fieldset.alias)">
<fieldset ng-class="['archetype-fieldset-' + fieldset.alias, (getFieldsetValidity(fieldset) == false ? 'archetypeFieldsetError' : '')]" ng-init="fieldsetConfigModel = getConfigFieldsetByAlias(fieldset.alias)">
<div class="archetypeFieldsetLabel" ng-class="{enableCollapsing: model.config.enableCollapsing}">
<div ng-click="focusFieldset(fieldset)" class="label-sub module-label">
<span class="caret" ng-hide="fieldset.collapse || !model.config.enableCollapsing"></span>
<span class="caret caret-right" ng-show="fieldset.collapse && model.config.enableCollapsing"></span>
<label>
<label ng-class="{dimmed: fieldset.disabled}">
<i class="fieldsetIcon icon ng-class:fieldsetConfigModel.icon"></i>
<span ng-bind="getFieldsetTitle(fieldsetConfigModel, $index)"></span>
</label>
@@ -22,22 +22,24 @@
</a>
</li>
</ul>
<i class="icon icon-documents" ng-click="cloneRow($index)" ng-show="canClone()"></i>
<i class="icon icon-remove" ng-click="removeRow($index)" ng-show="canRemove()"></i>
<i class="icon icon-power" ng-class="{dimmed: fieldset.disabled}" ng-click="enableDisable(fieldset)" ng-show="canDisable()"></i>
<i class="icon icon-navigation handle" ng-show="canSort()"></i>
</div>
</div>
<div class="archetypeCollapser animate-hide" ng-hide="isCollapsed(fieldset)">
<div class="archetypeCollapser animate-hide" ng-hide="model.config.enableCollapsing && isCollapsed(fieldset)">
<form class="form-inline">
<div ng-class="[property.alias, (getPropertyValidity($parent.$index, property.alias) === false ? 'archetypePropertyError' : '')]" class="archetypeProperty control-group" ng-repeat="property in fieldsetConfigModel.properties">
<label ng-hide="archetypeConfig.hidePropertyLabels == '1'" class="control-label" for="archetype-property-{{model.alias}}-{{$parent.$index}}-{{$index}}">
<div ng-class="[('archetype-property-' + property.alias), (getPropertyValidity($parent.$index, property.alias) === false ? 'archetypePropertyError' : '')]" class="archetypeProperty control-group" ng-repeat="property in fieldsetConfigModel.properties">
<label ng-hide="model.config.hidePropertyLabels == '1'" class="control-label" for="archetype-property-{{model.alias}}-{{$parent.$index}}-{{$index}}">
<span>{{property.label}}</span>
<div class="archetypeFieldsetHelpText" ng-show="property.helpText">
<small>{{property.helpText}}</small>
</div>
</label>
<div class="controls">
<archetype-property class="archetypeEditor" property="property" fieldset-index="$parent.$index" fieldset="fieldset" archetype-config="model.config" property-config-index="$index" archetype-render-model="model.value" umbraco-property-alias="model.alias" umbraco-form = "form"></archetype-property>
<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>
</div>
</div>
</form>
+1 -1
View File
@@ -1 +1 @@
<div archetype-custom-view archetype="model"></div>
<div archetype-custom-view ng-controller="Imulus.ArchetypeController"></div>
+2 -2
View File
@@ -1,8 +1,8 @@
{
"name": "Archetype",
"version": "1.2.1-beta",
"version": "1.7.1",
"url": "http://github.com/imulus/archetype/",
"author": "Imulus",
"author": "Imulus - Kevin Giszewski - Tom Fulton - Lee Kelleher - Matt Brailsford - Kenn Jacobsen - Et. Al.",
"authorUrl": "http://imulus.com/",
"license": "MIT",
"licenseUrl": "http://opensource.org/licenses/MIT"