ramaze 0.0.8 → 0.0.9
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.
- data/Rakefile +42 -0
- data/doc/allison/LICENSE +184 -0
- data/doc/allison/README +37 -0
- data/doc/allison/allison.css +300 -0
- data/doc/allison/allison.gif +0 -0
- data/doc/allison/allison.js +307 -0
- data/doc/allison/allison.rb +287 -0
- data/doc/allison/cache/BODY +588 -0
- data/doc/allison/cache/CLASS_INDEX +4 -0
- data/doc/allison/cache/CLASS_PAGE +1 -0
- data/doc/allison/cache/FILE_INDEX +4 -0
- data/doc/allison/cache/FILE_PAGE +1 -0
- data/doc/allison/cache/FONTS +1 -0
- data/doc/allison/cache/FR_INDEX_BODY +1 -0
- data/doc/allison/cache/IMGPATH +1 -0
- data/doc/allison/cache/INDEX +1 -0
- data/doc/allison/cache/JAVASCRIPT +307 -0
- data/doc/allison/cache/METHOD_INDEX +4 -0
- data/doc/allison/cache/METHOD_LIST +1 -0
- data/doc/allison/cache/SRC_PAGE +1 -0
- data/doc/allison/cache/STYLE +322 -0
- data/doc/allison/cache/URL +1 -0
- data/doc/readme_chunks/principles.txt +33 -18
- data/doc/tutorial/todolist.html +599 -0
- data/doc/tutorial/todolist.txt +230 -230
- data/examples/identity.rb +21 -0
- data/examples/nitro_form.rb +22 -0
- data/lib/ramaze/controller.rb +1 -1
- data/lib/ramaze/dispatcher.rb +10 -4
- data/lib/ramaze/helper/{openid.rb → identity.rb} +15 -6
- data/lib/ramaze/helper/nitroform.rb +10 -0
- data/lib/ramaze/helper/stack.rb +1 -1
- data/lib/ramaze/inform.rb +18 -8
- data/lib/ramaze/snippets/kernel/aquire.rb +3 -3
- data/lib/ramaze/snippets/object/traits.rb +1 -1
- data/lib/ramaze/snippets/ramaze/caller_info.rb +17 -1
- data/lib/ramaze/snippets/ramaze/caller_lines.rb +1 -1
- data/lib/ramaze/store/yaml.rb +10 -1
- data/lib/ramaze/template/ezamar.rb +10 -5
- data/lib/ramaze/trinity/request.rb +12 -2
- data/lib/ramaze/version.rb +1 -1
- data/lib/ramaze.rb +5 -3
- data/spec/public/error404.xhtml +1 -0
- data/spec/spec_all.rb +21 -19
- data/spec/spec_helper.rb +1 -1
- data/spec/tc_error.rb +18 -4
- data/spec/tc_helper_cache.rb +1 -1
- data/spec/tc_helper_flash.rb +1 -2
- metadata +32 -4
data/doc/tutorial/todolist.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# To-do List Tutorial
|
2
2
|
|
3
3
|
Welcome to our official tutorial, the mandatory to-do list.
|
4
4
|
I'm writing this while doing the steps to assure it will work for you.
|
@@ -23,7 +23,7 @@ RubyForge.
|
|
23
23
|
Thanks in advance.
|
24
24
|
The author of the tutorial, Michael 'manveru' Fellinger
|
25
25
|
|
26
|
-
|
26
|
+
## First Step, Create
|
27
27
|
|
28
28
|
We are using `ramaze --create todolist` to create a new application.
|
29
29
|
Ramaze will then create the directory and fill it with a skeleton of a quite
|
@@ -32,12 +32,12 @@ to-do list.
|
|
32
32
|
|
33
33
|
So run:
|
34
34
|
|
35
|
-
|
35
|
+
$ ramaze --create todolist
|
36
36
|
|
37
37
|
done.
|
38
38
|
|
39
39
|
|
40
|
-
|
40
|
+
## Second Step, M, like Model
|
41
41
|
|
42
42
|
Ramaze comes at the moment only with a simple wrapper of the YAML::Store.
|
43
43
|
So we are going to base this on the tools available, you can just do the same
|
@@ -48,24 +48,24 @@ YAML::Store already, so we are just gonna modify it a bit to use our wrapper.
|
|
48
48
|
|
49
49
|
Instead of 'yaml/store' use:
|
50
50
|
|
51
|
-
|
51
|
+
require 'ramaze/store/default'
|
52
52
|
|
53
53
|
And further:
|
54
54
|
|
55
|
-
|
55
|
+
TodoList = Store::Default.new 'todolist.yaml'
|
56
56
|
|
57
57
|
To have a base to start off of, let's add some items as well.
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
{
|
60
|
+
'Laundry' => {:done => false},
|
61
|
+
'Wash dishes' => {:done => false},
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
}.each do |title, parameters|
|
64
|
+
TodoList[title] = parameters
|
65
|
+
end
|
66
66
|
|
67
67
|
|
68
|
-
|
68
|
+
## Third Step, V, like View
|
69
69
|
|
70
70
|
Now let's get our hands dirty and just edit the templates for our to-do list.
|
71
71
|
|
@@ -75,22 +75,22 @@ of Ramaze, called Ezamar.
|
|
75
75
|
Let's put some things in there, I'll explain the syntax as we go, it's quite
|
76
76
|
simple.
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
78
|
+
<html>
|
79
|
+
<head>
|
80
|
+
<title>TodoList</title>
|
81
|
+
</head>
|
82
|
+
<body>
|
83
|
+
<h1>TodoList</h1>
|
84
|
+
<ul>
|
85
|
+
<?r
|
86
|
+
TodoList.each do |title, parameters|
|
87
|
+
status = parameters[:done] ? 'done' : 'not done'
|
88
|
+
?>
|
89
|
+
<li>#{title}: #{status}</li>
|
90
|
+
<?r end ?>
|
91
|
+
</ul>
|
92
|
+
</body>
|
93
|
+
</html>
|
94
94
|
|
95
95
|
I will assume that you are familiar with basic Ruby already, so let's
|
96
96
|
concentrate on the things new here.
|
@@ -104,10 +104,10 @@ page.
|
|
104
104
|
The whole Template would expand to something like this (only showing the
|
105
105
|
interesting part)
|
106
106
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
107
|
+
<ul>
|
108
|
+
<li>Laundry: not done</li>
|
109
|
+
<li>Wash dishes: not done</li>
|
110
|
+
</ul>
|
111
111
|
|
112
112
|
That wasn't too bad, huh?
|
113
113
|
|
@@ -124,7 +124,7 @@ now access it by browsing to http://localhost:7000/
|
|
124
124
|
`ramaze --help` to see some other options.
|
125
125
|
|
126
126
|
|
127
|
-
|
127
|
+
## Fourth Step, C, like Controller
|
128
128
|
|
129
129
|
The last part of the MVC-paradigm is the Controller.
|
130
130
|
|
@@ -144,11 +144,11 @@ edit the file `src/controller/main.rb`.
|
|
144
144
|
|
145
145
|
The contents of it are like following:
|
146
146
|
|
147
|
-
|
148
|
-
|
149
|
-
|
147
|
+
class MainController < Controller
|
148
|
+
def index
|
149
|
+
"Hello, World"
|
150
|
+
end
|
150
151
|
end
|
151
|
-
end
|
152
152
|
|
153
153
|
The only method right now is #index, with a simple and for the moment quite
|
154
154
|
useless "Hello, World". The relationship between the methods on the controller
|
@@ -157,35 +157,35 @@ and the templates is 1:1, so the method #index is combined with the template
|
|
157
157
|
|
158
158
|
Let's get back to editing and change the index-method to this:
|
159
159
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
160
|
+
def index
|
161
|
+
@tasks = TodoList.content
|
162
|
+
@tasks.each do |title, parameters|
|
163
|
+
status = parameters[:done] ? 'done' : 'not done'
|
164
|
+
@tasks[title] = status
|
165
|
+
end
|
165
166
|
end
|
166
|
-
end
|
167
167
|
|
168
168
|
This will take care of the logic inside the template, which now should be
|
169
169
|
changed to do following:
|
170
170
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
171
|
+
<html>
|
172
|
+
<head>
|
173
|
+
<title>TodoList</title>
|
174
|
+
</head>
|
175
|
+
<body>
|
176
|
+
<h1>TodoList</h1>
|
177
|
+
<a href="/new">New Task</a>
|
178
|
+
<?r if @tasks.empty? ?>
|
179
|
+
No Tasks
|
180
|
+
<?r else ?>
|
181
|
+
<ul>
|
182
|
+
<?r @tasks.each do |title, status| ?>
|
183
|
+
<li>#{title}: #{status}</li>
|
184
|
+
<?r end ?>
|
185
|
+
</ul>
|
186
|
+
<?r end ?>
|
187
|
+
</body>
|
188
|
+
</html>
|
189
189
|
|
190
190
|
The rest of the template can stay the same.
|
191
191
|
|
@@ -198,31 +198,31 @@ Some things you should know:
|
|
198
198
|
* Instance-variables defined in the Controller are available in the View.
|
199
199
|
* The return-value of the Controller does not matter (in this case).
|
200
200
|
|
201
|
-
|
201
|
+
## Fifth Step, getting dynamic
|
202
202
|
|
203
203
|
We set out to build the ultimate to-do list, but there are still some things
|
204
204
|
missing. First off, we want to add new tasks, so let's get that done.
|
205
205
|
|
206
206
|
Add a link on the `template/index.xhtml` like this:
|
207
207
|
|
208
|
-
|
209
|
-
|
208
|
+
<h1>TodoList</h1>
|
209
|
+
<a href="/new">New Task</a>
|
210
210
|
|
211
211
|
Open a new file `template/new.xhtml` with a form to add a new task.
|
212
212
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
213
|
+
<html>
|
214
|
+
<head>
|
215
|
+
<title>TodoList</title>
|
216
|
+
</head>
|
217
|
+
<body>
|
218
|
+
<h1>New Task</h1>
|
219
|
+
<a href="/">Back to TodoList</a>
|
220
|
+
<form method="POST" action="create">
|
221
|
+
Task: <input type="text" name="title" /><br />
|
222
|
+
<inpyt type="submit" />
|
223
|
+
</form>
|
224
|
+
</body>
|
225
|
+
</html>
|
226
226
|
|
227
227
|
We will not need a method for this on our controller, in fact, actions can
|
228
228
|
consist of either method and template or only one of them. The Controller
|
@@ -244,11 +244,11 @@ OK, let's implement the action for #create, all we want to do is take the
|
|
244
244
|
requests parameters and create a new task for it, this looks like following on
|
245
245
|
your MainController.
|
246
246
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
247
|
+
def create
|
248
|
+
title = request['title']
|
249
|
+
TodoList[title] = {:done => false}
|
250
|
+
redirect R(self)
|
251
|
+
end
|
252
252
|
|
253
253
|
That's all folks!
|
254
254
|
|
@@ -258,7 +258,7 @@ and redirect back to the mapping of the current Controller ('/' in this case).
|
|
258
258
|
Now you can create as many tasks as you want, please don't get overworked ;)
|
259
259
|
|
260
260
|
|
261
|
-
|
261
|
+
## Sixth Step, open and close tasks
|
262
262
|
|
263
263
|
Since the nature of tasks is to be done eventually
|
264
264
|
we will need some way to mark it as done or open tasks again.
|
@@ -266,30 +266,30 @@ we will need some way to mark it as done or open tasks again.
|
|
266
266
|
Jump into `template/index.xhtml` and do the following:
|
267
267
|
|
268
268
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
269
|
+
<?r @tasks.each do |title, status, toggle| ?>
|
270
|
+
<li>
|
271
|
+
#{title}: #{status} - #{toggle}
|
272
|
+
</li>
|
273
|
+
<?r end ?>
|
274
274
|
|
275
275
|
We added a new element here, `toggle`, the Controller should give us
|
276
276
|
a link to change the status corresponding to the status of the task, so off
|
277
277
|
we go and change the index method on the controller once again:
|
278
278
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
279
|
+
def index
|
280
|
+
@tasks = []
|
281
|
+
TodoList.original.each do |title, parameters|
|
282
|
+
if parameters[:done]
|
283
|
+
status = 'done'
|
284
|
+
toggle = link( R( self, :open, CGI.escape(title) ), :title => 'Open Task' )
|
285
|
+
else
|
286
|
+
status = 'not done'
|
287
|
+
toggle = link( R( self, :close, CGI.escape(title) ), :title => 'Close Task' )
|
288
|
+
end
|
289
|
+
@tasks << [title, status, toggle]
|
288
290
|
end
|
289
|
-
@tasks
|
291
|
+
@tasks.sort!
|
290
292
|
end
|
291
|
-
@tasks.sort!
|
292
|
-
end
|
293
293
|
|
294
294
|
Wow, quite some new stuff here. Let me explain that in detail.
|
295
295
|
|
@@ -297,7 +297,7 @@ We first decide whether a task is done or not, then go on and provide a link to
|
|
297
297
|
toggle the status, link and R are both methods that help you do that.
|
298
298
|
the result will be something like:
|
299
299
|
|
300
|
-
|
300
|
+
<a href="/open/Wash+dishes">Close Task</a>
|
301
301
|
|
302
302
|
R actually is responsible to build the links href, for more information please
|
303
303
|
take a look at the RDoc for LinkHelper.
|
@@ -308,55 +308,55 @@ now we use an array to hold our tasks and sort it.
|
|
308
308
|
|
309
309
|
Now back again to `template/index.xhtml` and change it as follows:
|
310
310
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
311
|
+
<?r @tasks.each do |title, status, toggle| ?>
|
312
|
+
<li>
|
313
|
+
#{title}: #{status} [ #{toggle} ]
|
314
|
+
</li>
|
315
|
+
<?r end ?>
|
316
316
|
|
317
317
|
As usual, the things not changed are omitted for terseness.
|
318
318
|
|
319
319
|
And as usual since the links for open and close don't lead anywhere, add the
|
320
320
|
corresponding methods to the Controller:
|
321
321
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
322
|
+
def open title
|
323
|
+
task_status title, false
|
324
|
+
redirect R(self)
|
325
|
+
end
|
326
326
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
327
|
+
def close title
|
328
|
+
task_status title, true
|
329
|
+
redirect R(self)
|
330
|
+
end
|
331
331
|
|
332
|
-
|
332
|
+
private
|
333
333
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
334
|
+
def task_status title, status
|
335
|
+
task = TodoList[title]
|
336
|
+
task[:done] = status
|
337
|
+
TodoList[title] = task
|
338
|
+
end
|
339
339
|
|
340
340
|
Oh, now what have we got here?
|
341
341
|
private declares that methods from here on are only to be used within the
|
342
342
|
Controller itself, we define an #task_status method that takes the title and
|
343
|
-
status to be set so we don't have to repeat that code in #
|
344
|
-
follow the DRY (Don't repeat yourself) paradigm.
|
343
|
+
status to be set so we don't have to repeat that code in _#open_ and _#close_
|
344
|
+
and follow the DRY (Don't repeat yourself) paradigm.
|
345
345
|
|
346
346
|
Another thing we have not encountered so far is that you can define your public
|
347
347
|
methods to take parameters on their own, they will be calculated from requests.
|
348
348
|
|
349
|
-
|
349
|
+
'/open/Wash+dishes'
|
350
350
|
|
351
351
|
will translate into:
|
352
352
|
|
353
|
-
|
353
|
+
open('Wash dishes')
|
354
354
|
|
355
355
|
Which in turn will call task_status('Wash dishes', false)
|
356
356
|
|
357
357
|
That's it, go on and try it :)
|
358
358
|
|
359
|
-
|
359
|
+
## Seventh Step, delete tasks
|
360
360
|
|
361
361
|
Well, creating, opening and closing work now, one of the things you will
|
362
362
|
consider is to delete a task permanently.
|
@@ -364,23 +364,23 @@ consider is to delete a task permanently.
|
|
364
364
|
This is just two little changes away, so let's add the link for deletion in our
|
365
365
|
Controller:
|
366
366
|
|
367
|
-
|
368
|
-
|
367
|
+
delete = link( R( self, :delete, CGI.escape(title) ), :title => 'Delete' )
|
368
|
+
@tasks << [title, status, toggle, delete]
|
369
369
|
|
370
370
|
and an corresponding method while we're at it:
|
371
371
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
372
|
+
def delete title
|
373
|
+
TodoList.delete title
|
374
|
+
redirect R(self)
|
375
|
+
end
|
376
376
|
|
377
377
|
Now jumping to `template/index.xhtml` again, change it so it shows the link:
|
378
378
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
379
|
+
<?r @tasks.each do |title, status, toggle, delete| ?>
|
380
|
+
<li>
|
381
|
+
#{title}: #{status} [ #{toggle} | #{delete} ]
|
382
|
+
</li>
|
383
|
+
<?r end ?>
|
384
384
|
|
385
385
|
Voilà, you now have acquired the Certificate of Ramazeness, our accounting-
|
386
386
|
section will contact you within the next few days.
|
@@ -389,32 +389,32 @@ Just kidding, but that really are the basics, in the next few steps I will
|
|
389
389
|
explain some more advanced concepts of Ramaze and the templating.
|
390
390
|
|
391
391
|
|
392
|
-
|
392
|
+
## Eighth Step, Elements
|
393
393
|
|
394
|
-
|
394
|
+
<Page></Page>
|
395
395
|
|
396
396
|
This is called an Element, Ramaze will go and search for a class that matches
|
397
|
-
the name Page and responds to #
|
397
|
+
the name Page and responds to _#render_. Then it will go and hand the content in
|
398
398
|
between to that Element.
|
399
399
|
|
400
400
|
Sounds weird?
|
401
401
|
|
402
402
|
Let us have a look at our templates, they all got some repetitive stuff, like:
|
403
403
|
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
404
|
+
<html>
|
405
|
+
<head>
|
406
|
+
<title>TodoList</title>
|
407
|
+
</head>
|
408
|
+
<body>
|
409
|
+
<h1>some title</h1>
|
410
|
+
</body>
|
411
|
+
</html>
|
412
412
|
|
413
413
|
How about replacing that with something short and nice:
|
414
414
|
|
415
|
-
|
416
|
-
|
417
|
-
|
415
|
+
<Page title="TodoList">
|
416
|
+
your other content
|
417
|
+
</Page>
|
418
418
|
|
419
419
|
Would be nice of course, and when you start having more templates it makes an
|
420
420
|
awful lot of sense to change the enclosing stuff in one place.
|
@@ -423,43 +423,43 @@ So let's apply DRY here as well.
|
|
423
423
|
|
424
424
|
Take a look at the `src/element/page.rb`
|
425
425
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
426
|
+
class Page < Element
|
427
|
+
def render
|
428
|
+
%{
|
429
|
+
<html>
|
430
|
+
<head>
|
431
|
+
<title>Welcome to Ramaze</title>
|
432
|
+
</head>
|
433
|
+
<body>
|
434
|
+
#{content}
|
435
|
+
</body>
|
436
|
+
</html>
|
437
|
+
}
|
438
|
+
end
|
438
439
|
end
|
439
|
-
end
|
440
440
|
|
441
441
|
Alright, most things we need are in place already, the most important thing
|
442
|
-
is the #
|
443
|
-
#
|
442
|
+
is the _#content_ method that we call with _#{content}_ inside the string in
|
443
|
+
_#render_.
|
444
444
|
|
445
445
|
Just adopt it to your liking, I'll just use the things we had in our templates
|
446
446
|
so far:
|
447
447
|
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
448
|
+
class Page < Element
|
449
|
+
def render
|
450
|
+
%{
|
451
|
+
<html>
|
452
|
+
<head>
|
453
|
+
<title>TodoList</title>
|
454
|
+
</head>
|
455
|
+
<body>
|
456
|
+
<h1>#{@hash['title']}</h1>
|
457
|
+
#{content}
|
458
|
+
</body>
|
459
|
+
</html>
|
460
|
+
}
|
461
|
+
end
|
461
462
|
end
|
462
|
-
end
|
463
463
|
|
464
464
|
Please note that the @hash is filled with the things you pass as parameters
|
465
465
|
to tye Page-tag.
|
@@ -468,75 +468,75 @@ And let's change our templates as well.
|
|
468
468
|
|
469
469
|
First the `template/index.xhtml`
|
470
470
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
471
|
+
<Page title="TodoList">
|
472
|
+
<a href="/new">New Task</a>
|
473
|
+
<?r if @tasks.empty? ?>
|
474
|
+
No Tasks
|
475
|
+
<?r else ?>
|
476
|
+
<ul>
|
477
|
+
<?r @tasks.each do |title, status, toggle, delete| ?>
|
478
|
+
<li>
|
479
|
+
#{title}: #{status} [ #{toggle} | #{delete} ]
|
480
|
+
</li>
|
481
|
+
<?r end ?>
|
482
|
+
</ul>
|
483
|
+
<?r end ?>
|
484
|
+
</Page>
|
485
485
|
|
486
486
|
and the `template/new.xhtml`
|
487
487
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
488
|
+
<Page title="New Task">
|
489
|
+
<a href="/">Back to TodoList</a>
|
490
|
+
<form method="POST" action="create">
|
491
|
+
Task: <input type="text" name="title" /><br />
|
492
|
+
<input type="submit" />
|
493
|
+
</form>
|
494
|
+
</Page>
|
495
495
|
|
496
496
|
Alright, now just go and look at the result in the browser, try changing
|
497
497
|
the things inside the Element and look at how it behaves.
|
498
498
|
|
499
499
|
|
500
|
-
|
500
|
+
## Ninth Step, Prettify
|
501
501
|
|
502
502
|
Let's structure the data inside the list a little bit, in this case into a table to get it line up properly and look actually structured.
|
503
503
|
|
504
504
|
So, from what we have right now:
|
505
505
|
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
506
|
+
<ul>
|
507
|
+
<?r @tasks.each do |title, status, toggle, delete| ?>
|
508
|
+
<li>
|
509
|
+
#{title}: #{status} [ #{toggle} | #{delete} ]
|
510
|
+
</li>
|
511
|
+
<?r end ?>
|
512
|
+
</ul>
|
513
513
|
|
514
514
|
To something like this:
|
515
515
|
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
516
|
+
<table>
|
517
|
+
<?r @tasks.each do |title, status, toggle, delete| ?>
|
518
|
+
<tr>
|
519
|
+
<td class="title"> #{title} </td>
|
520
|
+
<td class="status"> #{status} </td>
|
521
|
+
<td class="toggle"> #{toggle} </td>
|
522
|
+
<td class="delete"> #{delete} </td>
|
523
|
+
</tr>
|
524
|
+
<?r end ?>
|
525
|
+
</table>
|
526
526
|
|
527
527
|
And, since we have proper classes to address some style sheets, jump into the Page element and add some style sheet like that:
|
528
528
|
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
529
|
+
<head>
|
530
|
+
<title>TodoList</title>
|
531
|
+
<style>
|
532
|
+
table { width: 100%; }
|
533
|
+
tr { background: #efe; width: 100%; }
|
534
|
+
tr:hover { background: #dfd; }
|
535
|
+
td.title { font-weight: bold; width: 60%; }
|
536
|
+
td.status { margin: 1em; }
|
537
|
+
a { color: #3a3; }
|
538
|
+
</style>
|
539
|
+
</head>
|
540
540
|
|
541
541
|
That looks quite a bit nicer, right?
|
542
542
|
And yes, if you don't like tables (though this is an entirely legit use in my opinion, you can just do it like you want, using nested lists or divs/spans, replacing the open/close and delete links with nice images and changing the style according to the status.
|