Merge branch 'develop' of github.com:imulus/Archetype into develop

This commit is contained in:
Kevin Giszewski
2014-01-28 12:00:32 -05:00
16 changed files with 445 additions and 138 deletions
+3 -1
View File
@@ -12,7 +12,9 @@ $RECYCLE.BIN/
dist/
node_modules/
pkg/
pkg/tmp/
pkg/*.nupkg
pkg/*.zip
[Dd]ebug/
[Bb]uild/
+98 -6
View File
@@ -1,7 +1,11 @@
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
pkgMeta: grunt.file.readJSON('pkg/meta.json'),
dest: 'dist',
package_dir: 'pkg',
package_temp_dir: '<%= package_dir %>/tmp/',
watch: {
less: {
@@ -58,26 +62,71 @@ module.exports = function(grunt) {
'app/controllers/controller.js',
'app/controllers/config.controller.js',
'app/directives/archetypeproperty.js',
'app/services/propertyeditor.js'
'app/resources/propertyeditor.js'
],
dest: '<%= dest %>/js/archetype.js'
}
},
nugetpack: {
dist: {
src: '<%= package_temp_dir %>/nuget/package.nuspec',
dest: '<%= package_dir %>'
}
},
template: {
'nuget_manifest': {
'options': {
'data': {
name: '<%= pkgMeta.name %>',
version: '<%= pkgMeta.version %>',
url: '<%= pkgMeta.url %>',
license: '<%= pkgMeta.license %>',
licenseUrl: '<%= pkgMeta.licenseUrl %>',
author: '<%= pkgMeta.author %>',
authorUrl: '<%= pkgMeta.authorUrl %>',
files: [{ path: '..\\..\\..\\<%= dest %>\\**', target: 'content\\App_Plugins\\Archetype'}]
}
},
'files': {
'<%= package_temp_dir %>/nuget/package.nuspec': ['<%= package_dir %>/nuget/package.nuspec']
}
}
},
clean: {
build: ['<%= dest %>']
},
copy: {
build: {
files: [
{expand: true, cwd: 'app/', src: ['package.manifest'], dest: '<%= dest %>', 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}
{expand: true, cwd: 'app/views/', src: ['archetype.html', 'archetype.config.html'], dest: '<%= dest %>/views', flatten: true},
{expand: true, cwd: 'app/Umbraco/Umbraco.Archetype/bin/Debug/', src: ['Archetype.dll'], dest: '<%= dest %>/bin', flatten: true}
]
},
deploy: {
files: [
{expand: true, cwd: '<%= dest %>/', src: ['**'], dest: '<%= grunt.option("target") %>\\App_Plugins\\Archetype', flatten: false},
{expand: true, cwd: '<%= dest %>/', src: ['**/*', '!bin/*'], dest: '<%= grunt.option("target") %>\\App_Plugins\\Archetype', flatten: false},
{expand: true, cwd: '<%= dest %>/', src: ['bin/*'], dest: '<%= grunt.option("target") %>\\bin', flatten: false},
]
},
nuget_prepare: {
files: [
{expand: true, cwd: '<%= dest %>/', src: ['**/*', '!bin/*'], dest: '<%= package_temp_dir %>/nuget/content/', flatten: false},
{expand: true, cwd: '<%= dest %>/', src: ['bin/*'], dest: '<%= package_temp_dir %>/nuget/lib/net40/', flatten: false}
]
},
umbracopackage: {
files: [
{expand: true, cwd: '<%= dest %>/', src: ['**/*', "!bin/*"], dest: 'pkg/tmp/umbraco/App_Plugins/Archetype', flatten: false},
{expand: true, cwd: '<%= dest %>/', src: ['bin/*'], dest: 'pkg/tmp/umbraco', flatten: false}
]
}
},
touch: {
@@ -87,7 +136,42 @@ module.exports = function(grunt) {
}
},
clean: ['<%= dest %>']
umbracoPackage: {
options: {
name: "<%= pkgMeta.name %>",
version: '<%= pkgMeta.version %>',
url: '<%= pkgMeta.url %>',
license: '<%= pkgMeta.license %>',
licenseUrl: '<%= pkgMeta.licenseUrl %>',
author: '<%= pkgMeta.author %>',
authorUrl: '<%= pkgMeta.authorUrl %>',
manifest: 'pkg/umbraco/package.xml',
readme: 'pkg/umbraco/readme.txt',
sourceDir: 'pkg/tmp/umbraco',
outputDir: 'pkg',
}
},
clean: {
build: ['<%= dest %>'],
package_temp: ['pkg/tmp'],
},
msbuild: {
dev: {
src: ['app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj'],
options: {
projectConfiguration: 'Debug',
targets: ['Clean', 'Rebuild'],
stdout: true,
maxCpuCount: 4,
buildParameters: {
WarningLevel: 2
},
verbosity: 'quiet'
}
}
}
});
@@ -98,12 +182,20 @@ 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.loadNpmTasks('grunt-msbuild');
grunt.loadTasks('tasks');
grunt.registerTask('package', ['package:nuget', 'package:umbraco']);
grunt.registerTask('package:nuget', ['copy:nuget_prepare', 'template:nuget_manifest', 'nugetpack', 'clean:package_temp']);
grunt.registerTask('package:umbraco', ['copy:umbracopackage', 'umbracoPackage', '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('css:build', ['less']);
grunt.registerTask('js:build', ['concat']);
grunt.registerTask('default', ['clean', 'css:build', 'js:build', 'copy:build']);
grunt.registerTask('default', ['clean', 'css:build', 'js:build', 'copy:build', 'msbuild:dev']);
};
+14 -9
View File
@@ -17,26 +17,31 @@ Archetype
Add `--touch` to either command to automatically touch the web.config on a deploy
## Installation ##
## Installation
1) Install the <a href='http://bit.ly/1gUYKW8'>package</a> through the Umbraco package installer. Recommended if you want to just see the packaged version.
To use this package right from this repo you will need to manually download and copy the files into the appropriate spot:
OR
###/App_Plugins###
2) Deploy with Grunt (see above). Recommended if you wish to extend this repo as this will inject this project into an existing v7 Umbraco install.
Your /App_Plugins should contain this structure:
OR
3) Not recommended but a down and dirty way is to manually download and copy the files into the appropriate spot:
Your /App_Plugins and /bin should contain this structure:
/App_Plugins
- package.manifest
- /css
-- archetype.css
- /js
-- archetype.js (our Grunt script concats the controller.js and all directives into one file, you may have to do so manually)
-- archetype.js (our Grunt script concats the controller.js/config.controller.js, services and all directives into one file, you will have to do so manually)
-- config.views.js
- /views
-- archetype.html
###/bin###
- Drop the Imulus.Archetype.dll in the /bin of your Umbraco install (this dll only handles template helpers, PVC's at present)
- You will have to build this yourself or download it here.
-- archetype.config.html
/bin
-- archetype.dll (you'll have to build it)
## Prevalue Configs ##
@@ -32,5 +32,6 @@ using System.Runtime.InteropServices;
// 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")]
[assembly: AssemblyVersion("0.1.0.0")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0-alpha")]
+19 -11
View File
@@ -1,21 +1,25 @@
angular.module("umbraco").controller("Imulus.ArchetypeConfigController", function ($scope, $http, assetsService, propertyEditorService) {
angular.module("umbraco").controller("Imulus.ArchetypeConfigController", function ($scope, $http, assetsService, propertyEditorResource) {
//$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 + "]})");
//define empty items
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 = JSON.parse('{"showAdvancedOptions": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hideFieldsetLabels": false, "hidePropertyLabel": false, "maxFieldsets": null, "fieldsets": [' + newFieldsetModel + ']}');
//ini the model
$scope.model.value = $scope.model.value || defaultFieldsetConfigModel;
//ini the render model
initConfigRenderModel();
//get the available views
propertyEditorService.getViews().then(function(data){
propertyEditorResource.getViews().then(function(data){
$scope.availableViews = data;
});
//config for the sorting
$scope.sortableOptions = {
axis: 'y',
cursor: "move",
@@ -28,6 +32,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
}
};
//function that determines how to manage expanding/collapsing fieldsets
$scope.focusFieldset = function(fieldset){
var iniState;
@@ -58,9 +63,11 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
fieldset.collapse = !iniState;
}
}
//ini
//ini the fieldsets
$scope.focusFieldset();
//function that determines how to manage expanding/collapsing properties
$scope.focusProperty = function(properties, property){
var iniState;
@@ -101,7 +108,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
$scope.archetypeConfigRenderModel = JSON.parse(v);
$scope.archetypeConfigRenderModel.toString = stringify;
}
}, true);
});
//helper that returns if an item can be removed
$scope.canRemoveFieldset = function ()
@@ -141,6 +148,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
return count;
}
//determines how many properties are visible
function countVisibleProperty(fieldset)
{
var count = 0;
@@ -156,7 +164,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
//handles a fieldset add
$scope.addFieldsetRow = function ($index, $event) {
$scope.archetypeConfigRenderModel.fieldsets.splice($index + 1, 0, eval("(" + newFieldsetModel + ")"));
$scope.archetypeConfigRenderModel.fieldsets.splice($index + 1, 0, JSON.parse(newFieldsetModel));
$scope.focusFieldset();
}
@@ -171,7 +179,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
//handles a property add
$scope.addPropertyRow = function (fieldset, $index) {
fieldset.properties.splice($index + 1, 0, eval("(" + newPropertyModel + ")"));
fieldset.properties.splice($index + 1, 0, JSON.parse(newPropertyModel));
}
//rather than splice the archetypeConfigRenderModel, we're hiding this and cleaning onFormSubmitting
+10 -26
View File
@@ -1,16 +1,17 @@
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
//get a reference to the current form
var form = angularHelper.getCurrentForm($scope);
//set the config equal to our prevalue config
$scope.model.config = $scope.model.config.archetypeConfig;
//ini the model
$scope.model.value = $scope.model.value || { fieldsets: [getEmptyRenderFieldset($scope.model.config.fieldsets[0])] };
//ini
//ini the render model
$scope.archetypeRenderModel = {};
initArchetypeRenderModel();
@@ -31,10 +32,7 @@
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
//sort config
$scope.sortableOptions = {
axis: 'y',
cursor: "move",
@@ -128,7 +126,7 @@
return (typeof property !== 'undefined') ? property.value : '';
};
//helper for collapsing
//helper for expanding/collapsing fieldsets
$scope.focusFieldset = function(fieldset){
var iniState;
@@ -154,24 +152,9 @@
}
}
//ini
//ini the fieldset expand/collapse
$scope.focusFieldset();
//helper returns valid JS or null
function getValidJson(variable, json)
{
if(!json) return null;
try {
return eval("(" + json + ")");
}
catch (e) {
console.log("There was an error while using 'eval' on " + variable);
console.log(json);
return null;
}
}
//developerMode helpers
$scope.archetypeRenderModel.toString = stringify;
@@ -228,10 +211,10 @@
});
}
//helper to add an empty fieldset
//helper to add an empty fieldset to the render model
function getEmptyRenderFieldset (fieldsetModel)
{
return eval("({ alias: '" + fieldsetModel.alias + "', remove: false, properties: []})");
return JSON.parse('{"alias": "' + fieldsetModel.alias + '", "remove": false, "properties": []}');
}
//helper for validation
@@ -288,6 +271,7 @@
return validation;
}
//helper to lookup validity when given a fieldsetIndex and property alias
$scope.getPropertyValidity = function(fieldsetIndex, alias)
{
if($scope.archetypeRenderModel.fieldsets[fieldsetIndex])
+34 -47
View File
@@ -2,16 +2,12 @@
function getFieldsetByAlias(fieldsets, alias)
{
for (var i in fieldsets)
{
if (fieldsets[i].alias == alias)
{
return fieldsets[i];
}
}
return _.find(fieldsets, function(fieldset){
return fieldset.alias == alias;
});
}
function getPropertyIdByAlias(properties, alias)
function getPropertyIndexByAlias(properties, alias)
{
for (var i in properties)
{
@@ -21,6 +17,31 @@
}
}
//helper that returns a JS ojbect from 'value' string or the original string
function jsonOrString(value, developerMode, debugLabel){
if(value && typeof value == 'string'){
try{
if(developerMode == '1'){
console.log("Trying to parse " + debugLabel + ": " + value);
}
value = JSON.parse(value);
}
catch(exception)
{
if(developerMode == '1'){
console.log("Failed to parse " + debugLabel + ".");
}
}
}
if(value && developerMode == '1'){
console.log(debugLabel + " post-parsing: ");
console.log(value);
}
return value;
}
var linker = function (scope, element, attrs) {
var configFieldsetModel = getFieldsetByAlias(scope.archetypeConfig.fieldsets, scope.fieldset.alias);
@@ -32,44 +53,10 @@
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);
}
config = jsonOrString(config, scope.archetypeConfig.developerMode, "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);
}
defaultValue = jsonOrString(defaultValue, scope.archetypeConfig.developerMode, "defaultValue");
if (view)
{
@@ -87,12 +74,12 @@
scope.model.config = {};
//ini the property value after test to make sure a prop exists in the renderModel
var renderModelPropertyIndex = getPropertyIdByAlias(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties, alias);
var renderModelPropertyIndex = getPropertyIndexByAlias(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties, alias);
if (!renderModelPropertyIndex)
{
scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties.push(eval("({alias: '" + alias + "', value:'" + defaultValue + "'})"));
renderModelPropertyIndex = getPropertyIdByAlias(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties, alias);
scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties.push(JSON.parse('{"alias": "' + alias + '", "value": "' + defaultValue + '"}'));
renderModelPropertyIndex = getPropertyIndexByAlias(scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties, alias);
}
scope.model.value = scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex].properties[renderModelPropertyIndex].value;
+68 -12
View File
@@ -1,20 +1,63 @@
.archetypeEditor fieldset{
border: 1px solid #666;
padding: 5px;
border: 1px solid #dddddd;
padding: 0;
margin-bottom: 5px;
background-color: #fff;
background-color: #f1f1f1;
clear: both;
display: inline-block;
width: 100%;
}
.archetypeEditor label{
width: 75px;
.archetypeEditor .archetypeFieldsetLabel {
padding: 8px 25px 8px 3px;
float: left;
width: 98%;
span {
font-weight: bold;
}
&:hover {
cursor: pointer;
label span {
text-decoration: underline;
}
}
.caret {
float:left;
margin: 8px 1px 0 7px;
&.caret-right {
border-bottom: 4px solid transparent;
border-top: 4px solid transparent;
border-left: 4px solid #000000;
content: "";
margin-top: 6px;
}
}
label{
width: 75px;
float: left;
}
}
.archetypeEditor fieldset>label{
.archetypeEditor .arechetypeCollapser{
clear: both;
height: 100%;
margin-top: 10px;
padding-top: 12px;
background-color: #fff;
border-top: 1px solid silver;
border-radius: 0 0 0 5px;
}
.archetypeEditor fieldset .archetypeFieldsetLabel label{
float: left;
width: 200px;
padding-left: 0;
width: auto;
margin-bottom: 0;
padding: 0;
}
.archetypeEditor .multiPropertyTextbox{
@@ -23,10 +66,22 @@
.archetypeEditor ul{
list-style: none;
margin-left: 0;
}
.archetypeEditor .archetypeEditorControls{
float: right;
i:hover {
cursor: pointer;
}
}
.archetypeEditor form {
margin-left:20px;
.control-label {
padding-top: 0 !important;
}
}
.archetypeEditor .archetypeProperty{
@@ -146,10 +201,6 @@
overflow: hidden;
}
.archetypeConfig .archetypeFieldsetCollapser{
margin-top: 10px;
}
.archetypeConfig .archetypeOptions label{
width: 200px;
}
@@ -187,4 +238,9 @@
margin-bottom: 5px;
padding-top: 3px;
padding-bottom: 3px;
}
.ui-sortable-placeholder {
visibility: visible !important;
background-color: #d0e7f1 !important;
}
@@ -1,5 +1,5 @@
angular.module('umbraco').factory('propertyEditorService', function($q, $http, umbRequestHelper){
return {
angular.module('umbraco').factory('propertyEditorResource', 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.'
+37 -21
View File
@@ -8,35 +8,51 @@
</li>
</ul>
</div>
<ul ui-sortable="sortableOptions" ng-model="archetypeRenderModel.fieldsets">
<li ng-repeat="fieldset in archetypeRenderModel.fieldsets" ng-hide="fieldset.remove">
<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 ng-bind="getFieldsetTitle(fieldsetConfigModel, $index)"></span>
</label>
<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="arechetypeCollapser" ng-hide="fieldset.collapse">
<div class="archetypeFieldsetLabel" ng-click="focusFieldset(fieldset)">
<span class="caret" ng-hide="fieldset.collapse"></span>
<span class="caret caret-right" ng-show="fieldset.collapse"></span>
<label ng-hide="model.config.hideFieldsetLabels == '1'">
<img ng-src='{{fieldsetConfigModel.icon}}' title="{{fieldsetConfigModel.tooltip}}" />
<span ng-bind="getFieldsetTitle(fieldsetConfigModel, $index)"></span>
</label>
<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>
<div class="arechetypeCollapser animate-hide" 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>
</div>
<form class="form-inline">
<div ng-class="{archetypePropertyError: getPropertyValidity($parent.$index, property.alias) === false}" class="archetypeProperty control-group" ng-repeat="property in fieldsetConfigModel.properties">
<label ng-hide="archetypeConfig.hidePropertyLabels == '1'" class="control-label" for="archetype-property-{{property.alias}}">
<span>{{property.label}}</span>
<div class="archetypeFieldsetHelpText" ng-show="property.helpText">
<em>{{property.helpText}}</em>
</div>
</label>
<div class="controls">
<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>
</form>
<div class="archetypeFieldsetFooterText" ng-show="fieldsetConfigModel.footerText">
<em>{{fieldsetConfigModel.footerText}}</em>
</div>
</div>
</div>
</fieldset>
</li>
+13 -1
View File
@@ -12,6 +12,18 @@
"grunt-contrib-jshint": "~0.7.2",
"grunt-cli": "~0.1.11",
"grunt-contrib-clean": "~0.5.0",
"grunt-touch": "~0.1.0"
"grunt-touch": "~0.1.0",
"guid": "0.0.12",
"adm-zip": "~0.4.3",
"rimraf": "~2.2.5",
"grunt-nuget": "~0.1.1",
"grunt-template": "~0.2.2",
"grunt-touch": "~0.1.0",
"fs-extra": "~0.8.1",
"grunt-msbuild": "~0.1.9"
},
"repository": {
"type": "git",
"url": "https://github.com/imulus/Archetype.git"
}
}
+9
View File
@@ -0,0 +1,9 @@
{
"name": "Archetype",
"version": "0.1.0-alpha",
"url": "http://github.com/imulus/archetype/",
"author": "Imulus",
"authorUrl": "http://imulus.com/",
"license": "MIT",
"licenseUrl": "http://opensource.org/licenses/MIT"
}
+20
View File
@@ -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><%= name %></title>
<authors>imulus, kgiszewski, tomfulton</authors>
<owners>imulus, kgiszewski, tomfulton</owners>
<projectUrl>http://github.com/imulus/archetype</projectUrl>
<description><![CDATA[Archetype for Umbraco]]></description>
<tags>umbraco</tags>
<iconUrl>http://github.com/imulus/archetype/raw/master/assets/logo.png</iconUrl>
<licenseUrl><%= licenseUrl %></licenseUrl>
</metadata>
<files>
<% files.forEach(function(file) { %>
<file src="<%- file.path %>" target="<%= file.target %>" />
<% }); %>
</files>
</package>
+39
View File
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<umbPackage>
<info>
<package>
<name><%= name %></name>
<version><%= version %></version>
<license url="<%= licenseUrl %>"><%= license %></license>
<url><%= url %></url>
<requirements>
<major>0</major>
<minor>0</minor>
<patch>0</patch>
</requirements>
</package>
<author>
<name><%= author %></name>
<website><%= authorUrl %></website>
</author>
<readme><![CDATA[<%= readmeContents %>]]></readme>
</info>
<DocumentTypes />
<Templates />
<Stylesheets />
<Macros />
<DictionaryItems />
<Languages />
<DataTypes />
<control />
<Actions />
<files>
<% files.forEach(function(file) { %>
<file>
<guid><%= file.guid %>.<%= file.ext %></guid>
<orgPath><%= file.dir %></orgPath>
<orgName><%= file.name %></orgName>
</file>
<% }); %>
</files>
</umbPackage>
View File
+76
View File
@@ -0,0 +1,76 @@
module.exports = function(grunt) {
grunt.registerTask('umbracoPackage', 'Create Umbraco Package', function() {
grunt.config.requires('umbracoPackage.options.name');
grunt.config.requires('umbracoPackage.options.version');
grunt.config.requires('umbracoPackage.options.license');
grunt.config.requires('umbracoPackage.options.licenseUrl');
grunt.config.requires('umbracoPackage.options.url');
grunt.config.requires('umbracoPackage.options.author');
grunt.config.requires('umbracoPackage.options.authorUrl');
grunt.config.requires('umbracoPackage.options.manifest');
grunt.config.requires('umbracoPackage.options.readme');
grunt.config.requires('umbracoPackage.options.outputDir');
grunt.config.requires('umbracoPackage.options.sourceDir');
var Guid = require('guid');
var path = require('path');
var rimraf = require('rimraf');
var AdmZip = require('adm-zip');
var fs = require('fs-extra');
var options = this.options({
minimumUmbracoVersion: '',
files: [],
cwd: '/'
});
var packageFileName = options.name + "_" + options.version + ".zip"
// Gather files
var filesToPackage = [];
getFilesRecursive(options.sourceDir);
filesToPackage = filesToPackage.map(function(f) {
return { guid: Guid.create(), dir: f.dir.replace(options.sourceDir, ''), name: f.name, ext: f.name.split('.').pop() };
});
// Create temp folder for package zip source
var guidFolder = Guid.create().toString();
var newDirName = path.join(options.sourceDir, "..\\" + guidFolder);
fs.mkdirSync(newDirName);
newDirName = path.join(newDirName, guidFolder);
fs.mkdirSync(newDirName);
// Copy flatten structure, with files renamed as <guid>.<ext>
filesToPackage.forEach(function(f) {
var newFileName = f.name == "package.xml" ? f.name : f.guid.toString() + '.' + f.ext;
fs.copySync(path.join(options.sourceDir, f.dir, f.name), path.join(newDirName, newFileName));
});
// Load / transform XML Manifest
options.files = filesToPackage;
options.readmeContents = grunt.file.read(options.readme);
var manifest = grunt.file.read(options.manifest);
manifest = grunt.template.process(manifest, {data: options});
grunt.file.write(path.join(options.sourceDir, "..\\", guidFolder, guidFolder, "package.xml"), manifest); // TODO: Probably shouldn't use sourceDir - what if under source control
// Zip
var zip = new AdmZip();
zip.addLocalFolder(path.join(options.sourceDir, "..\\", guidFolder));
zip.writeZip(path.join(options.outputDir, packageFileName))
function getFilesRecursive(dir) {
var files = fs.readdirSync(dir);
for (var i in files) {
if (!files.hasOwnProperty(i)) continue;
var name = dir+'/'+files[i];
if (fs.statSync(name).isDirectory()) {
getFilesRecursive(name);
} else {
filesToPackage.push({ dir: dir, name: files[i]});
}
}
}
});
};