netzke-core 0.7.7 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. data/.travis.yml +1 -2
  2. data/CHANGELOG.md +572 -0
  3. data/LICENSE +7 -1
  4. data/README.md +345 -29
  5. data/Rakefile +3 -3
  6. data/app/controllers/netzke_controller.rb +37 -48
  7. data/config/ci/before-travis.sh +3 -4
  8. data/javascripts/base.js +86 -150
  9. data/javascripts/ext.js +180 -210
  10. data/javascripts/{core_extensions.js → js_extensions.js} +0 -0
  11. data/lib/netzke-core.rb +16 -6
  12. data/lib/netzke/base.rb +84 -107
  13. data/lib/netzke/core.rb +7 -41
  14. data/lib/netzke/core/action_config.rb +37 -0
  15. data/lib/netzke/core/actions.rb +123 -0
  16. data/lib/netzke/core/client_class.rb +252 -0
  17. data/lib/netzke/core/component_config.rb +12 -0
  18. data/lib/netzke/core/composition.rb +274 -0
  19. data/lib/netzke/core/config_to_dsl_delegator.rb +69 -0
  20. data/lib/netzke/core/configuration.rb +63 -0
  21. data/lib/netzke/core/css_config.rb +51 -0
  22. data/lib/netzke/core/dynamic_assets.rb +19 -49
  23. data/lib/netzke/{embedding.rb → core/embedding.rb} +4 -6
  24. data/lib/netzke/core/endpoint_response.rb +15 -0
  25. data/lib/netzke/core/javascript.rb +111 -0
  26. data/lib/netzke/core/panel.rb +11 -0
  27. data/lib/netzke/{plugins.rb → core/plugins.rb} +10 -5
  28. data/lib/netzke/core/railz.rb +4 -0
  29. data/lib/netzke/{railz → core/railz}/action_view_ext.rb +22 -18
  30. data/lib/netzke/core/railz/action_view_ext/ext.rb +49 -0
  31. data/lib/netzke/core/railz/controller_extensions.rb +17 -0
  32. data/lib/netzke/core/railz/engine.rb +16 -0
  33. data/lib/netzke/core/railz/routes.rb +10 -0
  34. data/lib/netzke/core/ruby_ext.rb +5 -0
  35. data/lib/netzke/core/ruby_ext/array.rb +23 -0
  36. data/lib/netzke/core/ruby_ext/hash.rb +47 -0
  37. data/lib/netzke/{core_ext → core/ruby_ext}/string.rb +2 -7
  38. data/lib/netzke/core/ruby_ext/symbol.rb +13 -0
  39. data/lib/netzke/{core_ext → core/ruby_ext}/time_with_zone.rb +0 -0
  40. data/lib/netzke/core/services.rb +130 -0
  41. data/lib/netzke/core/session.rb +15 -19
  42. data/lib/netzke/core/state.rb +40 -0
  43. data/lib/netzke/core/stylesheets.rb +48 -0
  44. data/lib/netzke/core/version.rb +2 -2
  45. data/lib/netzke/plugin.rb +8 -11
  46. data/netzke-core.gemspec +69 -59
  47. data/test/core_test_app/Gemfile +2 -20
  48. data/test/core_test_app/Gemfile.lock +65 -74
  49. data/test/core_test_app/app/components/card_component_loader.rb +4 -4
  50. data/test/core_test_app/app/components/component_loader.rb +40 -120
  51. data/test/core_test_app/app/components/component_loader/javascripts/component_loader.js +49 -0
  52. data/test/core_test_app/app/components/component_with_actions.rb +61 -47
  53. data/test/core_test_app/app/components/component_with_custom_css.rb +8 -5
  54. data/test/core_test_app/app/components/component_with_js_mixin.rb +11 -5
  55. data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_one.js +1 -1
  56. data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_two.js +1 -1
  57. data/test/core_test_app/app/components/component_with_js_mixin/javascripts/method_set_one.js +1 -1
  58. data/test/core_test_app/app/components/component_with_nested_through.rb +2 -2
  59. data/test/core_test_app/app/components/component_with_prebuilt_toolbar_control.rb +12 -0
  60. data/test/core_test_app/app/components/component_with_prebuilt_toolbar_control/javascripts/component_with_prebuilt_toolbar_control.js +12 -0
  61. data/test/core_test_app/app/components/component_with_required_js.rb +24 -0
  62. data/test/core_test_app/app/components/configurable_on_class_level.rb +8 -0
  63. data/test/core_test_app/app/components/dsl_delegated_properties.rb +4 -0
  64. data/test/core_test_app/app/components/dsl_delegated_properties_base.rb +5 -0
  65. data/test/core_test_app/app/components/dynamic_tab_panel/javascripts/dynamic_tab_panel.js +2 -2
  66. data/test/core_test_app/app/components/ext_direct/composite.rb +32 -33
  67. data/test/core_test_app/app/components/ext_direct/details.rb +2 -4
  68. data/test/core_test_app/app/components/ext_direct/selector.rb +20 -22
  69. data/test/core_test_app/app/components/ext_direct/statistics.rb +2 -4
  70. data/test/core_test_app/app/components/extended_component_with_actions.rb +7 -3
  71. data/test/core_test_app/app/components/extended_component_with_js_mixin.rb +7 -4
  72. data/test/core_test_app/app/components/extended_component_with_js_mixin/javascripts/some_method_set.js +1 -1
  73. data/test/core_test_app/app/components/extended_server_caller.rb +20 -14
  74. data/test/core_test_app/app/components/hello_world.rb +23 -0
  75. data/test/core_test_app/app/components/hello_world/javascripts/hello_world.js +12 -0
  76. data/test/core_test_app/app/components/included.js +2 -2
  77. data/test/core_test_app/app/components/kinda_complex_component.rb +1 -3
  78. data/test/core_test_app/app/components/kinda_complex_component/basic_stuff.rb +15 -17
  79. data/test/core_test_app/app/components/kinda_complex_component/extra_stuff.rb +4 -5
  80. data/test/core_test_app/app/components/loader_of_component_with_custom_css.rb +14 -5
  81. data/test/core_test_app/app/components/localized_panel.rb +23 -25
  82. data/test/core_test_app/app/components/multipane_component_loader.rb +19 -20
  83. data/test/core_test_app/app/components/nested_component.rb +4 -5
  84. data/test/core_test_app/app/components/panel_with_plugin.rb +8 -3
  85. data/test/core_test_app/app/components/panel_with_tools.rb +15 -14
  86. data/test/core_test_app/app/components/plugin_with_components.rb +20 -12
  87. data/test/core_test_app/app/components/scoped_components/deep_scoped_components/some_deep_scoped_component.rb +5 -2
  88. data/test/core_test_app/app/components/scoped_components/extended_scoped_component.rb +5 -2
  89. data/test/core_test_app/app/components/scoped_components/some_scoped_component.rb +5 -2
  90. data/test/core_test_app/app/components/server_caller.rb +39 -17
  91. data/test/core_test_app/app/components/server_caller/javascripts/server_caller.js +42 -0
  92. data/test/core_test_app/app/components/server_counter.rb +18 -82
  93. data/test/core_test_app/app/components/server_counter/javascripts/server_counter.js +53 -0
  94. data/test/core_test_app/app/components/simple_authentication_component.rb +46 -0
  95. data/test/core_test_app/app/components/simple_component.rb +8 -3
  96. data/test/core_test_app/app/components/simple_composite.rb +12 -0
  97. data/test/core_test_app/app/components/simple_form_with_file_upload.rb +49 -0
  98. data/test/core_test_app/app/components/simple_panel.rb +2 -2
  99. data/test/core_test_app/app/components/simple_tab_panel.rb +24 -3
  100. data/test/core_test_app/app/components/simple_window.rb +4 -2
  101. data/test/core_test_app/app/components/some_composite.rb +77 -48
  102. data/test/core_test_app/app/components/some_plugin.rb +31 -30
  103. data/test/core_test_app/app/components/stateful_component.rb +46 -0
  104. data/test/core_test_app/app/components/stateful_component_with_shared_state.rb +11 -0
  105. data/test/core_test_app/app/components/window_with_simple_component.rb +14 -0
  106. data/test/core_test_app/app/views/layouts/application.html.erb +1 -1
  107. data/test/core_test_app/app/views/simple_rails/multiple_nested.html.erb +7 -19
  108. data/test/core_test_app/app/views/simple_rails/panel.html.erb +1 -0
  109. data/test/core_test_app/config/database.yml.travis +3 -5
  110. data/test/core_test_app/config/environments/production.rb +1 -1
  111. data/test/core_test_app/config/initializers/netzke.rb +3 -1
  112. data/test/core_test_app/config/locales/en.yml +9 -4
  113. data/test/core_test_app/config/locales/es.yml +4 -2
  114. data/test/core_test_app/config/routes.rb +2 -8
  115. data/test/core_test_app/db/schema.rb +3 -11
  116. data/test/core_test_app/features/actions_and_tools.feature +1 -0
  117. data/test/core_test_app/features/client-server.feature +7 -0
  118. data/test/core_test_app/features/component_loader.feature +13 -13
  119. data/test/core_test_app/features/composition.feature +14 -0
  120. data/test/core_test_app/features/config_to_dsl_delegation.feature +10 -0
  121. data/test/core_test_app/features/file_inclusion.feature +1 -1
  122. data/test/core_test_app/features/i18n.feature +4 -4
  123. data/test/core_test_app/features/js_include.feature +1 -1
  124. data/test/core_test_app/features/persistence.feature +21 -5
  125. data/test/core_test_app/features/step_definitions/generic_steps.rb +14 -0
  126. data/test/core_test_app/features/support/paths.rb +0 -3
  127. data/test/core_test_app/public/images/icons/accept.png +0 -0
  128. data/test/core_test_app/public/images/icons/anchor.png +0 -0
  129. data/test/core_test_app/public/images/icons/tick.png +0 -0
  130. data/test/core_test_app/spec/action_config_spec.rb +15 -0
  131. data/test/core_test_app/spec/{component/actions_spec.rb → actions_spec.rb} +38 -36
  132. data/test/core_test_app/spec/base_spec.rb +35 -0
  133. data/test/core_test_app/spec/client_class_spec.rb +17 -0
  134. data/test/core_test_app/spec/component +0 -0
  135. data/test/core_test_app/spec/composition_spec.rb +118 -0
  136. data/test/core_test_app/spec/core_ext_spec.rb +3 -14
  137. data/test/core_test_app/spec/endpoint_response_spec.rb +17 -0
  138. data/test/core_test_app/spec/javascript_spec.rb +33 -0
  139. data/test/core_test_app/spec/js_class_config_scope.rb +37 -0
  140. data/test/core_test_app/spec/panel_spec.rb +11 -0
  141. data/test/core_test_app/spec/services_spec.rb +16 -0
  142. data/test/core_test_app/spec/state_spec.rb +20 -0
  143. data/test/unit/core_ext_test.rb +0 -53
  144. data/test/unit/netzke_core_test.rb +11 -11
  145. metadata +76 -62
  146. data/CHANGELOG.rdoc +0 -325
  147. data/javascripts/touch.js +0 -58
  148. data/lib/netzke/actions.rb +0 -107
  149. data/lib/netzke/composition.rb +0 -224
  150. data/lib/netzke/config_to_dsl_delegator.rb +0 -43
  151. data/lib/netzke/configuration.rb +0 -195
  152. data/lib/netzke/core/masquerading.rb +0 -34
  153. data/lib/netzke/core_ext.rb +0 -6
  154. data/lib/netzke/core_ext/array.rb +0 -30
  155. data/lib/netzke/core_ext/hash.rb +0 -86
  156. data/lib/netzke/core_ext/symbol.rb +0 -21
  157. data/lib/netzke/ext_component.rb +0 -25
  158. data/lib/netzke/inheritance.rb +0 -31
  159. data/lib/netzke/javascript.rb +0 -382
  160. data/lib/netzke/javascript/scopes.rb +0 -39
  161. data/lib/netzke/railz.rb +0 -4
  162. data/lib/netzke/railz/action_view_ext/ext.rb +0 -64
  163. data/lib/netzke/railz/action_view_ext/touch.rb +0 -52
  164. data/lib/netzke/railz/controller_extensions.rb +0 -33
  165. data/lib/netzke/railz/engine.rb +0 -48
  166. data/lib/netzke/railz/routes.rb +0 -7
  167. data/lib/netzke/services.rb +0 -101
  168. data/lib/netzke/session.rb +0 -54
  169. data/lib/netzke/state.rb +0 -91
  170. data/lib/netzke/stylesheets.rb +0 -65
  171. data/test/core_test_app/app/components/component_with_included_js.rb +0 -16
  172. data/test/core_test_app/app/components/component_with_session_persistence.rb +0 -35
  173. data/test/core_test_app/app/components/deprecated/server_caller.rb +0 -20
  174. data/test/core_test_app/app/components/dynamic_tab_panel.rb +0 -19
  175. data/test/core_test_app/app/components/hello_world_component.rb +0 -31
  176. data/test/core_test_app/app/components/touch/hello_world_component.rb +0 -25
  177. data/test/core_test_app/app/components/touch/server_caller.rb +0 -28
  178. data/test/core_test_app/app/components/touch/simple_carousel.rb +0 -17
  179. data/test/core_test_app/app/controllers/touch_controller.rb +0 -6
  180. data/test/core_test_app/app/helpers/touch_helper.rb +0 -2
  181. data/test/core_test_app/app/views/layouts/touch.html.erb +0 -13
  182. data/test/core_test_app/db/migrate/20110110132720_create_netzke_component_states.rb +0 -20
  183. data/test/core_test_app/features/step_definitions/touch_steps.rb +0 -3
  184. data/test/core_test_app/features/touch.feature +0 -10
  185. data/test/core_test_app/gemfiles/rails3_1.gemfile +0 -16
  186. data/test/core_test_app/gemfiles/rails3_2.gemfile +0 -16
  187. data/test/core_test_app/spec/component/base_spec.rb +0 -36
  188. data/test/core_test_app/spec/component/component_spec.rb +0 -20
  189. data/test/core_test_app/spec/component/composition_spec.rb +0 -132
  190. data/test/core_test_app/spec/component/configuration_spec.rb +0 -61
  191. data/test/core_test_app/spec/component/javascript_spec.rb +0 -16
  192. data/test/core_test_app/spec/component/state_spec.rb +0 -18
data/LICENSE CHANGED
@@ -1 +1,7 @@
1
- Copyright (c) 2009 Sergei Kozlov, released under the MIT license
1
+ Copyright (c) 2012 netzke
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,54 +1,370 @@
1
- # Netzke Core
1
+ # Netzke Core [![Build Status](https://secure.travis-ci.org/nomadcoder/netzke-core.png?branch=master)](http://travis-ci.org/nomadcoder/netzke-core) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/netzke/netzke-core)
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/skozlov/netzke-core.png?branch=master)](http://travis-ci.org/skozlov/netzke-core)
3
+ [RDocs](http://rdoc.info/projects/netzke/netzke-core)
4
4
 
5
- Netzke Core is the bare bones of the [Netzke framework](https://github.com/nomadcoder/netzke). For pre-built full-featured components (like grids, forms, tab/accordion panels, applications, etc), see [netzke-basepack](http://github.com/nomadcoder/netzke-basepack) (Ext JS).
5
+ Netzke Core is the bare bones of the [Netzke framework](http://netzke.org). For pre-built full-featured components (like grids, forms, tab/accordion panels, etc), see [netzke-basepack](http://github.com/netzke/netzke-basepack) and [netzke-communitypack](http://github.com/netzke/netzke-communitypack).
6
+
7
+ Some knowledge of Sencha Ext JS will be needed in order to fully understand this overview.
8
+
9
+ ## Rationale
10
+
11
+ [Sencha Ext JS]("http://www.sencha.com/products/extjs") is a powerful front-end framework, which is used for crafting web-apps that give the end user experience similar to that of a desktop application. It has an extensive set of widgets ('components'), and leverages a modular approach to its fullest: a developer can extend components (using Ext JS's own [class system]("http://docs.sencha.com/ext-js/4-1/#!/guide/class_system")), nest components using many powerful layouts, dynamically create and destroy them. The architecture of Ext JS is well-thought and very complete.
12
+
13
+ However, with Ext JS being server-agnostic, it is not always a trivial task for a developer to bind Ext JS components to the server-side data *and* application business logic, especially in complex applications. Netzke as the solution that allows you to extend the modular approach to the server side.
6
14
 
7
15
  Netzke Core takes the burden of implementing the following key aspects of the framework:
8
16
 
9
- * JavaScript class generation
17
+ * Client-side (JavaScript) class generation
10
18
  * Client-server communication
11
- * Extendibility of components (with OOP, in both Ruby and JavaScript)
19
+ * Convenient declaration of Ext actions
20
+ * Extendibility of components (class inheritance and mixins)
12
21
  * Unlimited nesting (composition)
13
22
  * Dynamic component loading
14
- * JavaScript class caching
15
- * Inclusion of “external” JavaScript CSS files
16
- * ... and more
23
+ * Client-side class caching
24
+ * Inclusion of extra JavaScript and CSS files
25
+
26
+ ...and more.
27
+
28
+ All this extremely facilitates building fast, low-traffic, robust, and highly maintainable applications. As a result, your code scales much better in the sense of complexity, compared to using conventional MVC, where developers are pretty much limited with programming techniques they can apply.
29
+
30
+ ## HelloWorld component
31
+
32
+ *This component is distributed as a part of the test application, see `test/core_test_app/components`.*
33
+
34
+ In `YOUR_APP/components/hello_world.rb`:
35
+
36
+ ```ruby
37
+ class HelloWorld < Netzke::Base
38
+ # Configure client class
39
+ js_configure do |c|
40
+ c.title = "Hello World component"
41
+ c.mixin # mix in methods from hello_world/javascripts/hello_world.js
42
+ end
43
+
44
+ # Actions are used by Ext JS to share functionality and state b/w buttons and menu items
45
+ # The handler for this action should be called onPingServer by default
46
+ action :ping_server
47
+
48
+ # Self-configure with a bottom toolbar
49
+ def configure(c)
50
+ super
51
+ c.bbar = [:ping_server] # embed the action into bottom toolbar as a button
52
+ end
53
+
54
+ # Endpoint callable from client class
55
+ endpoint :greet_the_world do |params,this|
56
+ # call client class' method showGreeting
57
+ this.show_greeting("Hello World!")
58
+ end
59
+ end
60
+ ```
61
+
62
+ In `YOUR_APP/components/hello_world/javascripts/hello_world.js` put the client class (JavaScript) methods:
63
+
64
+ ```javascript
65
+ {
66
+ // handler for the ping_server action
67
+ onPingServer: function(){
68
+ // calling greet_the_world endpoint
69
+ this.greetTheWorld();
70
+ },
71
+
72
+ // called by the server as the result of executing the endpoint
73
+ showGreeting: function(greeting){
74
+ this.update("Server says: " + greeting);
75
+ }
76
+ }
77
+ ```
78
+
79
+ To embed the component in Rails view:
80
+
81
+ Add `netzke` routes:
82
+
83
+ ```ruby
84
+ # in routes.rb
85
+ RailsApp::Application.routes.draw do
86
+ netzke
87
+ ...
88
+ end
89
+ ```
90
+
91
+ Use `load_netzke` in the layout to include Ext JS and Netzke scripts and stylesheets:
92
+
93
+ ```erb
94
+ <!DOCTYPE html>
95
+ <html>
96
+ <head>
97
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
98
+ <%= csrf_meta_tag %>
99
+ <%= load_netzke %>
100
+ </head>
101
+ <body>
102
+ <%= yield %>
103
+ </body>
104
+ </html>
105
+ ```
106
+
107
+ Embed the component in the Rails view:
108
+
109
+ ```erb
110
+ <%= netzke :hello_world %>
111
+ ```
112
+
113
+ ## What is a Netzke component
114
+
115
+ A Netzke component is a Ruby class (further referred to as "server class"), which is being represented by an Ext JS Component on the server-side (further referred to as "client class"). The responsibility of the server class is to "assemble" the client class and provide the configuration for its instance (further referred as "client class instance"). Even if it may sound a bit complicated, Netzke provides a simple API for defining and configuring the client class. See [Client class](#client-class) for details.
116
+
117
+ Further, each Netzke component inherits convenient API for enabling the communication between the client and server class. See [Client-server interaction](#client-server-interaction) for details.
118
+
119
+ With Netzke components being a Ruby class, and the client class being *incapsulated* in it, it is possible to use a Netzke component in your application by simply writing Ruby code. However, while creating a component, developers can fully use their Ext JS skills - Netzke puts no obstacles here.
120
+
121
+ A typical Netzke component's code is structured like this (on example of MyComponent):
122
+
123
+ ```
124
+ your_web_app
125
+ app
126
+ components
127
+ my_component.rb <-- the Ruby class
128
+ my_component
129
+ some_module.rb <-- optional extra Ruby code
130
+ javascripts
131
+ some_dependency.js <-- optional external JS library
132
+ init_component.js <-- optional mixins to the client class
133
+ extra_functionality.js <-- more mixins (mixin-in may depend on component class configuration)
134
+ stylesheets
135
+ my_special_button.css <-- optional custom CSS
136
+ ```
137
+
138
+ ## Client class
139
+
140
+ The generated client class is *inherited* (as defined by the Ext JS [class system]("http://docs.sencha.com/ext-js/4-1/#!/guide/class_system")) from an Ext JS class, which by default is [Ext.panel.Panel]("http://docs.sencha.com/ext-js/4-1/#!/api/Ext.panel.Panel"). For example, a component defined like this:
141
+
142
+ ```ruby
143
+ class HelloWorld < Netzke::Base
144
+ end
145
+ ```
146
+
147
+ will have the following client class generated by Netzke (simplified):
148
+
149
+ ```javascript
150
+ Ext.define('Netzke.classes.HelloWorld', {"extend":"Ext.panel.Panel", "mixins":["Netzke.classes.Core.Mixin"]});
151
+ ```
152
+
153
+ `Netzke.classes.Core.Mixin` contains a set of client class methods and properties common to every Netzke component.
154
+
155
+ Extending `HelloWorld` will be automatically reflected on the client-class level:
156
+
157
+ ```ruby
158
+ class HelloNewWorld < HelloWorld
159
+ end
160
+ ```
161
+
162
+ will have the following client class generated (simplified):
163
+
164
+ ```javascript
165
+ Ext.define('Netzke.classes.HelloNewWorld', {"extend":"Netzke.classes.HelloWorld"});
166
+ ```
167
+
168
+ The configuration of a client-class is done by using the `Netzke::Base.js_configure`. For example, in order to inherit from a different Ext JS component, and to mix in the methods defined in an external JavaScript class:
169
+
170
+ ```ruby
171
+ class MyTabPanel < Netzke::Base
172
+ js_configure do |c|
173
+ c.extend = "Ext.tab.Panel"
174
+ c.mixin :extra_functionality
175
+ end
176
+ end
177
+ ```
178
+
179
+ For more details on defining the client class, refer to [Netzke::Core::ClientClass](http://rdoc.info/github/netzke/netzke-core/Netzke/Core/ClientClass).
180
+
181
+ ## Composition
182
+
183
+ Any Netzke component can define child components, which can either be statically nested in the compound layout (e.g. as different regions of the ['border' layout]("http://docs.sencha.com/ext-js/4-1/#!/api/Ext.layout.container.Border")), or dynamically loaded at a request (as in the case of the edit form window in `Netzke::Basepack::GridPanel`, for example).
184
+
185
+ ### Defining child components
186
+
187
+ You can define a child component by calling the `component` class method which normally requires a block:
188
+
189
+ ```ruby
190
+ component :users do |c|
191
+ c.klass = GridPanel
192
+ c.model = "User"
193
+ c.title = "Users"
194
+ end
195
+ ```
196
+
197
+ ### Nesting components
198
+
199
+ Declared components can be referred to in the component layout:
200
+
201
+ ```ruby
202
+ def configure(c)
203
+ super
204
+ c.items = [
205
+ { xtype: :panel, title: "Simple Ext panel" },
206
+ :users
207
+ ]
208
+ end
209
+ ```
210
+
211
+ ### Dynamic loading of components
212
+
213
+ Next to being statically nested in the layout, a child component can also be dynamically loaded by using client class' `netzkeLoadComponent` method:
17
214
 
18
- All this provides for fast, low-traffic, robust, highly maintainable applications.
215
+ this.netzkeLoadComponent('users');
216
+
217
+ this will load the "users" component and [add](http://docs.sencha.com/ext-js/4-1/#!/api/Ext.container.Container-method-add) it to the current container.
218
+
219
+ For more details on dynamic component loading refer to inline docs of [javascript/ext.js](https://github.com/netzke/netzke-core/blob/master/javascripts/ext.js).
220
+
221
+ For more details on composition refer to [Netzke::Core::Composition](http://rdoc.info/github/netzke/netzke-core/Netzke/Core/Composition).
222
+
223
+ ## Actions, toolbars, and menus
224
+
225
+ Actions are [used by Ext JS]("http://docs.sencha.com/ext-js/4-1/#!/api/Ext.Action") to share functionality and state among multiple buttons and menu items. Define actions with the `action` class method:
226
+
227
+ ```ruby
228
+ action :show_report do |c|
229
+ c.text = "Show report"
230
+ c.icon = :report
231
+ end
232
+ ```
233
+
234
+ The icon for this button will be `images/icons/report.png` (see [Icons support](#icons-support)).
235
+
236
+ Refer to actions in toolbars:
237
+
238
+ ```ruby
239
+ def configure(c)
240
+ super
241
+ c.bbar = [:show_report]
242
+ end
243
+ ```
244
+
245
+ Actions can also be referred to is submenus:
246
+
247
+ ```ruby
248
+ c.tbar = [{text: 'Menu', menu: {items: [:show_report]}}]
249
+ ```
250
+
251
+ For more details on composition refer to [Netzke::Core::Action](http://rdoc.info/github/netzke/netzke-core/Netzke/Core/Action).
252
+
253
+ ## Client-server interaction
254
+
255
+ Communication between the client class and the corresponding server class is done by means of defining *endpoints*. By defining an endpoint on the server, the client class automatically gets a method that is used to call the server.
256
+
257
+ ### Calling an endpoint from client class
258
+
259
+ By defining an endpoint like this:
260
+
261
+ ```ruby
262
+ class SimpleComponent < Netzke::Base
263
+ endpoint :whats_up_server do |params, this|
264
+ # ...
265
+ end
266
+ end
267
+ ```
268
+
269
+ ...the client class will obtain a method called `whatsUpServer`:
270
+
271
+ ```javascript
272
+ this.whatsUpServer(params, callback, scope);
273
+ ```
274
+
275
+ Parameters:
276
+
277
+ * `params` will be passed to the endpoint block as the first parameter
278
+ * `callback` (optional) receives a function to be called after the server successfully processes the endpoint call
279
+ * `scope` (optional) is the scope in which the callback function will be called
280
+
281
+ ### Calling client class methods from endpoint
282
+
283
+ An endpoint can instruct the client class to execute a set of methods after its execution, passing those methods arbitrary parameters. For example:
284
+
285
+ ```ruby
286
+ class SimpleComponent < Netzke::Base
287
+ endpoint :whats_up_server do |params, this|
288
+ this.set_title("All quiet here on the server")
289
+ this.my_method
290
+ end
291
+ end
292
+ ```
293
+
294
+ Here the client class will call its `setTitle` method (defined in `Ext.panel.Panel`) with parameter passed from the endpoint. Then a custom method `myMethod` will be called with no parameters.
295
+
296
+ For more details on client-server communication see [Netzke::Core::Services]("http://rdoc.info/github/netzke/netzke-core/Netzke/Core/Services").
297
+
298
+ ## Icons support
299
+
300
+ Netzke can optionally make use of icons for making clickable elements like buttons and menu items more visual. The icons should be (by default) located in `public/images/icons`.
301
+
302
+ An example of specifying an icon for an action:
303
+
304
+ ```ruby
305
+ action :logout do |c|
306
+ c.icon = :door
307
+ end
308
+ ```
309
+
310
+ The logout action will be configured with `public/images/icons/door.png` as icon.
311
+
312
+ For more details on using icons refer to [Netzke::Core::Actions]("http://rdoc.info/github/netzke/netzke-core/Netzke/Core/Actions").
313
+
314
+ ## I18n
315
+
316
+ Netzke Core will automatically include Ext JS localization files based on current `I18n.locale`.
317
+
318
+ Also, Netzke Core uses some conventions for localizing actions. Refer to [Netzke::Core::Actions](http://rdoc.info/github/netzke/netzke-core/Netzke/Core/Actions).
19
319
 
20
320
  ## Requirements
21
321
 
22
322
  * Ruby ~> 1.9.2
23
- * Rails ~> 3.1.0
323
+ * Rails ~> 3.2.0
24
324
  * Ext JS ~> 4.1.0
25
325
 
26
- ## Getting started
326
+ ## Installation
327
+
328
+ $ gem install netzke-core
329
+
330
+ For the latest ("edge") stuff, instruct the bundler to get the gem straight from github:
331
+
332
+ ```ruby
333
+ gem 'netzke-core', git: "git://github.com/netzke/netzke-core.git"
334
+ ```
27
335
 
28
- * Follow the simple [installation](https://github.com/nomadcoder/netzke-core/wiki/Installation) steps.
29
- * Learn how to build the [Hello World!](https://github.com/nomadcoder/netzke-core/wiki/Hello-world-extjs) component.
30
- * Dive into the [documentation](https://github.com/nomadcoder/netzke/wiki).
31
- * Get help on the [Google Groups](http://groups.google.com/group/netzke).
336
+ By default, Netzke assumes that your Ext JS library is located in public/extjs. It can be a symbolic link, e.g.:
32
337
 
33
- ## Testing and playing with Netzke Core
338
+ $ ln -s ~/code/sencha/ext-4.1.1 public/extjs
34
339
 
35
- Netzke Core is bundled with Cucumber and RSpec tests. If you would like to contribute to the project, you may want to learn how to [run the tests](https://github.com/nomadcoder/netzke-core/wiki/Automated-testing).
340
+ *(Make sure that the location of the license.txt distributed with Ext JS is exactly `public/extjs/license.txt`)*
36
341
 
37
- Besides, the bundled test application is a convenient [playground](https://github.com/nomadcoder/netzke-core/wiki/Playground) for those who search to experiment with the framework.
342
+ ## Running tests
343
+
344
+ The bundled `test/core_test_app` application used for automated testing can be easily run as a stand-alone Rails app. It's a good source of concise, focused examples. After starting the application, access any of the test components (located in `app/components`) by using the following url:
345
+
346
+ http://localhost:3000/components/{name of the component's class}
347
+
348
+ For example [http://localhost:3000/components/ServerCaller](http://localhost:3000/components/ServerCaller)
349
+
350
+ Before being able run the test app and the tests themselves, you must link your Ext JS library to `test/core_test_app/public`, e.g. (from the gems's root):
351
+
352
+ $ ln -s ~/code/sencha/ext-4.1.1 test/core_test_app/public/extjs
353
+
354
+ For cucumber tests (from `test/core_test_app`):
355
+
356
+ $ cucumber features
357
+
358
+ For RSpec tests (from `test/core_test_app`):
359
+
360
+ $ rspec spec
38
361
 
39
362
  ## Useful links
40
363
  * [Project website](http://netzke.org)
41
- * [Documentation](https://github.com/nomadcoder/netzke/wiki)
42
- * [Live-demo](http://demo.netzke.org) (features [Netzke Basepack](https://github.com/nomadcoder/netzke-basepack), with sample code)
364
+ * [Live demo](http://netzke-demo.herokuapp.com) (features [Netzke Basepack](https://github.com/netzke/netzke-basepack), with sample code)
43
365
  * [Twitter](http://twitter.com/netzke) - latest news about the framework
44
- * [Author's twitter](http://twitter.com/nomadcoder) - author's rambling about OS X, productivity, lifestyle, and what not
45
-
46
- ## Ext 3 support
47
- Versions 0.6.x are for you if you're using Ext 3 (*hardly maintained*)
48
-
49
- ## Rails 2 support
50
- With Rails 2 (and Ext 3 only), use versions 0.5.x (*not maintained*)
51
366
 
52
367
  ---
53
- Copyright (c) 2008-2011 NomadCoder, released under the MIT license
54
- Note, that Ext JS itself is licensed [differently](http://www.sencha.com/products/extjs/license/)
368
+ Copyright (c) 2008-2012 [netzke](https://twitter.com/netzke), released under the MIT license (see LICENSE).
369
+
370
+ **Note** that Ext JS is licensed [differently](http://www.sencha.com/products/extjs/license/), and you may need to purchase a commercial license in order to use it in your projects!
data/Rakefile CHANGED
@@ -4,8 +4,8 @@ begin
4
4
  Jeweler::Tasks.new do |gemspec|
5
5
  gemspec.version = Netzke::Core::Version::STRING
6
6
  gemspec.name = "netzke-core"
7
- gemspec.summary = "Build complex Sencha Ext JS Ruby on Rails components with minimum effort"
8
- gemspec.description = "Allows building DRY Sencha Ext JS Ruby on Rails applications by enabling modular development"
7
+ gemspec.summary = "Client-server GUI components with Sencha Ext JS and Ruby"
8
+ gemspec.description = "Allows building complex RIA by greatly facilitating modular development"
9
9
  gemspec.email = "nmcoder@gmail.com"
10
10
  gemspec.homepage = "http://netzke.org"
11
11
  gemspec.authors = ["nomadcoder"]
@@ -31,7 +31,7 @@ begin
31
31
  end
32
32
 
33
33
  namespace :yard do
34
- desc "Publish docs"
34
+ desc "Publish docs to api.netzke.org"
35
35
  task publish: :yard do
36
36
  dir = 'www/api.netzke.org/core'
37
37
  puts "Publishing to fl:#{dir}..."
@@ -1,5 +1,4 @@
1
1
  class NetzkeController < ApplicationController
2
-
3
2
  # Action for Ext.Direct RPC calls
4
3
  def direct
5
4
  result=""
@@ -10,9 +9,9 @@ class NetzkeController < ApplicationController
10
9
  begin
11
10
  result += invoke_endpoint(batch[:act], batch[:method].underscore, batch[:data].first, batch[:tid])
12
11
  rescue Exception => e
13
- Rails.logger.error "!!! Netzke: Error invoking endpoint: #{batch[:act]} #{batch[:method].underscore} #{batch[:data].inspect} #{batch[:tid]}\n"
14
- Rails.logger.error e.message
15
- Rails.logger.error e.backtrace.join("\n")
12
+ logger.error "!!! Netzke: Error invoking endpoint: #{batch[:act]} #{batch[:method].underscore} #{batch[:data].inspect} #{batch[:tid]}\n"
13
+ logger.error e.message
14
+ logger.error e.backtrace.join("\n")
16
15
  error=true
17
16
  break;
18
17
  end
@@ -24,12 +23,7 @@ class NetzkeController < ApplicationController
24
23
  render :text => result, :layout => false, :status => error ? 500 : 200
25
24
  end
26
25
 
27
- # Action used by non-Ext.Direct (Touch) components
28
- def dispatcher
29
- endpoint_dispatch(params[:address])
30
- end
31
-
32
- # Used in development mode for on-the-fly generation of public/netzke/ext.[js|css]
26
+ # On-the-fly generation of public/netzke/ext.[js|css]
33
27
  def ext
34
28
  respond_to do |format|
35
29
  format.js {
@@ -42,51 +36,46 @@ class NetzkeController < ApplicationController
42
36
  end
43
37
  end
44
38
 
45
- # Used in development mode for on-the-fly generation of public/netzke/touch.[js|css]
46
- def touch
47
- respond_to do |format|
48
- format.js {
49
- render :text => Netzke::Core::DynamicAssets.touch_js
50
- }
51
-
52
- format.css {
53
- render :text => Netzke::Core::DynamicAssets.touch_css
54
- }
55
- end
39
+ # Old-way action used at multi-part form submission (endpointUrl)
40
+ def dispatcher
41
+ endpoint_dispatch(params[:address])
56
42
  end
57
43
 
58
- protected
59
- def invoke_endpoint(endpoint_path, action, params, tid) #:nodoc:
60
- component_name, *sub_components = endpoint_path.split('__')
61
- components_in_session = Netzke::Core.session[:netzke_components]
44
+ protected
62
45
 
63
- if components_in_session
64
- component_instance = Netzke::Base.instance_by_config(components_in_session[component_name.to_sym])
65
- result = component_instance.invoke_endpoint((sub_components + [action]).join("__"), params)
66
- else
67
- result = {:component_not_in_session => true}.to_nifty_json
68
- end
46
+ def invoke_endpoint(endpoint_path, action, params, tid)
47
+ component_name, *sub_components = endpoint_path.split('__')
48
+ components_in_session = session[:netzke_components]
69
49
 
70
- {
71
- :type => "rpc",
72
- :tid => tid,
73
- :action => component_name,
74
- :method => action,
75
- :result => result.present? && result.l || {}
76
- }.to_json
50
+ if components_in_session
51
+ component_instance = Netzke::Base.instance_by_config(components_in_session[component_name.to_sym])
52
+ result = component_instance.invoke_endpoint((sub_components + [action]).join("__"), params).to_nifty_json
53
+ else
54
+ result = {:netzke_component_not_in_session => true}.to_nifty_json
77
55
  end
78
56
 
79
- # Main dispatcher of old-style (Sencha Touch) HTTP requests. The URL contains the name of the component,
80
- # as well as the method of this component to be called, according to the double underscore notation.
81
- # E.g.: some_grid__post_grid_data.
82
- def endpoint_dispatch(endpoint_path)
83
- component_name, *sub_components = endpoint_path.split('__')
84
- component_instance = Netzke::Base.instance_by_config(Netzke::Core.session[:netzke_components][component_name.to_sym])
57
+ # We render text/plain, so that the browser never modifies our response
58
+ response.headers["Content-Type"] = "text/plain; charset=utf-8"
85
59
 
86
- # We render text/plain, so that the browser never modifies our response
87
- response.headers["Content-Type"] = "text/plain; charset=utf-8"
60
+ { :type => "rpc",
61
+ :tid => tid,
62
+ :action => component_name,
63
+ :method => action,
64
+ :result => result.present? && result.l || {}
65
+ }.to_json
66
+ end
88
67
 
89
- render :text => component_instance.invoke_endpoint(sub_components.join("__"), params), :layout => false
90
- end
68
+ # The dispatcher for the old-style requests (used for multi-part form submission). The URL contains the name of the component,
69
+ # as well as the method of this component to be called, according to the double underscore notation.
70
+ # E.g.: some_grid__post_grid_data.
71
+ def endpoint_dispatch(endpoint_path)
72
+ component_name, *sub_components = endpoint_path.split('__')
73
+ component_instance = Netzke::Base.instance_by_config(session[:netzke_components][component_name.to_sym])
74
+
75
+ # We can't do this here; this method is only used for classic form submission, and the response from the server should be the (default) "text/html"
76
+ # response.headers["Content-Type"] = "text/plain; charset=utf-8"
77
+
78
+ render :text => component_instance.invoke_endpoint(sub_components.join("__"), params).to_nifty_json, :layout => false
79
+ end
91
80
 
92
81
  end