ramaze 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|