opalla 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 809e267708644b22d52a983becd190cc66156859
4
- data.tar.gz: c37af2cbd9a4c8503e3d31b528b507fdd41abe6f
3
+ metadata.gz: b420c0145b5c3f9a19e09a13662039babd80df2f
4
+ data.tar.gz: 9aad2ce70fb5d1b98fc5039c4dbe3c727e2e63e3
5
5
  SHA512:
6
- metadata.gz: 0ea42241f2f4bcd4c1a71bf58a35cd5e8a70cec469cdc08c8c046fa2e8349cd03eda1aebc0c47774774c3220dc3560e7fc459a60d68a39db9f2b5e44a24899d1
7
- data.tar.gz: 58c9f272c6cfa541268dc8317f630b4a5109d07f68f1cd8284c5a76cac041c0dfed3267954b8ccffb5839c307c2007aeb9de4ec55e4b9aa4da35dacc3f11d49a
6
+ metadata.gz: a1ff2aeb30b377ffcbc3718b73642be5338251088750a588ebebc6d9db4aca5cad6ea9a51c1c8b8108d93df15a7c148010bf06b5120a3a1844ba751a52093fbe
7
+ data.tar.gz: 5a83dc76cdfaee6cfc9b0359dbcd981c5273c2748835ef1c405e13b50f14adee079a2049229c358ca8b489b34a9840bc7ca7e36de19bafd381d9ccf36ef7a9a8
data/README.md CHANGED
@@ -1,41 +1,421 @@
1
1
  # Opalla
2
+ ![Opalla](opalla.gif)
2
3
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/opalla`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+ Opalla brings Rails way to the front-end. It follows a Rails conventions mixed with a little of Backbone.
4
5
 
5
- TODO: Delete this and the text above, and describe your gem
6
+ It's built on top of `opal` and `opal-rails`.
6
7
 
7
8
  ## Installation
8
-
9
9
  Add this line to your application's Gemfile:
10
10
 
11
11
  ```ruby
12
+ gem 'opal-rails'
12
13
  gem 'opalla'
13
14
  ```
14
15
 
16
+ Additionally, if you want to use `haml`, add:
17
+
18
+ ```ruby
19
+ gem 'opal-haml'
20
+ ```
21
+ (That's actually ultra-highly recommended)
22
+
15
23
  And then execute:
16
24
 
17
- $ bundle
25
+ ```
26
+ $ bundle
27
+ ```
28
+
29
+ Then run:
30
+
31
+ ```sh
32
+
33
+ rails g opalla:install
34
+
35
+ ```
36
+
37
+ Opalla is a front-end MVC framework. So you will to have this folder structure:
18
38
 
19
- Or install it yourself as:
39
+ ```
40
+ your_app
41
+ \_app
42
+ \_assets
43
+ \_javascripts
44
+ \_components
45
+ \_controllers
46
+ \_lib
47
+ \_collections
48
+ \_models
49
+ \_views
50
+ ```
20
51
 
21
- $ gem install opalla
52
+ And that’s it! You’re ready to drive Opalla.
22
53
 
23
54
  ## Usage
24
55
 
25
- TODO: Write usage instructions here
56
+ ### Router & Controllers
57
+ It all starts with the Opalla router. It will catch the current URL and direct to the controller/action, exactly like Rails does.
26
58
 
27
- ## Development
59
+ So for example, say you have the following route:
60
+
61
+ ```ruby
62
+ get 'pages#index'
63
+ ```
28
64
 
29
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
65
+ You can generate controllers by running the default Rails controller generator:
30
66
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
67
+ ```sh
32
68
 
33
- ## Contributing
69
+ rails g controller pages
34
70
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/opalla. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
71
+ ```
36
72
 
73
+ If you just installed Opalla on your existing app and want to generate Opalla controllers for it, just re-run the command above and leave Rails do the rest! (It won't overwrite anything unless you explicitly ask for).
37
74
 
38
- ## License
75
+ `Opalla::Router` will automatically import the routes and instantiate the `PagesController` inside your `javascripts/controller/pages_controller.rb` and trigger the `index` action:
39
76
 
40
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
77
+ ```ruby
78
+
79
+ class PagesController < ApplicationController
80
+
81
+ def index
82
+ el.html 'Hello World!'
83
+ end
84
+
85
+ end
86
+ ```
87
+
88
+ That would replace the `<body>` tag with 'Hello World', as the default `el` for a controller. If you want to change that, you can add `el 'YOU_SELECTOR_HERE'`, in a jQuery selector fashion. So for example:
89
+
90
+ ```ruby
91
+
92
+ class PagesController < ApplicationController
93
+ el '.main-content'
94
+
95
+ def index
96
+ el.html 'Hello World!'
97
+ end
98
+
99
+ end
100
+ ```
101
+
102
+ ### Templates
103
+ Your Opalla templates will live under `app/assets/javascripts/views`. There you have `./controllers` and `./components`. Note that components templates should start their names with `_`, just like `partials`.
104
+
105
+ Opalla will automatically have your templates folder added to your server side (Rails). So that means your templates will be rendered server-side and client-side. Yay!
106
+
107
+ The template will be able to get any access variables (`@variable`) and `methods`. Please note that you have to have both set on server and client sides.
108
+
109
+ Server-side:
110
+
111
+ ```ruby
112
+
113
+ class PagesController < ApplicationController
114
+ helper_method :something_awesome
115
+
116
+ def index
117
+ @dude = 'Pedro'
118
+ end
119
+
120
+ def something_awesome
121
+ 'Rails'
122
+ end
123
+
124
+ end
125
+
126
+ ```
127
+
128
+ Client-side, note that all methods are available by default, no need to set them as `helper_methods`:
129
+
130
+ ```ruby
131
+
132
+ class PagesController < ApplicationController
133
+ el '.main-content'
134
+
135
+ def index
136
+ @dude = 'Pedro'
137
+ render
138
+ end
139
+
140
+ def something_awesome
141
+ 'Rails'
142
+ end
143
+
144
+ end
145
+ ```
146
+
147
+ The following `haml` layout would work for both sides:
148
+
149
+ ```haml
150
+
151
+ %main
152
+ The dude is called #{@dude}.
153
+ He works with #{something_awesome}
154
+
155
+ ```
156
+
157
+ If you want to share variables with your front-end Opalla MVC, that’s ok. Use the `expose` method automatically available on your server-side controllers:
158
+
159
+ ```ruby
160
+
161
+ def index
162
+ expose message: 'Hello World!',
163
+ my_array: [1,2,3]
164
+ end
165
+
166
+ ```
167
+
168
+ And then you can use the data normally in your views:
169
+
170
+ ```haml
171
+ %p= message
172
+ %p= my_array.join('/')
173
+ ```
174
+
175
+ That variables will be automatically available on both sides of your application.
176
+
177
+ ### Components
178
+ `app/assets/javascripts/components` is where you components live. They will by default render the folder located on `app/assets/javascripts/views/components/_COMPONENT_NAME` (without the '_component' part of the name)
179
+
180
+ To create components:
181
+
182
+ ```sh
183
+
184
+ rails g opalla:component my_component
185
+
186
+ ```
187
+
188
+ They are instantiated and rendered from the controller layout, like this:
189
+
190
+ ```haml
191
+
192
+ %main
193
+ The dude is called #{@dude}.
194
+ He works with #{something_awesome}
195
+ component(:contact_box)
196
+
197
+ ```
198
+
199
+ That will look for the component `app/assets/javascripts/components/contact_box_component.rb`:
200
+
201
+ ```ruby
202
+
203
+ class ContactBoxComponent < ApplicationComponent
204
+
205
+ end
206
+ ```
207
+
208
+ #### Model Data
209
+ The components can get their data from a `Opalla::Model`. Here's how it goes:
210
+
211
+ First, generate your model:
212
+
213
+ ```sh
214
+ bin/rails g opalla:model contact_info
215
+ ```
216
+
217
+ Let’s add a simple attr_accessor:
218
+
219
+ ```ruby
220
+ class Opalla::Model
221
+ attr_accessor :email
222
+ end
223
+ ```
224
+
225
+ In the server-side controller you can expose the data, so that will be rendered from the server as default (no one wants blank pages to maybe hurt the SEO):
226
+
227
+ ```ruby
228
+ class PagesController < ApplicationController
229
+ @contact_info = ContactInfo.new
230
+ @contact_info.email = 'pedro@pedromaciel.com'
231
+ expose contact: @contact_info
232
+ end
233
+ ```
234
+
235
+ Then, in your server side, you don’t need anything for this case, except for render:
236
+
237
+ ```ruby
238
+
239
+ class PagesController < ApplicationController
240
+ el '.main-content'
241
+
242
+ def index
243
+ render
244
+ end
245
+
246
+ end
247
+
248
+ ```
249
+
250
+ In the controller template:
251
+
252
+ ```haml
253
+
254
+ %main
255
+ component(model: @contact_box)
256
+
257
+ ```
258
+
259
+ In the component template:
260
+
261
+ ```haml
262
+
263
+ .contact-info
264
+ .email= model.email
265
+
266
+ ```
267
+
268
+ In the model (`app/assets/javascripts/models/contact_info.rb`):
41
269
 
270
+ ```ruby
271
+ class ContactInfo
272
+ def initialize
273
+ end
274
+ end
275
+ ```
276
+
277
+ ### Collection Data
278
+
279
+ Generate collections:
280
+ ```sh
281
+ bin/rails g opalla:collection products
282
+ ```
283
+
284
+ Opalla will automatically assume that the model is the singular name. So `products` for example is a collection of `product` model. So you have to have the `product` model as well.
285
+
286
+ When working with collection components, you’ll often want to work with `data-attributes`. Opalla has a nifty way to help you:
287
+
288
+ Consider you have the following component:
289
+ ```ruby
290
+ class ProductComponent < ApplicationComponent
291
+
292
+ end
293
+ ```
294
+
295
+ With the following collection (notice the binding):
296
+ ```ruby
297
+ class Products < Opalla::Collection
298
+ bind :price, :category
299
+ end
300
+ ```
301
+
302
+ On your collection model, you set data:
303
+ ```ruby
304
+ class Product < Opalla::Model
305
+ data :price, :category, :model_id
306
+ end
307
+ ```
308
+
309
+ On your component template:
310
+ ```haml
311
+ .products
312
+ collection.each |product|
313
+ .product{data=product.data}
314
+ end
315
+ end
316
+ ```
317
+
318
+ That will generate data attributes: `data-price`, `data-category`, `data-model-id`, the last enabling you to incorporate events in a very simple fashion
319
+
320
+ ```ruby
321
+ class ProductComponent < ApplicationComponent
322
+ events 'click .product' -> target { buy(collection.find(target)) }
323
+ end
324
+ ```
325
+
326
+ That would trigger the buy element providing the `model` as argument. That’s because the `find method` in collections will look for the element or closest ancestor that has a `data-model-id` and return the model itself for you. Really easy!
327
+
328
+ Check the next chapter to see more ways on how collections can be very useful.
329
+
330
+ ### Bindings
331
+
332
+ You can bind data from a model or collection to the component. That will trigger a `#render` action on the component:
333
+
334
+ ```ruby
335
+
336
+ class ContactBoxComponent < ApplicationComponent
337
+ bind :email, :name
338
+
339
+ end
340
+
341
+ ```
342
+
343
+ And that's it! Everytime the resource attributes change, being it a `model` or a `collection`, the component will be re-rendered.
344
+
345
+ #### 2-way binding
346
+ If you assign a `[data-bind='ATTRIBUTE_NAME']` to an input element on your template, it will change look for the closest ancestor that has `[data-model-id]` and change its attribute whenever you change the input.
347
+
348
+ Example:
349
+ ```haml
350
+ .product{data: product.data} # it is expected you set the model data
351
+ input{data-bind: 'name'}
352
+ ```
353
+
354
+ ### Events
355
+ Similarly to Backbone, you can add events in the following way:
356
+
357
+ ```ruby
358
+
359
+ class PagesController < ApplicationController
360
+ el '.main-content'
361
+ events 'click a' => :do_something
362
+
363
+ def index
364
+ el.html 'Hello World!'
365
+ end
366
+
367
+ def do_something
368
+ alert 'I\'m doing something!'
369
+ end
370
+
371
+ end
372
+
373
+ ```
374
+
375
+ You can also provide a `lambda` instead:
376
+
377
+ ```ruby
378
+ class PagesController < ApplicationController
379
+ el '.main-content'
380
+ events 'click a' => { alert "I'm doing something!" }
381
+
382
+ def index
383
+ el.html 'Hello World!'
384
+ end
385
+
386
+ end
387
+
388
+ ```
389
+ You can also access the targetted object like this:
390
+
391
+ ```ruby
392
+ class PagesController < ApplicationController
393
+ el '.main-content'
394
+ events 'click a' => target { alert 'I\'m doing something!' }
395
+
396
+ def index
397
+ el.html 'Hello World!'
398
+ end
399
+
400
+ def do_something
401
+
402
+ end
403
+
404
+ end
405
+
406
+ ```
407
+
408
+ Please note that all events have their default behavior prevented by default.
409
+
410
+ ## Development
411
+ The project is on beta phase. It's missing:
412
+
413
+ * Specs
414
+ * Tests
415
+ * Rubocops
416
+ * ActiveRecord models support
417
+
418
+ Fork and make a PR. Or talk to me at `pedro@pedromaciel.com`.
419
+
420
+ ## License
421
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -1,5 +1,12 @@
1
- require "opalla/version"
1
+ require 'ostruct'
2
+ require 'bundler'; Bundler.require
2
3
 
3
- module Opalla
4
- # Your code goes here...
5
- end
4
+ require 'opal-browser'
5
+ require 'opalla/version'
6
+ require 'opalla/component_helper'
7
+ require 'opalla/controller_add_on'
8
+ require 'opalla/util'
9
+ require 'opalla/middleware'
10
+ require 'opalla/engine'
11
+ require_relative '../opal/model'
12
+ require_relative '../opal/collection'