Merge branch 'develop' into feature/packaging
Conflicts: .gitignore Gruntfile.js package.json
This commit is contained in:
+45
-1
@@ -12,4 +12,48 @@ $RECYCLE.BIN/
|
||||
|
||||
dist/
|
||||
node_modules/
|
||||
pkg/
|
||||
pkg/tmp/
|
||||
pkg/*.nupkg
|
||||
|
||||
[Dd]ebug/
|
||||
[Bb]uild/
|
||||
[Rr]elease/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Pp]ackages/
|
||||
|
||||
*.aps
|
||||
*.bak
|
||||
*.backup
|
||||
*.build.csdef
|
||||
*.cache
|
||||
*.ilk
|
||||
*.lib
|
||||
*.log
|
||||
*.meta
|
||||
*.ncb
|
||||
*.obj
|
||||
*.orig
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.scc
|
||||
*.sdf
|
||||
*.sln.docstates
|
||||
*.suo
|
||||
*.tlb
|
||||
*.tlh
|
||||
*.tli
|
||||
*.tmp
|
||||
*.user
|
||||
*.vspscc
|
||||
*.[Pp]ublish.xml
|
||||
*_i.c
|
||||
*_p.c
|
||||
.builds
|
||||
.svn
|
||||
.hg
|
||||
.hgignore
|
||||
+44
-3
@@ -2,6 +2,9 @@ module.exports = function(grunt) {
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
dest: 'dist',
|
||||
version: '0.0.0',
|
||||
package_dir: 'pkg',
|
||||
package_temp_dir: '<%= package_dir %>/tmp/',
|
||||
|
||||
watch: {
|
||||
less: {
|
||||
@@ -56,22 +59,56 @@ module.exports = function(grunt) {
|
||||
application: {
|
||||
src: [
|
||||
'app/controllers/controller.js',
|
||||
'app/directives/archetypeproperty.js'
|
||||
'app/controllers/config.controller.js',
|
||||
'app/directives/archetypeproperty.js',
|
||||
'app/services/propertyeditor.js'
|
||||
],
|
||||
dest: '<%= dest %>/js/archetype.js'
|
||||
}
|
||||
},
|
||||
|
||||
nugetpack: {
|
||||
dist: {
|
||||
src: '<%= package_temp_dir %>/nuget/package.nuspec',
|
||||
dest: '<%= package_dir %>'
|
||||
}
|
||||
},
|
||||
|
||||
template: {
|
||||
'nuget_manifest': {
|
||||
'options': {
|
||||
'data': {
|
||||
version: '<%= version %>',
|
||||
files: [{ path: '..\\..\\..\\<%= dest %>\\**', target: 'content\\App_Plugins\\Archetype'}]
|
||||
}
|
||||
},
|
||||
'files': {
|
||||
'<%= package_temp_dir %>/nuget/package.nuspec': ['<%= package_dir %>/nuget/package.nuspec']
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
clean: {
|
||||
build: ['<%= dest %>'],
|
||||
package_temp: ['<%= package_temp_dir %>']
|
||||
},
|
||||
|
||||
copy: {
|
||||
build: {
|
||||
files: [
|
||||
{expand: true, cwd: 'app/', src: ['package.manifest'], dest: '<%= dest %>', flatten: true},
|
||||
{expand: true, cwd: 'app/views/', src: ['archetype.html'], dest: '<%= dest %>/views', flatten: true}
|
||||
{expand: true, cwd: 'app/config/', src: ['config.views.js'], dest: '<%= dest %>/js', flatten: true},
|
||||
{expand: true, cwd: 'app/views/', src: ['archetype.html', 'archetype.config.html'], dest: '<%= dest %>/views', flatten: true}
|
||||
]
|
||||
},
|
||||
deploy: {
|
||||
files: [
|
||||
{expand: true, cwd: '<%= dest %>/', src: ['**'], dest: '<%= grunt.option("target") %>\\App_Plugins\\Imulus.Archetype', flatten: false},
|
||||
{expand: true, cwd: '<%= dest %>/', src: ['**'], dest: '<%= grunt.option("target") %>\\App_Plugins\\Archetype', flatten: false},
|
||||
]
|
||||
},
|
||||
nuget_prepare: {
|
||||
files: [
|
||||
{expand: true, cwd: '<%= dest %>/', src: ['**'], dest: '<%= package_temp_dir %>/nuget/content/', flatten: false},
|
||||
]
|
||||
},
|
||||
umbracopackage: {
|
||||
@@ -105,6 +142,7 @@ module.exports = function(grunt) {
|
||||
},
|
||||
|
||||
clean: ['<%= dest %>']
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -115,10 +153,13 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-nuget');
|
||||
grunt.loadNpmTasks('grunt-template');
|
||||
grunt.loadNpmTasks('grunt-touch');
|
||||
grunt.loadTasks('tasks');
|
||||
|
||||
|
||||
grunt.registerTask('package:nuget', ['default', 'clean:package_temp', 'copy:nuget_prepare', 'template:nuget_manifest', 'nugetpack', 'clean:package_temp']);
|
||||
grunt.registerTask('touchwebconfigifenabled', function() { if (grunt.option("touch")) grunt.task.run("touch:webconfig") });
|
||||
grunt.registerTask('deploy', ['default', 'copy:deploy', 'touchwebconfigifenabled']);
|
||||
grunt.registerTask('package:umbraco', ['copy:umbracopackage', 'umbracoPackage']);
|
||||
|
||||
@@ -41,164 +41,11 @@ Your /App_Plugins should contain this structure:
|
||||
## Prevalue Configs ##
|
||||
|
||||
Most of the fields are self evident, the following fields will be discussed further:
|
||||
|
||||
###Empty Fieldset Models###
|
||||
This option is required and defines the fieldsets and their properties.
|
||||
|
||||
If you get a YSOD regarding truncating of data, it's b/c Umbraco has a arbitrarily low limit on the number of characters (2500) allowed as prevalues in the DB.
|
||||
See: http://issues.umbraco.org/issue/U4-2120
|
||||
|
||||
An example follows below:
|
||||
|
||||
( //note that this needs to start with an open parentheses and notice the closing one at the end of this. This avoids issues with only seeing [object].
|
||||
[ //this array holds the array of fieldset objects
|
||||
{ //fieldset object
|
||||
alias: "FS1", //fieldset alias (unique)
|
||||
tooltip: "This is for fieldset 1", //used as a helper text
|
||||
icon: "/umbraco/Images/aboutNew.png", //a custom icon
|
||||
label: "Fieldset 1", //the fieldset label
|
||||
headerText: "Please fill out the boxes.", // text to be prepended to the fieldset properties?
|
||||
footerText: "Thanks!", //text to be appended to the fieldset properties?
|
||||
properties:[ //an array of property objects
|
||||
{
|
||||
alias: "firstName", //uniquely name the property (unique to the fieldset)
|
||||
label: "First Name", //a label to use
|
||||
helpText: "(Required)", //a note that will appear under the label
|
||||
view: "/umbraco/views/propertyeditors/textbox/textbox.html", //a path to a view
|
||||
value: "", //set to none or set to a default; can be json (if the view understands it)
|
||||
config: { //pass configs to the view; configs are based on the view used
|
||||
|
||||
}
|
||||
},
|
||||
{ //another property
|
||||
alias: "lastName",
|
||||
label: "Last Name",
|
||||
helpText: "(Required)",
|
||||
view: "/umbraco/views/propertyeditors/textbox/textbox.html",
|
||||
value: "",
|
||||
config: {
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
alias: "age",
|
||||
label: "Age",
|
||||
helpText: "(Optional)",
|
||||
view: "/umbraco/views/propertyeditors/textbox/textbox.html",
|
||||
value: "",
|
||||
config: {
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
alias: "blah",
|
||||
label: "Blah",
|
||||
helpText: "",
|
||||
view: "/umbraco/views/propertyeditors/contentpicker/contentpicker.html",
|
||||
value: "",
|
||||
config: {
|
||||
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ //another fieldset
|
||||
alias: "FS2",
|
||||
tooltip: "This is for fieldset 2",
|
||||
icon: "/umbraco/Images/about.png",
|
||||
label: "Fieldset 2",
|
||||
headerText: "Please fill out the boxes.",
|
||||
footerText: "Thanks!",
|
||||
properties:[
|
||||
{
|
||||
alias: "foo",
|
||||
label: "Foo",
|
||||
helpText: "(Required)",
|
||||
view: "/umbraco/views/propertyeditors/textbox/textbox.html",
|
||||
value: "",
|
||||
config: {
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
alias: "bar",
|
||||
label: "Bar",
|
||||
helpText: "",
|
||||
view: "/umbraco/views/propertyeditors/textbox/textbox.html",
|
||||
value: "",
|
||||
config: {
|
||||
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
)//close it
|
||||
|
||||
###Default Model###
|
||||
Here is the spot to define a starting value. This model uses only the essential data that must be saved. This example shows multiple fieldsets with multiple properties:
|
||||
|
||||
( //again use a parenthesis to avoid [object]
|
||||
{
|
||||
"fieldsets": [
|
||||
{
|
||||
"alias": "FS2",
|
||||
"properties": [
|
||||
{
|
||||
"alias": "bar",
|
||||
"value": "Field"
|
||||
},
|
||||
{
|
||||
"alias": "foo",
|
||||
"value": "Another"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"alias": "FS2",
|
||||
"properties": [
|
||||
{
|
||||
"alias": "foo",
|
||||
"value": "The Foo Field"
|
||||
},
|
||||
{
|
||||
"alias": "bar",
|
||||
"value": "The Bar Field"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"alias": "FS1",
|
||||
"properties": [
|
||||
{
|
||||
"alias": "age",
|
||||
"value": "Old"
|
||||
},
|
||||
{
|
||||
"alias": "lastName",
|
||||
"value": "Giszewski"
|
||||
},
|
||||
{
|
||||
"alias": "firstName",
|
||||
"value": "Kevin"
|
||||
},
|
||||
{
|
||||
"alias": "blah",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
###Developer Mode###
|
||||
|
||||
By turning this on, you will get a textarea visible with the data model (not prevalue model). You can change the contents of the textarea for real-time editing. Additionally when in developer mode, the console will reflect the scope object of each property.
|
||||
|
||||
###Sortable Options###
|
||||
Just in case you need to pass something into the jQueryUI sort options, you can override the default behavior by passing in a new JS snippet here.
|
||||
|
||||
##View Compatibility##
|
||||
The basis of compatibility is based on the following:
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<solution>
|
||||
<add key="disableSourceControlIntegration" value="true" />
|
||||
</solution>
|
||||
</configuration>
|
||||
Binary file not shown.
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
|
||||
|
||||
<!-- Enable the restore command to run before builds -->
|
||||
<RestorePackages Condition=" '$(RestorePackages)' == '' ">true</RestorePackages>
|
||||
|
||||
<!-- Property that enables building a package from a project -->
|
||||
<BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>
|
||||
|
||||
<!-- Determines if package restore consent is required to restore packages -->
|
||||
<RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">false</RequireRestoreConsent>
|
||||
|
||||
<!-- Download NuGet.exe if it does not already exist -->
|
||||
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(PackageSources)' == '' ">
|
||||
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
|
||||
<!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
|
||||
<!--
|
||||
<PackageSource Include="https://www.nuget.org/api/v2/" />
|
||||
<PackageSource Include="https://my-nuget-source/nuget/" />
|
||||
-->
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
|
||||
<!-- Windows specific commands -->
|
||||
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
|
||||
<PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
|
||||
<!-- We need to launch nuget.exe with the mono command if we're not on windows -->
|
||||
<NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
|
||||
<PackagesConfig>packages.config</PackagesConfig>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- NuGet command -->
|
||||
<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\NuGet.exe</NuGetExePath>
|
||||
<PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
|
||||
|
||||
<NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
|
||||
<NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(NuGetExePath)</NuGetCommand>
|
||||
|
||||
<PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
|
||||
|
||||
<RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
|
||||
<NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
|
||||
|
||||
<PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
|
||||
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>
|
||||
|
||||
<!-- Commands -->
|
||||
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
|
||||
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
|
||||
|
||||
<!-- We need to ensure packages are restored prior to assembly resolve -->
|
||||
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
|
||||
RestorePackages;
|
||||
$(BuildDependsOn);
|
||||
</BuildDependsOn>
|
||||
|
||||
<!-- Make the build depend on restore packages -->
|
||||
<BuildDependsOn Condition="$(BuildPackage) == 'true'">
|
||||
$(BuildDependsOn);
|
||||
BuildPackage;
|
||||
</BuildDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="CheckPrerequisites">
|
||||
<!-- Raise an error if we're unable to locate nuget.exe -->
|
||||
<Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
|
||||
<!--
|
||||
Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
|
||||
This effectively acts as a lock that makes sure that the download operation will only happen once and all
|
||||
parallel builds will have to wait for it to complete.
|
||||
-->
|
||||
<MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_DownloadNuGet">
|
||||
<DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
|
||||
</Target>
|
||||
|
||||
<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
|
||||
<Exec Command="$(RestoreCommand)"
|
||||
Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
|
||||
|
||||
<Exec Command="$(RestoreCommand)"
|
||||
LogStandardErrorAsError="true"
|
||||
Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
|
||||
</Target>
|
||||
|
||||
<Target Name="BuildPackage" DependsOnTargets="CheckPrerequisites">
|
||||
<Exec Command="$(BuildCommand)"
|
||||
Condition=" '$(OS)' != 'Windows_NT' " />
|
||||
|
||||
<Exec Command="$(BuildCommand)"
|
||||
LogStandardErrorAsError="true"
|
||||
Condition=" '$(OS)' == 'Windows_NT' " />
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
<OutputFilename ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Reference Include="System.Core" />
|
||||
<Using Namespace="System" />
|
||||
<Using Namespace="System.IO" />
|
||||
<Using Namespace="System.Net" />
|
||||
<Using Namespace="Microsoft.Build.Framework" />
|
||||
<Using Namespace="Microsoft.Build.Utilities" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
try {
|
||||
OutputFilename = Path.GetFullPath(OutputFilename);
|
||||
|
||||
Log.LogMessage("Downloading latest version of NuGet.exe...");
|
||||
WebClient webClient = new WebClient();
|
||||
webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Log.LogErrorFromException(ex);
|
||||
return false;
|
||||
}
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
</Project>
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Archetype.Umbraco", "Umbraco.Archetype\Archetype.Umbraco.csproj", "{7D185D41-4228-4978-ACB8-83F9A48AD94F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{D84AA4ED-85A6-484F-9E72-BE7AC9835821}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.nuget\NuGet.Config = .nuget\NuGet.Config
|
||||
.nuget\NuGet.exe = .nuget\NuGet.exe
|
||||
.nuget\NuGet.targets = .nuget\NuGet.targets
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7D185D41-4228-4978-ACB8-83F9A48AD94F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7D185D41-4228-4978-ACB8-83F9A48AD94F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7D185D41-4228-4978-ACB8-83F9A48AD94F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7D185D41-4228-4978-ACB8-83F9A48AD94F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,207 @@
|
||||
<?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>{7D185D41-4228-4978-ACB8-83F9A48AD94F}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Archetype.Umbraco</RootNamespace>
|
||||
<AssemblyName>Archetype</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="AutoMapper">
|
||||
<HintPath>..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="AutoMapper.Net4">
|
||||
<HintPath>..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.Net4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="businesslogic">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\businesslogic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ClientDependency.Core">
|
||||
<HintPath>..\packages\ClientDependency.1.7.0.4\lib\ClientDependency.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ClientDependency.Core.Mvc">
|
||||
<HintPath>..\packages\ClientDependency-Mvc.1.7.0.4\lib\ClientDependency.Core.Mvc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="cms">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\cms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="controls">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\controls.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="CookComputing.XmlRpcV2">
|
||||
<HintPath>..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Examine">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\Examine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HtmlAgilityPack">
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.4.6\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ICSharpCode.SharpZipLib">
|
||||
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="interfaces">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\interfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4net">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Lucene.Net">
|
||||
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.ApplicationBlocks.Data">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\Microsoft.ApplicationBlocks.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Web.Helpers">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\Microsoft.Web.Helpers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</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>
|
||||
</Reference>
|
||||
<Reference Include="MiniProfiler">
|
||||
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data">
|
||||
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SQLCE4Umbraco">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\SQLCE4Umbraco.dll</HintPath>
|
||||
</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>
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\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>
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\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>
|
||||
</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>
|
||||
<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>
|
||||
</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>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</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">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.AspNet.Razor.2.0.30506.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>
|
||||
<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>
|
||||
<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>
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="TidyNet">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\TidyNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="umbraco">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Umbraco.Core">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\Umbraco.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="umbraco.DataLayer">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.DataLayer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="umbraco.editorControls">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.editorControls.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="umbraco.MacroEngines">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.MacroEngines.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="umbraco.providers">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.providers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Umbraco.Web.UI">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\Umbraco.Web.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="umbraco.XmlSerializers">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.XmlSerializers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UmbracoExamine">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\UmbracoExamine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UrlRewritingNet.UrlRewriter">
|
||||
<HintPath>..\packages\UmbracoCms.Core.7.0.1\lib\UrlRewritingNet.UrlRewriter.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Extensions\Extensions.cs" />
|
||||
<Compile Include="Models\Archetype.cs" />
|
||||
<Compile Include="Models\Fieldset.cs" />
|
||||
<Compile Include="Models\Property.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PropertyConverters\ArchetypeValueConverter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<!-- 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,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Archetype.Umbraco.Extensions
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
//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("]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Archetype.Umbraco.Models
|
||||
{
|
||||
public class Archetype
|
||||
{
|
||||
public IEnumerable<Fieldset> Fieldsets { get; set; }
|
||||
|
||||
public Archetype()
|
||||
{
|
||||
Fieldsets = new List<Fieldset>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Archetype.Umbraco.Models
|
||||
{
|
||||
public class Fieldset
|
||||
{
|
||||
public string Alias { get; set; }
|
||||
public IEnumerable<Property> Properties;
|
||||
|
||||
public Fieldset()
|
||||
{
|
||||
Properties = new List<Property>();
|
||||
}
|
||||
|
||||
public string GetValue(string propertyAlias)
|
||||
{
|
||||
return GetValue<string>(propertyAlias);
|
||||
}
|
||||
|
||||
public T GetValue<T>(string propertyAlias)
|
||||
{
|
||||
var property = GetProperty(propertyAlias);
|
||||
|
||||
if (property == null || string.IsNullOrEmpty(property.Value))
|
||||
return default(T);
|
||||
|
||||
var convertAttempt = property.Value.TryConvertTo<T>();
|
||||
|
||||
if (convertAttempt.Success)
|
||||
return convertAttempt.Result;
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
private Property GetProperty(string propertyAlias)
|
||||
{
|
||||
return Properties.FirstOrDefault(p => p.Alias.InvariantEquals(propertyAlias));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Archetype.Umbraco.Models
|
||||
{
|
||||
public class Property
|
||||
{
|
||||
public string Alias { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Archetype")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Archetype")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("e37e94f9-c7ba-4b54-b7e1-64419b3dba0b")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Archetype.Umbraco.Models;
|
||||
using Archetype.Umbraco.Extensions;
|
||||
|
||||
namespace Archetype.Umbraco.PropertyConverters
|
||||
{
|
||||
/* based on the Tim Geyssens sample at: https://github.com/TimGeyssens/MatrixPropEditor/blob/master/SamplePropertyValueConverter/SamplePropertyValueConverter/MatrixValueConverter.cs */
|
||||
[PropertyValueType(typeof(Archetype.Umbraco.Models.Archetype))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class ArchetypeValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.Equals("Imulus.Archetype");
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
|
||||
var sourceString = source.ToString();
|
||||
|
||||
if (sourceString.DetectIsJson())
|
||||
{
|
||||
try
|
||||
{
|
||||
var archetype = JsonConvert.DeserializeObject <Archetype.Umbraco.Models.Archetype> (sourceString);
|
||||
return archetype;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return sourceString;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="AutoMapper" version="3.0.0" targetFramework="net45" />
|
||||
<package id="ClientDependency" version="1.7.0.4" targetFramework="net45" />
|
||||
<package id="ClientDependency-Mvc" version="1.7.0.4" targetFramework="net45" />
|
||||
<package id="HtmlAgilityPack" version="1.4.6" targetFramework="net45" />
|
||||
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
|
||||
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net45" />
|
||||
<package id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.1" targetFramework="net45" />
|
||||
<package id="Microsoft.AspNet.Razor" version="2.0.30506.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.30506.0" targetFramework="net45" />
|
||||
<package id="Microsoft.AspNet.WebApi.WebHost" version="4.0.30506.0" targetFramework="net45" />
|
||||
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net45" />
|
||||
<package id="Microsoft.Net.Http" 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="4.5.11" targetFramework="net45" />
|
||||
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
|
||||
<package id="UmbracoCms.Core" version="7.0.1" targetFramework="net45" />
|
||||
<package id="xmlrpcnet" version="2.5.0" targetFramework="net45" />
|
||||
</packages>
|
||||
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"name": "Textstring",
|
||||
"path": "/umbraco/views/propertyeditors/textbox/textbox.html"
|
||||
},
|
||||
{
|
||||
"name": "Content Picker",
|
||||
"path": "/umbraco/views/propertyeditors/contentpicker/contentpicker.html"
|
||||
},
|
||||
{
|
||||
"name": "Boolean",
|
||||
"path": "/umbraco/views/propertyeditors/boolean/boolean.html"
|
||||
},
|
||||
{
|
||||
"name": "Checkbox List",
|
||||
"path": "/umbraco/views/propertyeditors/checkboxlist/checkboxlist.html"
|
||||
},
|
||||
{
|
||||
"name": "Radio Buttons",
|
||||
"path": "/umbraco/views/propertyeditors/radiobuttons/radiobuttons.html"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,239 @@
|
||||
angular.module("umbraco").controller("Imulus.ArchetypeConfigController", function ($scope, $http, assetsService, propertyEditorService) {
|
||||
|
||||
//$scope.model.value = "";
|
||||
//console.log($scope.model.value);
|
||||
|
||||
var newPropertyModel = '{alias: "", remove: false, collapse: false, label: "", helpText: "", view: "", value: "", config: ""}';
|
||||
var newFieldsetModel = '{alias: "", remove: false, collapse: false, labelTemplate: "", tooltip: "", icon: "", label: "", headerText: "", footerText: "", properties:[' + newPropertyModel + ']}';
|
||||
var defaultFieldsetConfigModel = eval("({showAdvancedOptions: false, hideFieldsetToolbar: false, enableMultipleFieldsets: false, hideFieldsetControls: false, hideFieldsetLabels: false, hidePropertyLabel: false, maxFieldsets: null, fieldsets: [" + newFieldsetModel + "]})");
|
||||
|
||||
$scope.model.value = $scope.model.value || defaultFieldsetConfigModel;
|
||||
|
||||
initConfigRenderModel();
|
||||
|
||||
//get the available views
|
||||
propertyEditorService.getViews().then(function(data){
|
||||
$scope.availableViews = data;
|
||||
});
|
||||
|
||||
$scope.sortableOptions = {
|
||||
axis: 'y',
|
||||
cursor: "move",
|
||||
handle: ".handle",
|
||||
update: function (ev, ui) {
|
||||
|
||||
},
|
||||
stop: function (ev, ui) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
$scope.focusFieldset = function(fieldset){
|
||||
var iniState;
|
||||
|
||||
if(fieldset)
|
||||
{
|
||||
iniState = fieldset.collapse;
|
||||
}
|
||||
|
||||
_.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){
|
||||
if($scope.archetypeConfigRenderModel.fieldsets.length == 1 && fieldset.remove == false)
|
||||
{
|
||||
fieldset.collapse = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(fieldset.label)
|
||||
{
|
||||
fieldset.collapse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldset.collapse = false;
|
||||
}
|
||||
});
|
||||
|
||||
if(iniState)
|
||||
{
|
||||
fieldset.collapse = !iniState;
|
||||
}
|
||||
}
|
||||
//ini
|
||||
$scope.focusFieldset();
|
||||
|
||||
$scope.focusProperty = function(properties, property){
|
||||
var iniState;
|
||||
|
||||
if(property)
|
||||
{
|
||||
iniState = property.collapse;
|
||||
}
|
||||
|
||||
_.each(properties, function(property){
|
||||
if(property.label)
|
||||
{
|
||||
property.collapse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
property.collapse = false;
|
||||
}
|
||||
});
|
||||
|
||||
if(iniState)
|
||||
{
|
||||
property.collapse = !iniState;
|
||||
}
|
||||
}
|
||||
|
||||
//setup JSON.stringify helpers
|
||||
$scope.archetypeConfigRenderModel.toString = stringify;
|
||||
|
||||
//encapsulate stringify (should be built into browsers, not sure of IE support)
|
||||
function stringify() {
|
||||
return JSON.stringify(this);
|
||||
}
|
||||
|
||||
//watch for changes
|
||||
$scope.$watch('archetypeConfigRenderModel', function (v) {
|
||||
//console.log(v);
|
||||
if (typeof v === 'string') {
|
||||
$scope.archetypeConfigRenderModel = JSON.parse(v);
|
||||
$scope.archetypeConfigRenderModel.toString = stringify;
|
||||
}
|
||||
}, true);
|
||||
|
||||
//helper that returns if an item can be removed
|
||||
$scope.canRemoveFieldset = function ()
|
||||
{
|
||||
return countVisibleFieldset() > 1;
|
||||
}
|
||||
|
||||
//helper that returns if an item can be sorted
|
||||
$scope.canSortFieldset = function ()
|
||||
{
|
||||
return countVisibleFieldset() > 1;
|
||||
}
|
||||
|
||||
//helper that returns if an item can be removed
|
||||
$scope.canRemoveProperty = function (fieldset)
|
||||
{
|
||||
return countVisibleProperty(fieldset) > 1;
|
||||
}
|
||||
|
||||
//helper that returns if an item can be sorted
|
||||
$scope.canSortProperty = function (fieldset)
|
||||
{
|
||||
return countVisibleProperty(fieldset) > 1;
|
||||
}
|
||||
|
||||
//helper to count what is visible
|
||||
function countVisibleFieldset()
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
_.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){
|
||||
if (fieldset.remove == false) {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
function countVisibleProperty(fieldset)
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
for (var i in fieldset.properties) {
|
||||
if (fieldset.properties[i].remove == false) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//handles a fieldset add
|
||||
$scope.addFieldsetRow = function ($index, $event) {
|
||||
$scope.archetypeConfigRenderModel.fieldsets.splice($index + 1, 0, eval("(" + newFieldsetModel + ")"));
|
||||
$scope.focusFieldset();
|
||||
}
|
||||
|
||||
//rather than splice the archetypeConfigRenderModel, we're hiding this and cleaning onFormSubmitting
|
||||
$scope.removeFieldsetRow = function ($index) {
|
||||
if ($scope.canRemoveFieldset()) {
|
||||
if (confirm('Are you sure you want to remove this?')) {
|
||||
$scope.archetypeConfigRenderModel.fieldsets[$index].remove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//handles a property add
|
||||
$scope.addPropertyRow = function (fieldset, $index) {
|
||||
fieldset.properties.splice($index + 1, 0, eval("(" + newPropertyModel + ")"));
|
||||
}
|
||||
|
||||
//rather than splice the archetypeConfigRenderModel, we're hiding this and cleaning onFormSubmitting
|
||||
$scope.removePropertyRow = function (fieldset, $index) {
|
||||
if ($scope.canRemoveProperty(fieldset)) {
|
||||
if (confirm('Are you sure you want to remove this?')) {
|
||||
fieldset.properties[$index].remove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//helper to ini the render model
|
||||
function initConfigRenderModel()
|
||||
{
|
||||
$scope.archetypeConfigRenderModel = $scope.model.value;
|
||||
|
||||
_.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){
|
||||
|
||||
fieldset.remove = false;
|
||||
|
||||
if(fieldset.label)
|
||||
{
|
||||
fieldset.collapse = true;
|
||||
}
|
||||
|
||||
_.each(fieldset.properties, function(fieldset){
|
||||
fieldset.remove = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//sync things up on save
|
||||
$scope.$on("formSubmitting", function (ev, args) {
|
||||
syncModelToRenderModel();
|
||||
});
|
||||
|
||||
//helper to sync the model to the renderModel
|
||||
function syncModelToRenderModel()
|
||||
{
|
||||
$scope.model.value = $scope.archetypeConfigRenderModel;
|
||||
var fieldsets = [];
|
||||
|
||||
_.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){
|
||||
//check fieldsets
|
||||
if (!fieldset.remove) {
|
||||
fieldsets.push(fieldset);
|
||||
|
||||
var properties = [];
|
||||
|
||||
_.each(fieldset.properties, function(property){
|
||||
if (!property.remove) {
|
||||
properties.push(property);
|
||||
}
|
||||
});
|
||||
|
||||
fieldset.properties = properties;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.model.value.fieldsets = fieldsets;
|
||||
}
|
||||
|
||||
//archetype css
|
||||
assetsService.loadCss("/App_Plugins/Archetype/css/archetype.css");
|
||||
});
|
||||
+176
-32
@@ -1,28 +1,41 @@
|
||||
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, assetsService) {
|
||||
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, $interpolate, assetsService, angularHelper, notificationsService) {
|
||||
|
||||
//$scope.model.value = "";
|
||||
|
||||
//set default value of the model
|
||||
//this works by checking to see if there is a model; then cascades to the default model then to an empty fieldset
|
||||
|
||||
//validate the user configs
|
||||
$scope.model.config.defaultModel = getValidJson("$scope.model.config.defaultModel", $scope.model.config.defaultModel);
|
||||
$scope.model.config.fieldsetModels = getValidJson("$scope.model.config.fieldsetModels", $scope.model.config.fieldsetModels);
|
||||
var form = angularHelper.getCurrentForm($scope);
|
||||
|
||||
$scope.model.value = $scope.model.value || ($scope.model.config.defaultModel || { fieldsets: [getEmptyRenderItem($scope.model.config.fieldsetModels[0])] });
|
||||
$scope.model.config = $scope.model.config.archetypeConfig;
|
||||
|
||||
$scope.model.value = $scope.model.value || { fieldsets: [getEmptyRenderFieldset($scope.model.config.fieldsets[0])] };
|
||||
|
||||
//ini
|
||||
$scope.archetypeRenderModel = {};
|
||||
initArchetypeRenderModel();
|
||||
|
||||
//helper to get $eval the labelTemplate
|
||||
$scope.getFieldsetTitle = function(fieldsetConfigModel, fieldsetIndex) {
|
||||
var fieldset = $scope.archetypeRenderModel.fieldsets[fieldsetIndex];
|
||||
var template = fieldsetConfigModel.labelTemplate;
|
||||
var rgx = /{{(.*?)}}*/g;
|
||||
var results;
|
||||
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);
|
||||
}
|
||||
|
||||
return parsedTemplate;
|
||||
};
|
||||
|
||||
/* add/remove/sort */
|
||||
|
||||
//defines the options for the jquery sortable
|
||||
//i used an ng-model="archetypeRenderModel" so the sort updates the right model
|
||||
//configuration overrides the default
|
||||
var configSortableOptions = getValidJson("$scope.model.config.sortableOptions", $scope.model.config.sortableOptions);
|
||||
|
||||
$scope.sortableOptions = configSortableOptions || {
|
||||
$scope.sortableOptions = {
|
||||
axis: 'y',
|
||||
cursor: "move",
|
||||
handle: ".handle",
|
||||
@@ -38,19 +51,21 @@
|
||||
$scope.addRow = function (fieldsetAlias, $index) {
|
||||
if ($scope.canAdd())
|
||||
{
|
||||
if ($scope.model.config.fieldsetModels)
|
||||
if ($scope.model.config.fieldsets)
|
||||
{
|
||||
var newRenderItem = getEmptyRenderItem($scope.getConfigFieldsetByAlias(fieldsetAlias));
|
||||
var newFieldset = getEmptyRenderFieldset($scope.getConfigFieldsetByAlias(fieldsetAlias));
|
||||
|
||||
if (typeof $index != 'undefined')
|
||||
{
|
||||
$scope.archetypeRenderModel.fieldsets.splice($index + 1, 0, newRenderItem);
|
||||
$scope.archetypeRenderModel.fieldsets.splice($index + 1, 0, newFieldset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$scope.archetypeRenderModel.fieldsets.push(newRenderItem);
|
||||
$scope.archetypeRenderModel.fieldsets.push(newFieldset);
|
||||
}
|
||||
}
|
||||
newFieldset.collapse = true;
|
||||
$scope.focusFieldset(newFieldset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,9 +81,9 @@
|
||||
//helpers for determining if a user can do something
|
||||
$scope.canAdd = function ()
|
||||
{
|
||||
if ($scope.model.config.maxProperties)
|
||||
if ($scope.model.config.maxFieldsets)
|
||||
{
|
||||
return countVisible() < $scope.model.config.maxProperties;
|
||||
return countVisible() < $scope.model.config.maxFieldsets;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -89,16 +104,58 @@
|
||||
//helper, ini the render model from the server (model.value)
|
||||
function initArchetypeRenderModel() {
|
||||
$scope.archetypeRenderModel = $scope.model.value;
|
||||
|
||||
_.each($scope.archetypeRenderModel.fieldsets, function (fieldset)
|
||||
{
|
||||
fieldset.remove = false;
|
||||
fieldset.collapse = false;
|
||||
fieldset.isValid = true;
|
||||
});
|
||||
}
|
||||
|
||||
//helper to get the correct fieldset from config
|
||||
$scope.getConfigFieldsetByAlias = function(alias) {
|
||||
for (var i in $scope.model.config.fieldsetModels) {
|
||||
if ($scope.model.config.fieldsetModels[i].alias == alias) {
|
||||
return $scope.model.config.fieldsetModels[i];
|
||||
return _.find($scope.model.config.fieldsets, function(fieldset){
|
||||
return fieldset.alias == alias;
|
||||
});
|
||||
}
|
||||
|
||||
//helper to get a property by alias from a fieldset
|
||||
$scope.getPropertyValueByAlias = function(fieldset, propertyAlias) {
|
||||
var property = _.find(fieldset.properties, function(p) {
|
||||
return p.alias == propertyAlias;
|
||||
});
|
||||
return (typeof property !== 'undefined') ? property.value : '';
|
||||
};
|
||||
|
||||
//helper for collapsing
|
||||
$scope.focusFieldset = function(fieldset){
|
||||
|
||||
var iniState;
|
||||
|
||||
if(fieldset)
|
||||
{
|
||||
iniState = fieldset.collapse;
|
||||
}
|
||||
|
||||
_.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
|
||||
if($scope.archetypeRenderModel.fieldsets.length == 1 && fieldset.remove == false)
|
||||
{
|
||||
fieldset.collapse = false;
|
||||
return;
|
||||
}
|
||||
|
||||
fieldset.collapse = true;
|
||||
});
|
||||
|
||||
if(iniState)
|
||||
{
|
||||
fieldset.collapse = !iniState;
|
||||
}
|
||||
}
|
||||
|
||||
//ini
|
||||
$scope.focusFieldset();
|
||||
|
||||
//helper returns valid JS or null
|
||||
function getValidJson(variable, json)
|
||||
@@ -126,7 +183,7 @@
|
||||
//watch for changes
|
||||
$scope.$watch('archetypeRenderModel', function (v) {
|
||||
if ($scope.model.config.developerMode) {
|
||||
//console.log(v);
|
||||
console.log(v);
|
||||
if (typeof v === 'string') {
|
||||
$scope.archetypeRenderModel = JSON.parse(v);
|
||||
$scope.archetypeRenderModel.toString = stringify;
|
||||
@@ -139,11 +196,11 @@
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
for (var i in $scope.archetypeRenderModel.fieldsets) {
|
||||
if ($scope.archetypeRenderModel.fieldsets[i].remove == false) {
|
||||
_.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
|
||||
if (fieldset.remove == false) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -153,24 +210,111 @@
|
||||
{
|
||||
$scope.model.value = { fieldsets: [] };
|
||||
|
||||
for (var i in $scope.archetypeRenderModel.fieldsets) {
|
||||
if (!$scope.archetypeRenderModel.fieldsets[i].remove) {
|
||||
//remove the 'remove' property as this is only for sorting/internal use
|
||||
delete $scope.archetypeRenderModel.fieldsets[i].remove;
|
||||
$scope.model.value.fieldsets.push($scope.archetypeRenderModel.fieldsets[i]);
|
||||
_.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
|
||||
if (typeof fieldset != 'function' && !fieldset.remove){
|
||||
|
||||
//clone and clean
|
||||
var tempFieldset = JSON.parse(JSON.stringify(fieldset));
|
||||
delete tempFieldset.remove;
|
||||
delete tempFieldset.isValid;
|
||||
delete tempFieldset.collapse;
|
||||
|
||||
_.each(tempFieldset.properties, function(property){
|
||||
delete property.isValid;
|
||||
});
|
||||
|
||||
$scope.model.value.fieldsets.push(tempFieldset);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//helper to add an empty fieldset
|
||||
function getEmptyRenderItem (fieldsetModel)
|
||||
function getEmptyRenderFieldset (fieldsetModel)
|
||||
{
|
||||
return eval("({ alias: '" + fieldsetModel.alias + "', remove: false, properties: []})");
|
||||
}
|
||||
|
||||
//helper for validation
|
||||
function getValidation()
|
||||
{
|
||||
var validation = {}
|
||||
validation.isValid = true;
|
||||
validation.requiredAliases = [];
|
||||
validation.invalidProperties = [];
|
||||
|
||||
//determine which fields are required
|
||||
_.each($scope.model.config.fieldsets, function(fieldset){
|
||||
_.each(fieldset.properties, function(property){
|
||||
if(property.required)
|
||||
{
|
||||
validation.requiredAliases.push(property.alias);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//if nothing required; let's go
|
||||
if(validation.requiredAliases.length == 0)
|
||||
{
|
||||
return validation;
|
||||
}
|
||||
|
||||
//otherwise we need to check the required aliases
|
||||
_.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
|
||||
fieldset.isValid = true;
|
||||
|
||||
_.each(fieldset.properties, function(property){
|
||||
property.isValid = true;
|
||||
|
||||
//if a required field
|
||||
if(_.find(validation.requiredAliases, function(alias){ return alias == property.alias }))
|
||||
{
|
||||
//TODO: do a better validation test
|
||||
if(property.value == ""){
|
||||
fieldset.isValid = false;
|
||||
property.isValid = false;
|
||||
validation.isValid = false;
|
||||
|
||||
validation.invalidProperties.push(property);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if($scope.model.config.developerMode == '1')
|
||||
{
|
||||
console.log(validation);
|
||||
}
|
||||
|
||||
return validation;
|
||||
}
|
||||
|
||||
$scope.getPropertyValidity = function(fieldsetIndex, alias)
|
||||
{
|
||||
if($scope.archetypeRenderModel.fieldsets[fieldsetIndex])
|
||||
{
|
||||
var property = _.find($scope.archetypeRenderModel.fieldsets[fieldsetIndex].properties, function(property){
|
||||
return property.alias == alias;
|
||||
});
|
||||
}
|
||||
|
||||
return (typeof property == 'undefined') ? true : property.isValid;
|
||||
}
|
||||
|
||||
//sync things up on save
|
||||
$scope.$on("formSubmitting", function (ev, args) {
|
||||
syncModelToRenderModel();
|
||||
|
||||
var validation = getValidation();
|
||||
|
||||
if(!validation.isValid)
|
||||
{
|
||||
notificationsService.warning("Cannot Save Document", "The document could not be saved because of missing required fields.")
|
||||
form.$setValidity("archetypeError", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
syncModelToRenderModel();
|
||||
form.$setValidity("archetypeError", true);
|
||||
}
|
||||
});
|
||||
|
||||
//custom js
|
||||
@@ -179,7 +323,7 @@
|
||||
}
|
||||
|
||||
//archetype css
|
||||
assetsService.loadCss("/App_Plugins/Imulus.Archetype/css/archetype.css");
|
||||
assetsService.loadCss("/App_Plugins/Archetype/css/archetype.css");
|
||||
|
||||
//custom css
|
||||
if($scope.model.config.customCssPath)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
angular.module("umbraco").directive('archetypeProperty', function ($compile, $http) {
|
||||
|
||||
function getFieldsetByAlias(fieldsetModels, alias)
|
||||
function getFieldsetByAlias(fieldsets, alias)
|
||||
{
|
||||
for (var i in fieldsetModels)
|
||||
for (var i in fieldsets)
|
||||
{
|
||||
if (fieldsetModels[i].alias == alias)
|
||||
if (fieldsets[i].alias == alias)
|
||||
{
|
||||
return fieldsetModels[i];
|
||||
return fieldsets[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,13 +23,54 @@
|
||||
|
||||
var linker = function (scope, element, attrs) {
|
||||
|
||||
var configFieldsetModel = getFieldsetByAlias(scope.archetypeConfig.fieldsetModels, scope.fieldset.alias);
|
||||
var configFieldsetModel = getFieldsetByAlias(scope.archetypeConfig.fieldsets, scope.fieldset.alias);
|
||||
|
||||
var view = configFieldsetModel.properties[scope.propertyConfigIndex].view;
|
||||
var label = configFieldsetModel.properties[scope.propertyConfigIndex].label;
|
||||
var config = configFieldsetModel.properties[scope.propertyConfigIndex].config;
|
||||
var alias = configFieldsetModel.properties[scope.propertyConfigIndex].alias;
|
||||
var defaultValue = configFieldsetModel.properties[scope.propertyConfigIndex].value;
|
||||
|
||||
//try to convert the config to a JS object
|
||||
if(config && typeof config == 'string'){
|
||||
try{
|
||||
if(scope.archetypeConfig.developerMode == '1'){
|
||||
console.log("Trying to eval config: " + config);
|
||||
}
|
||||
config = eval("(" + config + ")");
|
||||
}
|
||||
catch(exception)
|
||||
{
|
||||
if(scope.archetypeConfig.developerMode == '1'){
|
||||
console.log("Failed to eval config.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(config && scope.archetypeConfig.developerMode == '1'){
|
||||
console.log("Config post-eval: " + config);
|
||||
}
|
||||
|
||||
//try to convert the defaultValue to a JS object
|
||||
if(defaultValue && typeof defaultValue == 'string'){
|
||||
try{
|
||||
if(scope.archetypeConfig.developerMode == '1'){
|
||||
console.log("Trying to eval default value: " + defaultValue);
|
||||
}
|
||||
defaultValue = eval("(" + defaultValue + ")");
|
||||
}
|
||||
catch(exception)
|
||||
{
|
||||
if(scope.archetypeConfig.developerMode == '1'){
|
||||
console.log("Failed to eval defaultValue.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(defaultValue && scope.archetypeConfig.developerMode == '1'){
|
||||
console.log("Default value post-eval: " + defaultValue);
|
||||
}
|
||||
|
||||
if (view)
|
||||
{
|
||||
$http.get(view).success(function (data) {
|
||||
@@ -50,7 +91,7 @@
|
||||
|
||||
if (!renderModelPropertyIndex)
|
||||
{
|
||||
scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties.push(eval("({alias: '" + alias + "', value:''})"));
|
||||
scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties.push(eval("({alias: '" + alias + "', value:'" + defaultValue + "'})"));
|
||||
renderModelPropertyIndex = getPropertyIdByAlias(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties, alias);
|
||||
}
|
||||
scope.model.value = scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties[renderModelPropertyIndex].value;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
.archetypeEditor .archetypeProperty{
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.archetypeEditor .umb-contentpicker{
|
||||
@@ -76,4 +77,114 @@
|
||||
clear:both;
|
||||
margin-bottom: 3px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.archetypeConfig {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.archetypeConfig ul{
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeEditorControls{
|
||||
float: right;
|
||||
}
|
||||
|
||||
.archetypeConfig li{
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.archetypeConfig label{
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeFieldsetWrapper{
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeFieldsetOption input[type=text]{
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeDeveloperModel {
|
||||
width: 88%;
|
||||
margin-left: 30px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypePropertiesWrapper{
|
||||
border: 1px solid #ddd;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
margin-left: 50px;
|
||||
width: 665px;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypePropertiesWrapper ul{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypePropertiesWrapper li{
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypePropertiesWrapper li:last-child{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeFieldsets {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeFieldsetTitle {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeFieldsetCollapser{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeOptions label{
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeAdvancedOptions label{
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeDeveloperModel {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypeMaxFieldsets{
|
||||
border: 1px solid #ddd;
|
||||
width: 25px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypePropertyTitle{
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.archetypeConfig .archetypePropertyCollapser{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.archetypeEditor .archetypeFieldsetError{
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.archetypeEditor .archetypePropertyError{
|
||||
border: 1px solid red;
|
||||
background-color: #8b0000;
|
||||
color: #fff;
|
||||
margin-bottom: 5px;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
+11
-110
@@ -1,129 +1,30 @@
|
||||
{
|
||||
propertyEditors: [
|
||||
propertyEditors: [
|
||||
{
|
||||
alias: "Imulus.Archetype",
|
||||
name: "Imulus Archetype",
|
||||
name: "Archetype",
|
||||
editor: {
|
||||
view: "~/App_Plugins/Imulus.Archetype/views/archetype.html",
|
||||
view: "~/App_Plugins/Archetype/views/archetype.html",
|
||||
valueType: "JSON"
|
||||
},
|
||||
},
|
||||
prevalues: {
|
||||
fields: [
|
||||
{
|
||||
label: "Empty Fieldset Models",
|
||||
description: "(Required) Define your fieldset models?",
|
||||
key: "fieldsetModels",
|
||||
view: "textarea",
|
||||
fields: [
|
||||
{
|
||||
label: "Config",
|
||||
description: "(Required) Describe your Archetype.",
|
||||
key: "archetypeConfig",
|
||||
view: "/App_Plugins/Archetype/views/archetype.config.html",
|
||||
validation: [
|
||||
{
|
||||
type: "Required"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Hide fieldset toolbar?",
|
||||
description: "Hides the fieldset toolbar that appears when more than one fieldset model appears.",
|
||||
key: "hideFieldsetToolbar",
|
||||
view: "boolean",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Hide fieldset editor controls?",
|
||||
description: "Hides the fieldset add/remove/sort controls.",
|
||||
key: "hideFieldsetControls",
|
||||
view: "boolean",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Hide fieldset labels?",
|
||||
description: "Hides the fieldset labels.",
|
||||
key: "hideFieldsetLabels",
|
||||
view: "boolean",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Hide property labels?",
|
||||
description: "Hides the property labels.",
|
||||
key: "hidePropertyLabels",
|
||||
view: "boolean",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Default Model",
|
||||
description: "(Optional) What would you the default model to be? Otherwise the model will defer to the Empty Fieldset Model for new items.",
|
||||
key: "defaultModel",
|
||||
view: "textarea",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Max Fieldsets",
|
||||
description: "(Optional) How many Fieldsets are allowed? Entering '1' will disable the controls. Default is unlimited.",
|
||||
key: "maxProperties",
|
||||
view: "number",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Custom Wrapper Class",
|
||||
description: "(Optional) Enter a custom CSS class that will be applied to the wrapper div.",
|
||||
key: "customCssClass",
|
||||
view: "textstring",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "CSS File",
|
||||
description: "(Optional) Enter a path for a custom CSS file to be included on the page.",
|
||||
key: "customCssPath",
|
||||
view: "textstring",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "JS File",
|
||||
description: "(Optional) Enter a path for a custom JS file to be included on the page.",
|
||||
key: "customJsPath",
|
||||
view: "textstring",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Developer Mode",
|
||||
description: "(Advanced) Turn on for developer options.",
|
||||
key: "developerMode",
|
||||
view: "boolean",
|
||||
validation: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Sortable Options",
|
||||
description: "(Advanced) Override the default sortable controls with a JSON object.",
|
||||
key: "sortableOptions",
|
||||
view: "textarea",
|
||||
validation: [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
javascript: [
|
||||
'~/App_Plugins/Imulus.Archetype/js/archetype.js'
|
||||
'~/App_Plugins/Archetype/js/archetype.js'
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
angular.module('umbraco').factory('propertyEditorService', function($q, $http, umbRequestHelper){
|
||||
return {
|
||||
getViews: function() {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get("/App_Plugins/Archetype/js/config.views.js"), 'Failed to retreive config for views.'
|
||||
);
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,119 @@
|
||||
<div class="archetypeConfig" ng-controller="Imulus.ArchetypeConfigController">
|
||||
<ul class="archetypeFieldsets" ui-sortable="sortableOptions" ng-model="archetypeConfigRenderModel.fieldsets">
|
||||
<li ng-repeat="fieldset in archetypeConfigRenderModel.fieldsets" ng-hide="fieldset.remove">
|
||||
<div class="archetypeFieldsetWrapper" >
|
||||
<div class="archetypeEditorControls" ng-show="archetypeConfigRenderModel.enableMultipleFieldsets">
|
||||
<i class="icon icon-add" ng-click="addFieldsetRow($index, $event)"></i>
|
||||
<i class="icon icon-delete" ng-click="removeFieldsetRow($index)" ng-show="canRemoveFieldset()"></i>
|
||||
<i class="icon icon-navigation handle" ng-show="canSortFieldset()"></i>
|
||||
</div>
|
||||
<div class="archetypeFieldsetTitle" ng-click="focusFieldset(fieldset)">{{fieldset.label}}</div>
|
||||
<div class="archetypeFieldsetCollapser" ng-hide="fieldset.collapse && fieldset.label">
|
||||
<div class="archetypeFieldsetOption">
|
||||
<label>Label</label><input type="text" ng-model="fieldset.label" />
|
||||
</div>
|
||||
<div class="archetypeFieldsetOption">
|
||||
<label>Alias</label><input type="text" ng-model="fieldset.alias" />
|
||||
</div>
|
||||
<div class="archetypeFieldsetOption">
|
||||
<label>Label Template</label><input type="text" ng-model="fieldset.labelTemplate" />
|
||||
</div>
|
||||
<div class="archetypeFieldsetOption">
|
||||
<label>Tooltip</label><input type="text" ng-model="fieldset.tooltip" />
|
||||
</div>
|
||||
<div class="archetypeFieldsetOption">
|
||||
<label>Icon</label><input type="text" ng-model="fieldset.icon" />
|
||||
</div>
|
||||
<div class="archetypeFieldsetOption">
|
||||
<label>Header Text</label><input type="text" ng-model="fieldset.headerText" />
|
||||
</div>
|
||||
<div class="archetypeFieldsetOption">
|
||||
<label>Footer Text</label><input type="text" ng-model="fieldset.footerText" />
|
||||
</div>
|
||||
<div class="archetypeFieldsetOption">
|
||||
<label>Properties</label>
|
||||
</div>
|
||||
<div class="archetypePropertiesWrapper">
|
||||
<ul ui-sortable="sortableOptions" ng-model="fieldset.properties">
|
||||
<li ng-repeat="property in fieldset.properties" ng-hide="property.remove">
|
||||
<div class="archetypeEditorControls">
|
||||
<i class="icon icon-add" ng-click="addPropertyRow(fieldset, $index)"></i>
|
||||
<i class="icon icon-delete" ng-click="removePropertyRow(fieldset, $index)" ng-show="canRemoveProperty(fieldset)"></i>
|
||||
<i class="icon icon-navigation handle" ng-show="canSortProperty(fieldset)"></i>
|
||||
</div>
|
||||
<div class="archetypePropertyTitle" ng-click="focusProperty(fieldset.properties, property)">{{property.label}}</div>
|
||||
<div class="archetypePropertyCollapser" ng-hide="property.collapse && property.label">
|
||||
<div>
|
||||
<label>Label</label><input type="text" ng-model="property.label" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Alias</label><input type="text" ng-model="property.alias" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Help Text</label><input type="text" ng-model="property.helpText" />
|
||||
</div>
|
||||
<div>
|
||||
<label>View</label><select ng-model="property.view" ng-options="view.path as view.name for view in availableViews"></select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Default Value</label><input type="text" ng-model="property.value" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Config</label><textarea ng-model="property.config" /></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label>Required</label><input type="checkbox" ng-model="property.required" />
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="archetypeOptions">
|
||||
|
||||
<div>
|
||||
<label>Toggle Advanced Options<small>Show advanced options.</small></label><input type="checkbox" ng-model="archetypeConfigRenderModel.showAdvancedOptions"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="archetypeAdvancedOptions" ng-show="archetypeConfigRenderModel.showAdvancedOptions">
|
||||
<div>
|
||||
<label>Hide fieldset editor controls?<small>Hides the fieldset add/remove/sort controls.</small></label><input type="checkbox" ng-model="archetypeConfigRenderModel.hideFieldsetControls"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>Hide fieldset labels?<small>Hides the fieldset labels.</small></label><input type="checkbox" ng-model="archetypeConfigRenderModel.hideFieldsetLabels"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>Hide property labels?<small>Hides the property labels.</small></label><input type="checkbox" ng-model="archetypeConfigRenderModel.hidePropertyLabels"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>Max fieldsets<small>How many Fieldsets are allowed? Entering '1' will disable the controls. Default is unlimited.</small></label><input type="text" class="archetypeMaxFieldsets" ng-model="archetypeConfigRenderModel.maxFieldsets"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enable multiple fieldsets?<small>Allows multiple types of fieldsets within this archetype.</small></label><input type="checkbox" ng-model="archetypeConfigRenderModel.enableMultipleFieldsets"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>Hide fieldset toolbar?<small>Hides the fieldset toolbar that appears when more than one fieldset model appears.</small></label><input type="checkbox" ng-model="archetypeConfigRenderModel.hideFieldsetToolbar"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>Custom Wrapper Class<small>(Optional) Enter a custom CSS class that will be applied to the wrapper div.</small></label><input type="text" ng-model="archetypeConfigRenderModel.customCssClass"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>CSS File<small>(Optional) Enter a path for a custom CSS file to be included on the page.</small></label><input type="text" ng-model="archetypeConfigRenderModel.customCssPath"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>JS File<small>(Optional) Enter a path for a custom JS file to be included on the page.</small></label><input type="text" ng-model="archetypeConfigRenderModel.customJsPath"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>Toggle Developer Mode<small>Turn on for developer options.</small></label><input type="checkbox" ng-model="archetypeConfigRenderModel.developerMode"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>Config Model<small>Be careful editing the text below, it controls the schema for this archetype.</small></label>
|
||||
<textarea class="archetypeDeveloperModel" ng-model="archetypeConfigRenderModel"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+22
-20
@@ -1,8 +1,8 @@
|
||||
<div class="archetypeEditor ng-class:model.config.customCssClass" ng-controller="Imulus.ArchetypeController">
|
||||
<textarea class="archetypeDeveloperModel" ng-show="model.config.developerMode" ng-model="archetypeRenderModel"></textarea>
|
||||
<div class="archetypeFieldsetToolbar" ng-show="model.config.fieldsetModels.length > 1 && model.config.hideFieldsetToolbar != '1'">
|
||||
<div class="archetypeFieldsetToolbar" ng-show="model.config.fieldsets.length > 1 && model.config.hideFieldsetToolbar != '1'">
|
||||
<ul>
|
||||
<li ng-repeat="fieldsetModel in model.config.fieldsetModels" ng-click="addRow(fieldsetModel.alias)">
|
||||
<li ng-repeat="fieldsetModel in model.config.fieldsets" ng-click="addRow(fieldsetModel.alias)">
|
||||
<img ng-src='{{fieldsetModel.icon}}' title="{{fieldsetModel.tooltip}}" />
|
||||
<span>{{fieldsetModel.label}}</span>
|
||||
</li>
|
||||
@@ -10,32 +10,34 @@
|
||||
</div>
|
||||
<ul ui-sortable="sortableOptions" ng-model="archetypeRenderModel.fieldsets">
|
||||
<li ng-repeat="fieldset in archetypeRenderModel.fieldsets" ng-hide="fieldset.remove">
|
||||
<fieldset ng-class="fieldset.alias" ng-init="fieldsetConfigModel=getConfigFieldsetByAlias(fieldset.alias)">
|
||||
<label ng-hide="model.config.hideFieldsetLabels == '1'">
|
||||
<fieldset ng-class="{archetypeFieldsetError: !fieldset.isValid}" ng-init="fieldsetConfigModel = getConfigFieldsetByAlias(fieldset.alias)">
|
||||
<label ng-hide="model.config.hideFieldsetLabels == '1'" ng-click="focusFieldset(fieldset)">
|
||||
<img ng-src='{{fieldsetConfigModel.icon}}' title="{{fieldsetConfigModel.tooltip}}"/>
|
||||
<span>{{fieldsetConfigModel.label}}</span>
|
||||
<span ng-bind="getFieldsetTitle(fieldsetConfigModel, $index)"></span>
|
||||
</label>
|
||||
<div class="archetypeEditorControls" ng-hide="model.config.hideFieldsetControls || model.config.maxProperties == '1'">
|
||||
<div class="archetypeEditorControls" ng-hide="model.config.hideFieldsetControls || model.config.maxFieldsets == '1'">
|
||||
<i class="icon icon-add" ng-click="addRow(fieldset.alias, $index)" ng-show="canAdd()"></i>
|
||||
<i class="icon icon-delete" ng-click="removeRow($index)" ng-show="canRemove()"></i>
|
||||
<i class="icon icon-navigation handle" ng-show="canSort()"></i>
|
||||
</div>
|
||||
<div class="archetypeFieldsetHeaderText" ng-show="fieldsetConfigModel.headerText">
|
||||
<em>{{fieldsetConfigModel.headerText}}</em>
|
||||
</div>
|
||||
<div class="archetypeProperty" ng-repeat="property in fieldsetConfigModel.properties">
|
||||
<label ng-hide="archetypeConfig.hidePropertyLabels == '1'">
|
||||
<span>{{property.label}}</span>
|
||||
<div class="archetypeFieldsetHelpText" ng-show="property.helpText">
|
||||
<em>{{property.helpText}}</em>
|
||||
</div>
|
||||
</label>
|
||||
<div class="arechetypeCollapser" ng-hide="fieldset.collapse">
|
||||
<div class="archetypeFieldsetHeaderText" ng-show="fieldsetConfigModel.headerText">
|
||||
<em>{{fieldsetConfigModel.headerText}}</em>
|
||||
</div>
|
||||
<div ng-class="{archetypePropertyError: getPropertyValidity($parent.$index, property.alias) === false}" class="archetypeProperty" ng-repeat="property in fieldsetConfigModel.properties">
|
||||
<label ng-hide="archetypeConfig.hidePropertyLabels == '1'">
|
||||
<span>{{property.label}}</span>
|
||||
<div class="archetypeFieldsetHelpText" ng-show="property.helpText">
|
||||
<em>{{property.helpText}}</em>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<archetype-property class="archetypeEditor ng-class:property.alias" property="property" fieldset-index="$parent.$index" fieldset="fieldset" archetype-config="model.config" property-config-index="$index" archetype-render-model="archetypeRenderModel"></archetype-property>
|
||||
<archetype-property class="archetypeEditor ng-class:property.alias" property="property" fieldset-index="$parent.$index" fieldset="fieldset" archetype-config="model.config" property-config-index="$index" archetype-render-model="archetypeRenderModel"></archetype-property>
|
||||
</div>
|
||||
<div class="archetypeFieldsetFooterText" ng-show="fieldsetConfigModel.footerText">
|
||||
<em>{{fieldsetConfigModel.footerText}}</em>
|
||||
</div>
|
||||
</div>
|
||||
<div class="archetypeFieldsetFooterText" ng-show="fieldsetConfigModel.footerText">
|
||||
<em>{{fieldsetConfigModel.footerText}}</em>
|
||||
</div>
|
||||
</fieldset>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
+4
-1
@@ -15,6 +15,9 @@
|
||||
"grunt-touch": "~0.1.0",
|
||||
"guid": "0.0.12",
|
||||
"adm-zip": "~0.4.3",
|
||||
"rimraf": "~2.2.5"
|
||||
"rimraf": "~2.2.5",
|
||||
"grunt-nuget": "~0.1.1",
|
||||
"grunt-template": "~0.2.2",
|
||||
"grunt-touch": "~0.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Archetype</id>
|
||||
<version><%= version %></version>
|
||||
<title>Archetype</title>
|
||||
<authors>imulus, tomfulton</authors>
|
||||
<owners>imulus, tomfulton</owners>
|
||||
<projectUrl>http://github.com/imulus/archetype</projectUrl>
|
||||
<description><![CDATA[Archetype]]></description>
|
||||
<tags>umbraco</tags>
|
||||
<iconUrl>http://github.com/imulus/archetype/raw/master/assets/logo.png</iconUrl>
|
||||
<licenseUrl>http://www.opensource.org/licenses/mit-license.php</licenseUrl>
|
||||
</metadata>
|
||||
<files>
|
||||
<% for (var file in files) { %>
|
||||
<file src="<%- files[file].path %>" target="<%= files[file].target %>" />
|
||||
<% } %>
|
||||
</files>
|
||||
</package>
|
||||
Reference in New Issue
Block a user