opalla 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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'