xmvc 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +17 -0
  5. data/Rakefile +63 -0
  6. data/VERSION +1 -0
  7. data/bin/xmvc +13 -0
  8. data/lib/xmvc/README +20 -0
  9. data/lib/xmvc/builder.rb +72 -0
  10. data/lib/xmvc/builders/all_builder.rb +13 -0
  11. data/lib/xmvc/builders/app_builder.rb +36 -0
  12. data/lib/xmvc/builders/base.rb +138 -0
  13. data/lib/xmvc/builders/css_builder.rb +34 -0
  14. data/lib/xmvc/builders/docs_builder.rb +20 -0
  15. data/lib/xmvc/builders/mvc_builder.rb +33 -0
  16. data/lib/xmvc/builders/plugin_builder.rb +53 -0
  17. data/lib/xmvc/cli.rb +58 -0
  18. data/lib/xmvc/environment.rb +9 -0
  19. data/lib/xmvc/generator.rb +79 -0
  20. data/lib/xmvc/generators/app.rb +94 -0
  21. data/lib/xmvc/generators/base.rb +90 -0
  22. data/lib/xmvc/generators/controller.rb +41 -0
  23. data/lib/xmvc/generators/model.rb +40 -0
  24. data/lib/xmvc/generators/scaffold.rb +15 -0
  25. data/lib/xmvc/generators/templates/Controller.js +10 -0
  26. data/lib/xmvc/generators/templates/Model.js +9 -0
  27. data/lib/xmvc/generators/templates/ModelSpec.js +12 -0
  28. data/lib/xmvc/generators/templates/View.js +17 -0
  29. data/lib/xmvc/generators/templates/_Action.js +7 -0
  30. data/lib/xmvc/generators/templates/app/README.rdoc +152 -0
  31. data/lib/xmvc/generators/templates/app/app/App.js +64 -0
  32. data/lib/xmvc/generators/templates/app/app/controllers/application_controller.js +10 -0
  33. data/lib/xmvc/generators/templates/app/app/controllers/home_controller.js +10 -0
  34. data/lib/xmvc/generators/templates/app/app/views/home/index.js +17 -0
  35. data/lib/xmvc/generators/templates/app/app/views/layout/menu.js +23 -0
  36. data/lib/xmvc/generators/templates/app/config/application.js +1 -0
  37. data/lib/xmvc/generators/templates/app/config/boot.js +66 -0
  38. data/lib/xmvc/generators/templates/app/config/database.js +4 -0
  39. data/lib/xmvc/generators/templates/app/config/environment.json +62 -0
  40. data/lib/xmvc/generators/templates/app/config/environments/development.json +1 -0
  41. data/lib/xmvc/generators/templates/app/config/environments/production.json +4 -0
  42. data/lib/xmvc/generators/templates/app/config/routes.js +27 -0
  43. data/lib/xmvc/generators/templates/app/config/settings.yml +3 -0
  44. data/lib/xmvc/generators/templates/app/public/index.html +19 -0
  45. data/lib/xmvc/generators/templates/app/public/stylesheets/extjs-mvc-all.css +49 -0
  46. data/lib/xmvc/generators/templates/app/spec/SpecHelper.js +0 -0
  47. data/lib/xmvc/generators/templates/app/spec/index.html +66 -0
  48. data/lib/xmvc/generators/templates/app/vendor/screw-unit/EXAMPLE.html +68 -0
  49. data/lib/xmvc/generators/templates/app/vendor/screw-unit/LICENSE +22 -0
  50. data/lib/xmvc/generators/templates/app/vendor/screw-unit/README.markdown +307 -0
  51. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/jquery-1.2.3.js +3408 -0
  52. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/jquery.fn.js +29 -0
  53. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/jquery.print.js +108 -0
  54. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.assets.js +36 -0
  55. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.behaviors.js +91 -0
  56. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.builder.js +80 -0
  57. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.css +90 -0
  58. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.events.js +42 -0
  59. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.matchers.js +145 -0
  60. data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.server.js +21 -0
  61. data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/behaviors_spec.js +178 -0
  62. data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/matchers_spec.js +237 -0
  63. data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/print_spec.js +119 -0
  64. data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/spec_helper.js +0 -0
  65. data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/suite.html +18 -0
  66. data/lib/xmvc/generators/templates/scaffold/ScaffoldController.js +18 -0
  67. data/lib/xmvc/generators/view.rb +33 -0
  68. data/lib/xmvc/plugin.rb +102 -0
  69. data/lib/xmvc/settings.rb +75 -0
  70. data/lib/xmvc/stats.rb +259 -0
  71. data/lib/xmvc/test.rb +9 -0
  72. data/lib/xmvc/testserver.ru +95 -0
  73. data/lib/xmvc/ui.rb +55 -0
  74. data/lib/xmvc/update.rb +71 -0
  75. data/lib/xmvc.rb +79 -0
  76. data/test/helper.rb +10 -0
  77. data/test/test_extjs-core.rb +7 -0
  78. data/xmvc.gemspec +142 -0
  79. metadata +237 -0
@@ -0,0 +1,79 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require 'hpricot'
4
+ require 'generators/base'
5
+ require 'generators/app'
6
+ require 'generators/model'
7
+ require 'generators/view'
8
+ require 'generators/controller'
9
+ require 'generators/scaffold'
10
+
11
+ module Xmvc
12
+ module Generator
13
+
14
+ @@generators = %w(app model controller scaffold view namespace)
15
+ def self.dispatch(generator, *params)
16
+
17
+ unless @@generators.include?(generator)
18
+ raise MVC::ArgumentError.new("Must use one of the following: " + @@generators.join(", ").downcase)
19
+ end
20
+
21
+ name = params.shift
22
+
23
+ case generator
24
+ when "app"
25
+ App.new(name).generate!
26
+ when "model"
27
+ fields = params.select {|arg| arg != "--force"}.collect {|f| f.split(":")}
28
+ Model.new(name, fields).generate!
29
+ when "controller"
30
+ actions = params.select {|arg| arg != "--force"}
31
+ Controller.new(name, actions).generate!
32
+ when "scaffold"
33
+ fields = params.select {|arg| arg != "--force"}.collect {|f| f.split(":")}
34
+ Scaffold.new(name, fields).generate!
35
+ when "view"
36
+ package = name
37
+ name = params.shift
38
+ View.new(package, name).generate!
39
+ when "namespace"
40
+ self.namespace(name)
41
+
42
+ end
43
+ end
44
+
45
+ # overwrites all instances of 'MyApp' with the namespace provided
46
+ def self.namespace(namespace)
47
+ current = Xmvc.namespace
48
+
49
+ configs = %w(
50
+ config/settings.yml
51
+ config/application.js
52
+ )
53
+ Dir["app/controllers/*.js"].each do |f|
54
+ write_namespace(f, current, namespace)
55
+ end
56
+ Dir["app/views/*/*.js"].each do |f|
57
+ write_namespace(f, current, namespace)
58
+ end
59
+ configs.each {|f|
60
+ write_namespace(f, current, namespace)
61
+ }
62
+ end
63
+
64
+
65
+
66
+ private
67
+
68
+ def self.write_namespace(f, current, namespace)
69
+ Xmvc.ui.confirm(" namespacing #{f}")
70
+ gsub_file(f, current, namespace)
71
+ end
72
+
73
+ #find/replace in a file. Stolen/adapted from Rails
74
+ def self.gsub_file(filename, regexp, *args, &block)
75
+ content = File.read(filename).gsub(regexp, *args, &block)
76
+ File.open(filename, 'wb') { |file| file.write(content) }
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,94 @@
1
+ module Xmvc
2
+ module Generator
3
+ class App < Base
4
+
5
+ def initialize(name, namespace=nil)
6
+ @file_re ||= Regexp.new("^\.?\/(.*)")
7
+ @name = name
8
+ @namespace = namespace || Extlib::Inflection.camelize(name)
9
+ @template = "#{TEMPLATE_PATH}/app"
10
+ end
11
+
12
+ def generate!
13
+ if File.exists?(@name)
14
+ raise Xmvc::AppAlreadyExists.new("An app named #{@name} already exists")
15
+ end
16
+ FileUtils.mkdir(@name)
17
+ FileUtils.chdir(@name)
18
+
19
+ create_app
20
+ create_config
21
+ create_lib
22
+ create_public
23
+ create_spec
24
+ create_vendor
25
+ create_mvc
26
+
27
+ # Build assets.
28
+ Xmvc::BuilderManager.dispatch(:setup, {
29
+ :asset_root => File.expand_path('.')
30
+ })
31
+
32
+ end
33
+
34
+ private
35
+
36
+ def create_app
37
+ FileUtils.mkdir(%w(app app/models app/views app/controllers))
38
+ copy_file("app", ".")
39
+ show_files("app")
40
+ end
41
+
42
+ def create_config
43
+ FileUtils.mkdir(%w(config config/environments))
44
+ copy_file("config", ".")
45
+ show_files("config")
46
+ end
47
+
48
+ def create_lib
49
+ FileUtils.mkdir(%w(lib))
50
+ show_files("lib")
51
+ end
52
+
53
+ def create_public
54
+ FileUtils.mkdir(%w(public public/stylesheets public/images public/javascripts))
55
+ copy_file("public", ".")
56
+ show_files("public")
57
+ end
58
+
59
+ def create_spec
60
+ FileUtils.mkdir(%w(spec spec/controllers spec/models))
61
+ copy_file("spec", ".")
62
+ show_files("spec")
63
+ end
64
+
65
+ def create_vendor
66
+ FileUtils.mkdir(%w(vendor vendor/plugins))
67
+ copy_file("vendor", ".")
68
+ show_files("vendor", false)
69
+ show_files("vendor/mvc", false)
70
+ end
71
+
72
+ def create_mvc
73
+ FileUtils.cp_r("#{Xmvc::ROOT}/js/", "vendor/mvc")
74
+ end
75
+
76
+ def notify(f)
77
+ m = f.match(@file_re)
78
+ Xmvc.ui.confirm(" create #{(m) ? m[1] : f}")
79
+ end
80
+
81
+ def copy_file(src, dest)
82
+ FileUtils.cp_r("#{@template}/#{src}", dest)
83
+ end
84
+
85
+ def show_files(dir, recursive=true)
86
+ pattern = (recursive) ? "./#{dir}/**/*.*" : "./#{dir}/*"
87
+ notify(dir)
88
+ Dir[pattern].each do |f|
89
+ notify(f)
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,90 @@
1
+ module Xmvc
2
+ module Generator
3
+
4
+ class EnvironmentError < Xmvc::Error; status_code(11) ; end
5
+
6
+ class Base
7
+
8
+ TEMPLATE_PATH = "#{File.dirname(__FILE__)}/templates"
9
+
10
+ def initialize *args
11
+ @gsubs ||= {}
12
+ @gsubs['namespace'] = Xmvc.environment['namespace']
13
+ end
14
+
15
+ protected
16
+ def ensure_directories_present! *args
17
+ args.each do |a|
18
+ Dir.mkdir(a) unless File.exists?(a)
19
+ end
20
+ end
21
+
22
+ def ensure_no_overwrite! *args
23
+ args.each do |a|
24
+ if File.exists?(a) && !ARGV.include?("--force")
25
+ raise Xmvc::FileExists.new("File already exists: #{a}")
26
+ end
27
+ end
28
+ end
29
+
30
+ def template(template_filename, destination_filename)
31
+ #write the file
32
+ File.open(destination_filename, 'w') {|f| f.puts(render_template(template_filename))}
33
+
34
+ Xmvc.ui.confirm(" Created #{destination_filename}")
35
+ end
36
+
37
+ def render_template(template_filename, gsubs = @gsubs)
38
+ #grab the template file text
39
+ template_text = IO.read("#{TEMPLATE_PATH}/#{template_filename}")
40
+
41
+ #translate the template file text
42
+ gsubs.each_pair do |key, value|
43
+ template_text.gsub!(Regexp.new("<%= @#{key} %>"), value)
44
+ end
45
+
46
+ template_text
47
+ end
48
+
49
+ def include_script html_filename, script_filename, dom_id
50
+
51
+ end
52
+
53
+ private
54
+
55
+ ##
56
+ # write a newly generated controller, model or view to environment.json
57
+ # Unfortunately, we cannot JSON.parse the entire config/environment.json, since it contains comments
58
+ # and such. Have to RegExp, pick-out the requested key, and JSON.parse the returned chunk.
59
+ # Is this Regexp satisfactory?? Could probably be made better.
60
+ #
61
+ def to_environment(key, item)
62
+ re = Regexp.new("\"#{key}\"\s*\:\s*(\\[.*?\\](?!\}))", Regexp::MULTILINE)
63
+ content = File.read('config/environment.json')
64
+ m = content.match(re)
65
+ if m
66
+ begin
67
+ items = JSON.parse("#{m[1].strip}")
68
+ rescue StandardError => e
69
+ raise EnvironmentError.new("A JSON parsing error occured parsing config/environment.json. Failed to add #{key} to environment.json.")
70
+ end
71
+
72
+ if item.kind_of?(Hash) # <-- it's a view
73
+ view = items.find {|i| i[item[:package]] }
74
+ if view
75
+ view[item[:package]] << item[:filename]
76
+ else
77
+ items << { item[:package] => [item[:filename]]}
78
+ end
79
+ else
80
+ items << item unless items.include?(item)
81
+ end
82
+ File.open('config/environment.json', "w") do |file|
83
+ file << content.gsub(re, "\"#{key}\": #{items.to_json}")
84
+ end
85
+ end
86
+ end
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,41 @@
1
+ module Xmvc
2
+ module Generator
3
+ class Controller < Base
4
+ def initialize(name, actions = [])
5
+ super
6
+
7
+ @name = name
8
+ @actions = actions
9
+ @package = name.downcase
10
+
11
+ @gsubs.merge!({
12
+ 'controller_name' => Extlib::Inflection.underscore(name),
13
+ 'short_name' => @package,
14
+ 'actions' => generate_actions
15
+ })
16
+
17
+ @controller_filename = "app/controllers/#{@gsubs['controller_name']}_controller.js"
18
+ end
19
+
20
+ def generate!
21
+ ensure_no_overwrite! @controller_filename
22
+ ensure_directories_present! "app", "app/controllers"
23
+
24
+ template "Controller.js", @controller_filename
25
+
26
+ to_environment(:controllers, @gsubs["controller_name"])
27
+
28
+ generate_views!
29
+ end
30
+
31
+ private
32
+ def generate_actions
33
+ @actions.collect {|act| render_template("_Action.js", {'action_name' => act})}.join("")
34
+ end
35
+
36
+ def generate_views!
37
+ @actions.each {|a| View.new(@package, a).generate!}
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,40 @@
1
+ module Xmvc
2
+ module Generator
3
+ class Model < Base
4
+ def initialize(name, fields = [])
5
+ super
6
+
7
+ @fields = fields
8
+ @gsubs['inst_name'] = name.downcase
9
+ @gsubs['class_name'] = Extlib::Inflection.camelize(name)
10
+ @gsubs['file_name'] = Extlib::Inflection.underscore(name)
11
+ @gsubs['fields'] = fields.collect {|f| field_template(f[0], f[1])}.join(",\n")
12
+
13
+ @model_filename = "app/models/#{@gsubs['file_name']}.js"
14
+ @spec_filename = "spec/models/#{@gsubs['file_name']}.spec.js"
15
+ end
16
+
17
+ def generate!
18
+ ensure_no_overwrite! @model_filename, @spec_filename
19
+
20
+ ensure_directories_present! "app", "app/models"
21
+ ensure_directories_present! "spec", "spec/models"
22
+
23
+ template "Model.js", @model_filename
24
+ template "ModelSpec.js", @spec_filename
25
+
26
+ to_environment(:models, @gsubs["file_name"])
27
+ end
28
+
29
+ private
30
+ def field_template(name, type)
31
+ padding = longest_field_length - name.length
32
+ " {name: '#{name}', #{" " * padding}type: '#{type}'}"
33
+ end
34
+
35
+ def longest_field_length
36
+ @fields.collect {|f| f[0].length}.max
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,15 @@
1
+ module Xmvc
2
+ module Generator
3
+ class Scaffold < Base
4
+ def initialize(name, fields = [])
5
+ super
6
+ @fields = fields
7
+ @name = name
8
+ end
9
+
10
+ def generate!
11
+ Model.new(@name, @fields).generate!
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @class <%= @namespace %>.controllers.ApplicationController
3
+ * @extends ExtMVC.controller.CrudController
4
+ * Shared application-wide controller. Place any application-specific code here that needs
5
+ * to be shared amongst other application controllers, and make the other controllers in the
6
+ * application extend this one
7
+ */
8
+ ExtMVC.registerController("<%= @controller_name %>", {
9
+ extend: "controller"
10
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @class <%= @class_name %>
3
+ * @extends ExtMVC.model.Base
4
+ */
5
+ ExtMVC.model.define("<%= @class_name %>", {
6
+ fields: [
7
+ <%= @fields %>
8
+ ]
9
+ });
@@ -0,0 +1,12 @@
1
+ Screw.Unit(function() {
2
+ describe("The <%= @class_name %> class", function() {
3
+ var <%= @inst_name %>;
4
+ before(function() {
5
+ <%= @inst_name %> = new <%= @namespace %>.models.<%= @class_name %>({
6
+ //set fields for this model here
7
+ });
8
+ });
9
+
10
+ //create your unit tests here
11
+ });
12
+ });
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @class MyApp.views.<%= @namespace %>.<%= @class_name %>
3
+ * @extends Ext.Panel
4
+ * Default Welcome to Ext MVC Panel - replace this with your own thing
5
+ */
6
+ ExtMVC.registerView('<%= @namespace %>', '<%= @name %>', {
7
+ xtype: 'panel',
8
+
9
+ initComponent: function() {
10
+ Ext.applyIf(this, {
11
+ title: "Welcome to Ext MVC",
12
+ html: "This is the <%= @name %> view which is found in <%= @filename %>."
13
+ });
14
+
15
+ Ext.Panel.prototype.initComponent.apply(this, arguments);
16
+ }
17
+ });
@@ -0,0 +1,7 @@
1
+
2
+ /**
3
+ * @action <%= @action_name %>
4
+ */
5
+ this.registerAction('<%= @action_name %>', function() {
6
+ this.renderView('<%= @action_name %>');
7
+ });
@@ -0,0 +1,152 @@
1
+ = ExtJS MVC Base App
2
+
3
+ Ext MVC Application structure for any new MVC application. Structure inspired by Ruby on Rails.
4
+
5
+ == Installation
6
+
7
+ Clone this as the starting point for your apps. Place your cloned directory somewhere apache can serve it, then head to index.html:
8
+
9
+ http://localhost/myDirectory/index.html
10
+
11
+ You should see a default application set up and ready to go.
12
+
13
+ == Prerequisites
14
+
15
+ Most prerequisites are installed for you inside the vendor directory:
16
+
17
+ * vendor/ext - contains a copy of ExtJS v2.2.1 (debug version, production copy by defaults comes off the cachefly CDN)
18
+ * vendor/mvc - contains a copy of the latest stable version of Ext MVC (debug and minified versions)
19
+ * vendor/screw-unit - contains a copy of ScrewUnit, a BDD testing framework for JavaScipt
20
+ * vendor/yui-compressor - contains a copy of the YUI compressor, which is used in the automatic build process
21
+
22
+ Although is is not strictly a prerequisite, you are *strongly* advised to install Ruby and Rubygems as the scripts below will automate a lot of things
23
+ for you and save you a lot of time. If you're running OSX you probably already have these, if you're on Windows it's a very simple install process.
24
+ Take a look at http://rubyonrails.org/download for instructions (just the Ruby and RubyGems sections).
25
+
26
+ If you don't intend to use the Ruby automation scripts, you can safely delete the script, vendor/mvc/scripts and vendor/yui-compressor folders.
27
+
28
+ == Getting Started
29
+
30
+ The only thing you need to change is the namespace your application will be using. Choose a meaningful namespace for your application - e.g. for
31
+ a blog application you might choose BlogApp, or something similar. All of your code will sit under that namespace, like this:
32
+
33
+ * BlogApp.models.Post // reference to a Post model constructor
34
+ * BlogApp.controllers.IndexController // reference to a controller constructor
35
+ * BlogApp.views.posts.New // reference to a view constructor, usually an Ext.Panel subclass
36
+
37
+ It doesn't matter if you don't know what those do yet, the important thing is that you don't pollute the global namespace. The whole of Ext MVC is
38
+ build around this idea.
39
+
40
+ Once you've chosen your namespace, just run the following command:
41
+
42
+ ruby script/setup MyAppNamespace
43
+
44
+ This will update all files with the default namespace ('MyApp') with the namespace you specify.
45
+
46
+ If you can't run the script, you can easily perform the setup yourself - just change the references from the default 'MyApp' namespace to your own
47
+ namespace in the following files:
48
+
49
+ * app/OS.js
50
+ * app/controllers/IndexController.js
51
+ * app/views/index/Index.js
52
+ * config/initialize.js
53
+ * config/settings.yml
54
+
55
+ Just use a simple find/replace all.
56
+
57
+ == Build tools
58
+
59
+ You need to ensure you have Ruby installed to use the build tools, and also the rake and hpricot gems (sudo gem install rake hpricot).
60
+
61
+ Ext MVC will automatically build (concatenate and minify) your javascript and CSS files. Just run the following command from the base directory:
62
+
63
+ ruby script/build all
64
+
65
+ This will inspect the javascript and css include tags inside index.html and compress them into a single JS file and a single CSS file. It will minify
66
+ the javascript if the YUI Compressor is installed in vendor/yui-compressor and create the following files:
67
+
68
+ * public/application-all.js
69
+ * public/application-all-min.js
70
+ * public/stylesheets/application-all.css
71
+
72
+ == Generators:
73
+
74
+ Ext MVC comes with some built-in generators to automate some aspects of application development. Run the generators
75
+ described below from within the main directory of your Ext MVC application.
76
+
77
+ Be sure that you have updated your config/settings.yml file before running these, otherwise everything will be namespaced
78
+ to 'MyApp' (see above).
79
+
80
+ === Model
81
+
82
+ ruby script/generate model User first_name:string last_name:string balance:int is_admin:boolean
83
+
84
+ Will generate the following files:
85
+
86
+ in app/models/User.js:
87
+ /**
88
+ * @class MyApp.models.MyModel
89
+ * @extends ExtMVC.Model
90
+ */
91
+ ExtMVC.Model.define("MyApp.models.User", {
92
+ modelName: 'user',
93
+ fields: [
94
+ {name: 'first_name', type: 'string'},
95
+ {name: 'last_name', type: 'string'},
96
+ {name: 'balance', type: 'int'},
97
+ {name: 'is_admin', type: 'boolean'}
98
+ ]
99
+ });
100
+
101
+ in spec/models/User.spec.js:
102
+ Screw.Unit(function() {
103
+ describe("The User class", function() {
104
+ var user;
105
+ before(function() {
106
+ user = new MyApp.models.User({
107
+ //set fields for this model here
108
+ });
109
+ });
110
+
111
+ //create your unit tests here
112
+ });
113
+ });
114
+
115
+ It will also add the following line to your index.html file:
116
+
117
+ <script type="text/javascript" src="app/models/User.js"></script>
118
+
119
+ And the following to your spec/index.html file:
120
+
121
+ <script type="text/javascript" src="../app/models/User.js"></script>
122
+ <script type="text/javascript" src="models/User.spec.js"></script>
123
+
124
+
125
+ == Deployment
126
+
127
+ Once you've built your app, upload only the 'public' folder to your web server. Nothing else is required to run the app.
128
+
129
+ == Directory Structure:
130
+
131
+ * app - a directory to contain your models, views and controllers
132
+ * app/controllers - contains all of your controllers
133
+ * app/models - contains all modesl
134
+ * app/views - contains all view files, usually in subdirectories (e.g. app/views/users/Index.js)
135
+ * config - contains application configuration files (see below)
136
+ * lib - contains any library files which are not suited to being plugins
137
+ * public - the directory you will set as document root on your web server. Place any public-facing assets in here. Note that all javascript and stylesheet files will be concatenated automatically into here when you deploy, so these can exist outside of this folder. Images and other assets will need to be placed here though.
138
+ * script - contains scripts to automate site build and minification
139
+ * spec - a directory to place your unit tests or specs
140
+ * vendor - holds any third-party code
141
+ * vendor/ext - contains the required version of ExtJS. ExtJS 2.2 comes pre-installed here, with the Ext adapter.
142
+ * vendor/mvc - contains the required version of Ext MVC. Most recent stable version installed by default. Obtain latest version from http://github.com/extmvc/extmvc/tree
143
+ * vendor/plugins - contains any MVC-compatible plugins (such as viewport builders, model extensions etc)
144
+
145
+ == Important Files:
146
+
147
+ * config/routes.js - set up any Ext.History related routing required (see file for help)
148
+ * config/initialize.js - any app-wide config code, such as setting up location of s.gif, booting your app, etc
149
+ * config/database.js - define which data adapter your app uses (RESTful adapter, Gears adapter, your own concoction etc)
150
+
151
+ * index.html - Development version of the site, including one file at a time and using ext-all-debug
152
+ * public/index.html - Production version of the site referencing concatenated and minified files
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @class MyApp.App
3
+ * @extends ExtMVC.App
4
+ * The MyApp application.
5
+ */
6
+
7
+ ExtMVC.App.define({
8
+ name : "MyApp",
9
+
10
+ /**
11
+ * Sets up the application's Viewport
12
+ */
13
+ launch: function() {
14
+
15
+ Ext.QuickTips.init();
16
+
17
+ this.menu = ExtMVC.buildView('layout', 'menu', {
18
+ region : 'west',
19
+ split: true,
20
+ width : 240,
21
+ listeners: {
22
+ scope: this,
23
+ click: function(node) {
24
+ var attrs = node.attributes;
25
+
26
+ if (attrs.controller != undefined) {
27
+ ExtMVC.dispatch({controller: attrs.controller, action: attrs.action});
28
+ }
29
+ }
30
+ }
31
+ });
32
+
33
+ /**
34
+ * @property main
35
+ * @type Ext.Panel
36
+ * A container into which views are rendered
37
+ */
38
+ this.main = new Ext.TabPanel({
39
+ region: 'center',
40
+ border: false,
41
+ cls : 'mainPanel',
42
+ activeTab: 0
43
+ });
44
+
45
+ this.viewport = new Ext.Viewport({
46
+ layout: 'border',
47
+ items: [{
48
+ xtype: 'box',
49
+ region: 'north',
50
+ height: 30
51
+ },this.menu, this.main
52
+ ]
53
+ });
54
+
55
+ this.fireEvent('launched');
56
+
57
+ ExtMVC.dispatch('home', 'index');
58
+
59
+ Ext.get('loading').remove();
60
+ Ext.get('loading-mask').fadeOut({remove:true});
61
+ }
62
+ });
63
+
64
+
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @class MyApp.controllers.ApplicationController
3
+ * @extends ExtMVC.controller.CrudController
4
+ * Shared application-wide controller. Place any application-specific code here that needs
5
+ * to be shared amongst other application controllers, and make the other controllers in the
6
+ * application extend this one
7
+ */
8
+ ExtMVC.registerController("application", {
9
+ extend: "controller"
10
+ });
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @class MyApp.controllers.IndexController
3
+ * @extends MyApp.controllers.ApplicationController
4
+ * Default root controller
5
+ */
6
+ ExtMVC.registerController("home", {
7
+ index: function() {
8
+ this.render('index');
9
+ }
10
+ });
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @class MyApp.views.home.Index
3
+ * @extends Ext.Panel
4
+ * Default Welcome to Ext MVC Panel - replace this with your own thing
5
+ */
6
+ ExtMVC.registerView('home', 'index', {
7
+ xtype: 'panel',
8
+
9
+ initComponent: function() {
10
+ Ext.applyIf(this, {
11
+ title: "Welcome to Ext MVC",
12
+ html: "This is the default template, which is found in app/views/home/Index.js. This is being displayed because your config/routes.js file has a map.root setting telling it to use the Index view of the HomeController"
13
+ });
14
+
15
+ Ext.Panel.prototype.initComponent.apply(this, arguments);
16
+ }
17
+ });