forked from mhartl/rails_tutorial_translation_4_0_version
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfilling-in-the-layout.html
2417 lines (1609 loc) · 221 KB
/
filling-in-the-layout.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<title>filling-in-the-layout</title>
<link rel="stylesheet" href="pygments.css" type="text/css" />
<link rel="stylesheet" href="polytexnic.css" type="text/css" />
</head>
<body>
<div id="book">
<h1 class="title">Ruby on Rails Tutorial </h1>
<h1 class="subtitle"> Learn Web Development with Rails</h1>
<h2 class="author">Michael Hartl</h2>
<h2 class="contents">Contents</h2>
<div id="table_of_contents"><ol><li class="chapter"><a href="beginning.html#top"><span class="number">Chapter 1</span> From zero to deploy</a></li><li><ol><li class="section"><a href="beginning.html#sec-introduction"><span class="number">1.1</span> Introduction</a></li><li><ol><li class="subsection"><a href="beginning.html#sec-comments_for_various_readers"><span class="number">1.1.1</span> Comments for various readers</a></li><li class="subsection"><a href="beginning.html#sec-1_1_2"><span class="number">1.1.2</span> “Scaling” Rails</a></li><li class="subsection"><a href="beginning.html#sec-conventions"><span class="number">1.1.3</span> Conventions in this book</a></li></ol></li><li class="section"><a href="beginning.html#sec-up_and_running"><span class="number">1.2</span> Up and running</a></li><li><ol><li class="subsection"><a href="beginning.html#sec-development_tools"><span class="number">1.2.1</span> Development environments</a></li><li><ol><li class="subsubsection"><a href="beginning.html#sec-1_2_1_1">IDEs</a></li><li class="subsubsection"><a href="beginning.html#sec-1_2_1_2">Text editors and command lines</a></li><li class="subsubsection"><a href="beginning.html#sec-1_2_1_3">Browsers</a></li><li class="subsubsection"><a href="beginning.html#sec-1_2_1_4">A note about tools</a></li></ol></li><li class="subsection"><a href="beginning.html#sec-rubygems"><span class="number">1.2.2</span> Ruby, RubyGems, Rails, and Git</a></li><li><ol><li class="subsubsection"><a href="beginning.html#sec-rails_installer_windows">Rails Installer (Windows)</a></li><li class="subsubsection"><a href="beginning.html#sec-install_git">Install Git</a></li><li class="subsubsection"><a href="beginning.html#sec-install_ruby">Install Ruby</a></li><li class="subsubsection"><a href="beginning.html#sec-install_rubygems">Install RubyGems</a></li><li class="subsubsection"><a href="beginning.html#sec-install_rails">Install Rails</a></li></ol></li><li class="subsection"><a href="beginning.html#sec-the_first_application"><span class="number">1.2.3</span> The first application</a></li><li class="subsection"><a href="beginning.html#sec-bundler"><span class="number">1.2.4</span> Bundler</a></li><li class="subsection"><a href="beginning.html#sec-rails_server"><span class="number">1.2.5</span> <tt>rails server</tt></a></li><li class="subsection"><a href="beginning.html#sec-mvc"><span class="number">1.2.6</span> Model-view-controller (MVC)</a></li></ol></li><li class="section"><a href="beginning.html#sec-version_control"><span class="number">1.3</span> Version control with Git</a></li><li><ol><li class="subsection"><a href="beginning.html#sec-git_setup"><span class="number">1.3.1</span> Installation and setup</a></li><li><ol><li class="subsubsection"><a href="beginning.html#sec-1_3_1_1">First-time system setup</a></li><li class="subsubsection"><a href="beginning.html#sec-1_3_1_2">First-time repository setup</a></li></ol></li><li class="subsection"><a href="beginning.html#sec-adding_and_committing"><span class="number">1.3.2</span> Adding and committing</a></li><li class="subsection"><a href="beginning.html#sec-1_3_3"><span class="number">1.3.3</span> What good does Git do you?</a></li><li class="subsection"><a href="beginning.html#sec-github"><span class="number">1.3.4</span> GitHub</a></li><li class="subsection"><a href="beginning.html#sec-git_commands"><span class="number">1.3.5</span> Branch, edit, commit, merge</a></li><li><ol><li class="subsubsection"><a href="beginning.html#sec-git_branch">Branch</a></li><li class="subsubsection"><a href="beginning.html#sec-git_edit">Edit</a></li><li class="subsubsection"><a href="beginning.html#sec-git_commit">Commit</a></li><li class="subsubsection"><a href="beginning.html#sec-git_merge">Merge</a></li><li class="subsubsection"><a href="beginning.html#sec-git_push">Push</a></li></ol></li></ol></li><li class="section"><a href="beginning.html#sec-deploying"><span class="number">1.4</span> Deploying</a></li><li><ol><li class="subsection"><a href="beginning.html#sec-heroku_setup"><span class="number">1.4.1</span> Heroku setup</a></li><li class="subsection"><a href="beginning.html#sec-heroku_step_one"><span class="number">1.4.2</span> Heroku deployment, step one</a></li><li class="subsection"><a href="beginning.html#sec-1_4_3"><span class="number">1.4.3</span> Heroku deployment, step two</a></li><li class="subsection"><a href="beginning.html#sec-heroku_commands"><span class="number">1.4.4</span> Heroku commands</a></li></ol></li><li class="section"><a href="beginning.html#sec-beginning_conclusion"><span class="number">1.5</span> Conclusion</a></li></ol></li><li class="chapter"><a href="a-demo-app.html#top"><span class="number">Chapter 2</span> A demo app</a></li><li><ol><li class="section"><a href="a-demo-app.html#sec-planning_the_application"><span class="number">2.1</span> Planning the application</a></li><li><ol><li class="subsection"><a href="a-demo-app.html#sec-modeling_demo_users"><span class="number">2.1.1</span> Modeling demo users</a></li><li class="subsection"><a href="a-demo-app.html#sec-modeling_demo_microposts"><span class="number">2.1.2</span> Modeling demo microposts</a></li></ol></li><li class="section"><a href="a-demo-app.html#sec-demo_users_resource"><span class="number">2.2</span> The Users resource</a></li><li><ol><li class="subsection"><a href="a-demo-app.html#sec-a_user_tour"><span class="number">2.2.1</span> A user tour</a></li><li class="subsection"><a href="a-demo-app.html#sec-mvc_in_action"><span class="number">2.2.2</span> MVC in action</a></li><li class="subsection"><a href="a-demo-app.html#sec-weaknesses_of_this_users_resource"><span class="number">2.2.3</span> Weaknesses of this Users resource</a></li></ol></li><li class="section"><a href="a-demo-app.html#sec-microposts_resource"><span class="number">2.3</span> The Microposts resource</a></li><li><ol><li class="subsection"><a href="a-demo-app.html#sec-a_micropost_microtour"><span class="number">2.3.1</span> A micropost microtour</a></li><li class="subsection"><a href="a-demo-app.html#sec-putting_the_micro_in_microposts"><span class="number">2.3.2</span> Putting the <em>micro</em> in microposts</a></li><li class="subsection"><a href="a-demo-app.html#sec-demo_user_has_many_microposts"><span class="number">2.3.3</span> A user <tt>has_many</tt> microposts</a></li><li class="subsection"><a href="a-demo-app.html#sec-inheritance_hierarchies"><span class="number">2.3.4</span> Inheritance hierarchies</a></li><li class="subsection"><a href="a-demo-app.html#sec-deploying_the_demo_app"><span class="number">2.3.5</span> Deploying the demo app</a></li></ol></li><li class="section"><a href="a-demo-app.html#sec-2_4"><span class="number">2.4</span> Conclusion</a></li></ol></li><li class="chapter"><a href="static-pages.html#top"><span class="number">Chapter 3</span> Mostly static pages</a></li><li><ol><li class="section"><a href="static-pages.html#sec-static_pages"><span class="number">3.1</span> Static pages</a></li><li class="section"><a href="static-pages.html#sec-first_tests"><span class="number">3.2</span> Our first tests</a></li><li><ol><li class="subsection"><a href="static-pages.html#sec-TDD"><span class="number">3.2.1</span> Test-driven development</a></li><li class="subsection"><a href="static-pages.html#sec-adding_a_page"><span class="number">3.2.2</span> Adding a page</a></li><li><ol><li class="subsubsection"><a href="static-pages.html#sec-red">Red</a></li><li class="subsubsection"><a href="static-pages.html#sec-green">Green</a></li><li class="subsubsection"><a href="static-pages.html#sec-refactor">Refactor</a></li></ol></li></ol></li><li class="section"><a href="static-pages.html#sec-slightly_dynamic_pages"><span class="number">3.3</span> Slightly dynamic pages</a></li><li><ol><li class="subsection"><a href="static-pages.html#sec-testing_a_title_change"><span class="number">3.3.1</span> Testing a title change</a></li><li class="subsection"><a href="static-pages.html#sec-passing_title_tests"><span class="number">3.3.2</span> Passing title tests</a></li><li class="subsection"><a href="static-pages.html#sec-embedded_ruby"><span class="number">3.3.3</span> Embedded Ruby</a></li><li class="subsection"><a href="static-pages.html#sec-layouts"><span class="number">3.3.4</span> Eliminating duplication with layouts</a></li></ol></li><li class="section"><a href="static-pages.html#sec-static_pages_conclusion"><span class="number">3.4</span> Conclusion</a></li><li class="section"><a href="static-pages.html#sec-static_pages_exercises"><span class="number">3.5</span> Exercises</a></li><li class="section"><a href="static-pages.html#sec-advanced_setup"><span class="number">3.6</span> Advanced setup</a></li><li><ol><li class="subsection"><a href="static-pages.html#sec-eliminating_bundle_exec"><span class="number">3.6.1</span> Eliminating <tt>bundle exec</tt></a></li><li><ol><li class="subsubsection"><a href="static-pages.html#sec-rvm_bundler_integration">RVM Bundler integration</a></li><li class="subsubsection"><a href="static-pages.html#sec-binstubs">binstubs</a></li></ol></li><li class="subsection"><a href="static-pages.html#sec-guard"><span class="number">3.6.2</span> Automated tests with Guard</a></li><li class="subsection"><a href="static-pages.html#sec-spork"><span class="number">3.6.3</span> Speeding up tests with Spork</a></li><li><ol><li class="subsubsection"><a href="static-pages.html#sec-spork_and_guard">Guard with Spork</a></li></ol></li><li class="subsection"><a href="static-pages.html#sec-tests_inside_sublime_text"><span class="number">3.6.4</span> Tests inside Sublime Text</a></li></ol></li></ol></li><li class="chapter"><a href="rails-flavored-ruby.html#top"><span class="number">Chapter 4</span> Rails-flavored Ruby</a></li><li><ol><li class="section"><a href="rails-flavored-ruby.html#sec-motivation"><span class="number">4.1</span> Motivation</a></li><li class="section"><a href="rails-flavored-ruby.html#sec-strings_and_methods"><span class="number">4.2</span> Strings and methods</a></li><li><ol><li class="subsection"><a href="rails-flavored-ruby.html#sec-comments"><span class="number">4.2.1</span> Comments</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-strings"><span class="number">4.2.2</span> Strings</a></li><li><ol><li class="subsubsection"><a href="rails-flavored-ruby.html#sec-printing">Printing</a></li><li class="subsubsection"><a href="rails-flavored-ruby.html#sec-single_quoted_strings">Single-quoted strings</a></li></ol></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-objects_and_message_passing"><span class="number">4.2.3</span> Objects and message passing</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-method_definitions"><span class="number">4.2.4</span> Method definitions</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-back_to_the_title_helper"><span class="number">4.2.5</span> Back to the title helper</a></li></ol></li><li class="section"><a href="rails-flavored-ruby.html#sec-other_data_structures"><span class="number">4.3</span> Other data structures</a></li><li><ol><li class="subsection"><a href="rails-flavored-ruby.html#sec-arrays_and_ranges"><span class="number">4.3.1</span> Arrays and ranges</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-blocks"><span class="number">4.3.2</span> Blocks</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-hashes_and_symbols"><span class="number">4.3.3</span> Hashes and symbols</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-css_revisited"><span class="number">4.3.4</span> CSS revisited</a></li></ol></li><li class="section"><a href="rails-flavored-ruby.html#sec-ruby_classes"><span class="number">4.4</span> Ruby classes</a></li><li><ol><li class="subsection"><a href="rails-flavored-ruby.html#sec-constructors"><span class="number">4.4.1</span> Constructors</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-a_class_of_our_own"><span class="number">4.4.2</span> Class inheritance</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-modifying_built_in_classes"><span class="number">4.4.3</span> Modifying built-in classes</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-a_controller_class"><span class="number">4.4.4</span> A controller class</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-a_user_class"><span class="number">4.4.5</span> A user class</a></li></ol></li><li class="section"><a href="rails-flavored-ruby.html#sec-conclusion"><span class="number">4.5</span> Conclusion</a></li><li class="section"><a href="rails-flavored-ruby.html#sec-exercises"><span class="number">4.6</span> Exercises</a></li></ol></li><li class="chapter"><a href="filling-in-the-layout.html#top"><span class="number">Chapter 5</span> Filling in the layout</a></li><li><ol><li class="section"><a href="filling-in-the-layout.html#sec-structure"><span class="number">5.1</span> Adding some structure</a></li><li><ol><li class="subsection"><a href="filling-in-the-layout.html#sec-adding_to_the_layout"><span class="number">5.1.1</span> Site navigation</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-custom_css"><span class="number">5.1.2</span> Bootstrap and custom CSS</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-partials"><span class="number">5.1.3</span> Partials</a></li></ol></li><li class="section"><a href="filling-in-the-layout.html#sec-sass_and_the_asset_pipeline"><span class="number">5.2</span> Sass and the asset pipeline</a></li><li><ol><li class="subsection"><a href="filling-in-the-layout.html#sec-the_asset_pipeline"><span class="number">5.2.1</span> The asset pipeline</a></li><li><ol><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_1_1">Asset directories</a></li><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_1_2">Manifest files</a></li><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_1_3">Preprocessor engines</a></li><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_1_4">Efficiency in production</a></li></ol></li><li class="subsection"><a href="filling-in-the-layout.html#sec-sass"><span class="number">5.2.2</span> Syntactically awesome stylesheets</a></li><li><ol><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_2_1">Nesting</a></li><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_2_2">Variables</a></li></ol></li></ol></li><li class="section"><a href="filling-in-the-layout.html#sec-layout_links"><span class="number">5.3</span> Layout links</a></li><li><ol><li class="subsection"><a href="filling-in-the-layout.html#sec-route_tests"><span class="number">5.3.1</span> Route tests</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-rails_routes"><span class="number">5.3.2</span> Rails routes</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-named_routes"><span class="number">5.3.3</span> Named routes</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-pretty_rspec"><span class="number">5.3.4</span> Pretty RSpec</a></li></ol></li><li class="section"><a href="filling-in-the-layout.html#sec-user_signup"><span class="number">5.4</span> User signup: A first step</a></li><li><ol><li class="subsection"><a href="filling-in-the-layout.html#sec-users_controller"><span class="number">5.4.1</span> Users controller</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-signup_url"><span class="number">5.4.2</span> Signup URL</a></li></ol></li><li class="section"><a href="filling-in-the-layout.html#sec-layout_conclusion"><span class="number">5.5</span> Conclusion</a></li><li class="section"><a href="filling-in-the-layout.html#sec-layout_exercises"><span class="number">5.6</span> Exercises</a></li></ol></li><li class="chapter"><a href="modeling-users.html#top"><span class="number">Chapter 6</span> Modeling users</a></li><li><ol><li class="section"><a href="modeling-users.html#sec-user_model"><span class="number">6.1</span> User model</a></li><li><ol><li class="subsection"><a href="modeling-users.html#sec-database_migrations"><span class="number">6.1.1</span> Database migrations</a></li><li class="subsection"><a href="modeling-users.html#sec-the_model_file"><span class="number">6.1.2</span> The model file</a></li><li class="subsection"><a href="modeling-users.html#sec-creating_user_objects"><span class="number">6.1.3</span> Creating user objects</a></li><li class="subsection"><a href="modeling-users.html#sec-finding_user_objects"><span class="number">6.1.4</span> Finding user objects</a></li><li class="subsection"><a href="modeling-users.html#sec-updating_user_objects"><span class="number">6.1.5</span> Updating user objects</a></li></ol></li><li class="section"><a href="modeling-users.html#sec-user_validations"><span class="number">6.2</span> User validations</a></li><li><ol><li class="subsection"><a href="modeling-users.html#sec-initial_user_tests"><span class="number">6.2.1</span> Initial user tests</a></li><li class="subsection"><a href="modeling-users.html#sec-presence_validation"><span class="number">6.2.2</span> Validating presence</a></li><li class="subsection"><a href="modeling-users.html#sec-length_validation"><span class="number">6.2.3</span> Length validation</a></li><li class="subsection"><a href="modeling-users.html#sec-format_validation"><span class="number">6.2.4</span> Format validation</a></li><li class="subsection"><a href="modeling-users.html#sec-uniqueness_validation"><span class="number">6.2.5</span> Uniqueness validation</a></li><li><ol><li class="subsubsection"><a href="modeling-users.html#sec-the_caveat">The uniqueness caveat</a></li></ol></li></ol></li><li class="section"><a href="modeling-users.html#sec-adding_a_secure_password"><span class="number">6.3</span> Adding a secure password</a></li><li><ol><li class="subsection"><a href="modeling-users.html#sec-a_hashed_password"><span class="number">6.3.1</span> A hashed password</a></li><li class="subsection"><a href="modeling-users.html#sec-password_and_confirmation"><span class="number">6.3.2</span> Password and confirmation</a></li><li class="subsection"><a href="modeling-users.html#sec-user_authentication"><span class="number">6.3.3</span> User authentication</a></li><li class="subsection"><a href="modeling-users.html#sec-has_secure_password"><span class="number">6.3.4</span> User has secure password</a></li><li class="subsection"><a href="modeling-users.html#sec-creating_a_user"><span class="number">6.3.5</span> Creating a user</a></li></ol></li><li class="section"><a href="modeling-users.html#sec-6_4"><span class="number">6.4</span> Conclusion</a></li><li class="section"><a href="modeling-users.html#sec-modeling_users_exercises"><span class="number">6.5</span> Exercises</a></li></ol></li><li class="chapter"><a href="sign-up.html#top"><span class="number">Chapter 7</span> Sign up</a></li><li><ol><li class="section"><a href="sign-up.html#sec-showing_users"><span class="number">7.1</span> Showing users</a></li><li><ol><li class="subsection"><a href="sign-up.html#sec-rails_environments"><span class="number">7.1.1</span> Debug and Rails environments</a></li><li class="subsection"><a href="sign-up.html#sec-a_users_resource"><span class="number">7.1.2</span> A Users resource</a></li><li class="subsection"><a href="sign-up.html#sec-tests_with_factories"><span class="number">7.1.3</span> Testing the user show page (with factories)</a></li><li class="subsection"><a href="sign-up.html#sec-a_gravatar_image"><span class="number">7.1.4</span> A Gravatar image and a sidebar</a></li></ol></li><li class="section"><a href="sign-up.html#sec-signup_form"><span class="number">7.2</span> Signup form</a></li><li><ol><li class="subsection"><a href="sign-up.html#sec-tests_for_user_signup"><span class="number">7.2.1</span> Tests for user signup</a></li><li class="subsection"><a href="sign-up.html#sec-using_form_for"><span class="number">7.2.2</span> Using <tt>form_for</tt></a></li><li class="subsection"><a href="sign-up.html#sec-the_form_html"><span class="number">7.2.3</span> The form HTML</a></li></ol></li><li class="section"><a href="sign-up.html#sec-signup_failure"><span class="number">7.3</span> Signup failure</a></li><li><ol><li class="subsection"><a href="sign-up.html#sec-a_working_form"><span class="number">7.3.1</span> A working form</a></li><li class="subsection"><a href="sign-up.html#sec-strong_parameters"><span class="number">7.3.2</span> Strong parameters</a></li><li class="subsection"><a href="sign-up.html#sec-signup_error_messages"><span class="number">7.3.3</span> Signup error messages</a></li></ol></li><li class="section"><a href="sign-up.html#sec-signup_success"><span class="number">7.4</span> Signup success</a></li><li><ol><li class="subsection"><a href="sign-up.html#sec-the_finished_signup_form"><span class="number">7.4.1</span> The finished signup form</a></li><li class="subsection"><a href="sign-up.html#sec-the_flash"><span class="number">7.4.2</span> The flash</a></li><li class="subsection"><a href="sign-up.html#sec-the_first_signup"><span class="number">7.4.3</span> The first signup</a></li><li class="subsection"><a href="sign-up.html#sec-deploying_to_production_with_ssl"><span class="number">7.4.4</span> Deploying to production with SSL</a></li></ol></li><li class="section"><a href="sign-up.html#sec-7_5"><span class="number">7.5</span> Conclusion</a></li><li class="section"><a href="sign-up.html#sec-signup_exercises"><span class="number">7.6</span> Exercises</a></li></ol></li><li class="chapter"><a href="sign-in-sign-out.html#top"><span class="number">Chapter 8</span> Sign in, sign out</a></li><li><ol><li class="section"><a href="sign-in-sign-out.html#sec-signin_failure"><span class="number">8.1</span> Sessions and signin failure</a></li><li><ol><li class="subsection"><a href="sign-in-sign-out.html#sec-sessions_controller"><span class="number">8.1.1</span> Sessions controller</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-signin_tests"><span class="number">8.1.2</span> Signin tests</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-signin_form"><span class="number">8.1.3</span> Signin form</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-reviewing_form_submission"><span class="number">8.1.4</span> Reviewing form submission</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-rendering_with_a_flash_message"><span class="number">8.1.5</span> Rendering with a flash message</a></li></ol></li><li class="section"><a href="sign-in-sign-out.html#sec-signin_success"><span class="number">8.2</span> Signin success</a></li><li><ol><li class="subsection"><a href="sign-in-sign-out.html#sec-remember_me"><span class="number">8.2.1</span> Remember me</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-a_working_sign_in_method"><span class="number">8.2.2</span> A working <tt>sign_in</tt> method</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-current_user"><span class="number">8.2.3</span> Current user</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-changing_the_layout_links"><span class="number">8.2.4</span> Changing the layout links</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-signin_upon_signup"><span class="number">8.2.5</span> Signin upon signup</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-signing_out"><span class="number">8.2.6</span> Signing out</a></li></ol></li><li class="section"><a href="sign-in-sign-out.html#sec-cucumber"><span class="number">8.3</span> Introduction to cucumber (optional)</a></li><li><ol><li class="subsection"><a href="sign-in-sign-out.html#sec-installation_and_setup"><span class="number">8.3.1</span> Installation and setup</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-features_and_steps"><span class="number">8.3.2</span> Features and steps</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-rspec_custom_matchers"><span class="number">8.3.3</span> Counterpoint: RSpec custom matchers</a></li></ol></li><li class="section"><a href="sign-in-sign-out.html#sec-8_4"><span class="number">8.4</span> Conclusion</a></li><li class="section"><a href="sign-in-sign-out.html#sec-sign_in_out_exercises"><span class="number">8.5</span> Exercises</a></li></ol></li><li class="chapter"><a href="updating-showing-and-deleting-users.html#top"><span class="number">Chapter 9</span> Updating, showing, and deleting users</a></li><li><ol><li class="section"><a href="updating-showing-and-deleting-users.html#sec-updating_users"><span class="number">9.1</span> Updating users</a></li><li><ol><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-edit_form"><span class="number">9.1.1</span> Edit form</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-unsuccessful_edits"><span class="number">9.1.2</span> Unsuccessful edits</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-successful_edits"><span class="number">9.1.3</span> Successful edits</a></li></ol></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-authorization"><span class="number">9.2</span> Authorization</a></li><li><ol><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-requiring_signed_in_users"><span class="number">9.2.1</span> Requiring signed-in users</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-requiring_the_right_user"><span class="number">9.2.2</span> Requiring the right user</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-friendly_forwarding"><span class="number">9.2.3</span> Friendly forwarding</a></li></ol></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-showing_all_users"><span class="number">9.3</span> Showing all users</a></li><li><ol><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-user_index"><span class="number">9.3.1</span> User index</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-sample_users"><span class="number">9.3.2</span> Sample users</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-pagination"><span class="number">9.3.3</span> Pagination</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-partial_refactoring"><span class="number">9.3.4</span> Partial refactoring</a></li></ol></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-destroying_users"><span class="number">9.4</span> Deleting users</a></li><li><ol><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-administrative_users"><span class="number">9.4.1</span> Administrative users</a></li><li><ol><li class="subsubsection"><a href="updating-showing-and-deleting-users.html#sec-revisiting_strong_parameters">Revisiting strong parameters</a></li></ol></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-the_destroy_action"><span class="number">9.4.2</span> The <tt>destroy</tt> action</a></li></ol></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-updating_and_deleting_users_conclusion"><span class="number">9.5</span> Conclusion</a></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-updating_deleting_exercises"><span class="number">9.6</span> Exercises</a></li></ol></li><li class="chapter"><a href="user-microposts.html#top"><span class="number">Chapter 10</span> User microposts</a></li><li><ol><li class="section"><a href="user-microposts.html#sec-a_micropost_model"><span class="number">10.1</span> A Micropost model</a></li><li><ol><li class="subsection"><a href="user-microposts.html#sec-the_basic_model"><span class="number">10.1.1</span> The basic model</a></li><li class="subsection"><a href="user-microposts.html#sec-first_micropost_validation"><span class="number">10.1.2</span> The first validation</a></li><li class="subsection"><a href="user-microposts.html#sec-user_micropost_associations"><span class="number">10.1.3</span> User/Micropost associations</a></li><li class="subsection"><a href="user-microposts.html#sec-ordering_and_dependency"><span class="number">10.1.4</span> Micropost refinements</a></li><li><ol><li class="subsubsection"><a href="user-microposts.html#sec-default_scope">Default scope</a></li><li class="subsubsection"><a href="user-microposts.html#sec-dependent_destroy">Dependent: destroy</a></li></ol></li><li class="subsection"><a href="user-microposts.html#sec-micropost_validations"><span class="number">10.1.5</span> Content validations</a></li></ol></li><li class="section"><a href="user-microposts.html#sec-showing_microposts"><span class="number">10.2</span> Showing microposts</a></li><li><ol><li class="subsection"><a href="user-microposts.html#sec-augmenting_the_user_show_page"><span class="number">10.2.1</span> Augmenting the user show page</a></li><li class="subsection"><a href="user-microposts.html#sec-sample_microposts"><span class="number">10.2.2</span> Sample microposts</a></li></ol></li><li class="section"><a href="user-microposts.html#sec-manipulating_microposts"><span class="number">10.3</span> Manipulating microposts</a></li><li><ol><li class="subsection"><a href="user-microposts.html#sec-access_control"><span class="number">10.3.1</span> Access control</a></li><li class="subsection"><a href="user-microposts.html#sec-creating_microposts"><span class="number">10.3.2</span> Creating microposts</a></li><li class="subsection"><a href="user-microposts.html#sec-a_proto_feed"><span class="number">10.3.3</span> A proto-feed</a></li><li class="subsection"><a href="user-microposts.html#sec-destroying_microposts"><span class="number">10.3.4</span> Destroying microposts</a></li></ol></li><li class="section"><a href="user-microposts.html#sec-10_4"><span class="number">10.4</span> Conclusion</a></li><li class="section"><a href="user-microposts.html#sec-micropost_exercises"><span class="number">10.5</span> Exercises</a></li></ol></li><li class="chapter"><a href="following-users.html#top"><span class="number">Chapter 11</span> Following users</a></li><li><ol><li class="section"><a href="following-users.html#sec-the_relationship_model"><span class="number">11.1</span> The Relationship model</a></li><li><ol><li class="subsection"><a href="following-users.html#sec-a_problem_with_the_data_model"><span class="number">11.1.1</span> A problem with the data model (and a solution)</a></li><li class="subsection"><a href="following-users.html#sec-relationship_user_associations"><span class="number">11.1.2</span> User/relationship associations</a></li><li class="subsection"><a href="following-users.html#sec-relationship_validations"><span class="number">11.1.3</span> Validations</a></li><li class="subsection"><a href="following-users.html#sec-following"><span class="number">11.1.4</span> Followed users</a></li><li class="subsection"><a href="following-users.html#sec-followers"><span class="number">11.1.5</span> Followers</a></li></ol></li><li class="section"><a href="following-users.html#sec-a_web_interface_for_following_and_followers"><span class="number">11.2</span> A web interface for following users</a></li><li><ol><li class="subsection"><a href="following-users.html#sec-sample_following_data"><span class="number">11.2.1</span> Sample following data</a></li><li class="subsection"><a href="following-users.html#sec-stats_and_a_follow_form"><span class="number">11.2.2</span> Stats and a follow form</a></li><li class="subsection"><a href="following-users.html#sec-following_and_followers_pages"><span class="number">11.2.3</span> Following and followers pages</a></li><li class="subsection"><a href="following-users.html#sec-a_working_follow_button_the_standard_way"><span class="number">11.2.4</span> A working follow button the standard way</a></li><li class="subsection"><a href="following-users.html#sec-a_working_follow_button_with_ajax"><span class="number">11.2.5</span> A working follow button with Ajax</a></li></ol></li><li class="section"><a href="following-users.html#sec-the_status_feed"><span class="number">11.3</span> The status feed</a></li><li><ol><li class="subsection"><a href="following-users.html#sec-motivation_and_strategy"><span class="number">11.3.1</span> Motivation and strategy</a></li><li class="subsection"><a href="following-users.html#sec-a_first_feed_implementation"><span class="number">11.3.2</span> A first feed implementation</a></li><li class="subsection"><a href="following-users.html#sec-scopes_subselects_and_a_lambda"><span class="number">11.3.3</span> Subselects</a></li><li class="subsection"><a href="following-users.html#sec-the_new_status_feed"><span class="number">11.3.4</span> The new status feed</a></li></ol></li><li class="section"><a href="following-users.html#sec-following_conclusion"><span class="number">11.4</span> Conclusion</a></li><li><ol><li class="subsection"><a href="following-users.html#sec-extensions_to_the_sample_application"><span class="number">11.4.1</span> Extensions to the sample application</a></li><li><ol><li class="subsubsection"><a href="following-users.html#sec-replies">Replies</a></li><li class="subsubsection"><a href="following-users.html#sec-messaging">Messaging</a></li><li class="subsubsection"><a href="following-users.html#sec-follower_notifications">Follower notifications</a></li><li class="subsubsection"><a href="following-users.html#sec-password_reminders">Password reminders</a></li><li class="subsubsection"><a href="following-users.html#sec-signup_confirmation">Signup confirmation</a></li><li class="subsubsection"><a href="following-users.html#sec-rss_feed">RSS feed</a></li><li class="subsubsection"><a href="following-users.html#sec-rest_api">REST API</a></li><li class="subsubsection"><a href="following-users.html#sec-search">Search</a></li></ol></li><li class="subsection"><a href="following-users.html#sec-guide_to_further_resources"><span class="number">11.4.2</span> Guide to further resources</a></li></ol></li><li class="section"><a href="following-users.html#sec-following_exercises"><span class="number">11.5</span> Exercises</a></li></ol></li></ol></div>
<div id="main_content"></div>
<p> <span class="preamble">
<span id="foreword">
<strong> Foreword</strong> <br />
</span>
</span></p>
<p>My former company (CD Baby) was one of the first to loudly switch to Ruby on Rails, and then even more loudly switch back to PHP (Google me to read about the drama). This book by Michael Hartl came so highly recommended that I had to try it, and the <em>Ruby on Rails Tutorial</em> is what I used to switch back to Rails again.</p>
<p>Though I’ve worked my way through many Rails books, this is the one that finally made me “get” it. Everything is done very much “the Rails way”—a way that felt very unnatural to me before, but now after doing this book finally feels natural. This is also the only Rails book that does test-driven development the entire time, an approach highly recommended by the experts but which has never been so clearly demonstrated before. Finally, by including Git, GitHub, and Heroku in the demo examples, the author really gives you a feel for what it’s like to do a real-world project. The tutorial’s code examples are not in isolation.</p>
<p>The linear narrative is such a great format. Personally, I powered through the <em>Rails Tutorial</em> in three long days, doing all the examples and challenges at the end of each chapter. Do it from start to finish, without jumping around, and you’ll get the ultimate benefit.</p>
<p>Enjoy!</p>
<p><a href="http://sivers.org/">Derek Sivers</a> (<a href="http://sivers.org/">sivers.org</a>) <br />
<em>Founder, CD Baby</em> <br /></p>
<p> <span class="preamble">
<strong> Acknowledgments</strong> <br />
</span></p>
<p>The <em>Ruby on Rails Tutorial</em> owes a lot to my previous Rails book, <em>RailsSpace</em>, and hence to my coauthor <a href="http://aure.com/">Aurelius Prochazka</a>. I’d like to thank Aure both for the work he did on that book and for his support of this one. I’d also like to thank Debra Williams Cauley, my editor on both <em>RailsSpace</em> and the <em>Ruby on Rails Tutorial</em>; as long as she keeps taking me to baseball games, I’ll keep writing books for her.</p>
<p>I’d like to acknowledge a long list of Rubyists who have taught and inspired me over the years: David Heinemeier Hansson, Yehuda Katz, Carl Lerche, Jeremy Kemper, Xavier Noria, Ryan Bates, Geoffrey Grosenbach, Peter Cooper, Matt Aimonetti, Gregg Pollack, Wayne E. Seguin, Amy Hoy, Dave Chelimsky, Pat Maddox, Tom Preston-Werner, Chris Wanstrath, Chad Fowler, Josh Susser, Obie Fernandez, Ian McFarland, Steven Bristol, Pratik Naik, Sarah Mei, Sarah Allen, Wolfram Arnold, Alex Chaffee, Giles Bowkett, Evan Dorn, Long Nguyen, James Lindenbaum, Adam Wiggins, Tikhon Bernstam, Ron Evans, Wyatt Greene, Miles Forrest, the good people at Pivotal Labs, the Heroku gang, the thoughtbot guys, and the GitHub crew. Finally, many, many readers—far too many to list—have contributed a huge number of bug reports and suggestions during the writing of this book, and I gratefully acknowledge their help in making it as good as it can be. <br /></p>
<p> <span class="preamble">
<span id="author">
<strong> About the author</strong> <br />
</span>
</span></p>
<p><a href="http://michaelhartl.com/">Michael Hartl</a> is the author of the <a href="http://ruby.railstutorial.org/"><em>Ruby on Rails Tutorial</em></a>, the leading introduction to web development with <a href="http://rubyonrails.org/">Ruby on Rails</a>. His prior experience includes writing and developing <em>RailsSpace</em>, an extremely obsolete Rails tutorial book, and developing Insoshi, a once-popular and now-obsolete social networking platform in Ruby on Rails. In 2011, Michael received a <a href="http://rubyheroes.com/heroes">Ruby Hero Award</a> for his contributions to the Ruby community. He is a graduate of <a href="http://college.harvard.edu/">Harvard College</a>, has a <a href="http://resolver.caltech.edu/CaltechETD:etd-05222003-161626">Ph.D. in Physics</a> from <a href="http://www.caltech.edu/">Caltech</a>, and is an alumnus of the <a href="http://ycombinator.com/">Y Combinator</a> entrepreneur program. <br /></p>
<p> <span id="license" class="preamble">
<strong> Copyright and license</strong> <br />
</span></p>
<p><em>Ruby on Rails Tutorial: Learn Web Development with Rails</em>. Copyright © 2013 by Michael Hartl. All source code in the <em>Ruby on Rails Tutorial</em> is available jointly under the <a href="http://opensource.org/licenses/MIT">MIT License</a> and the <a href="http://people.freebsd.org/~phk/">Beerware License</a>.</p>
<div class="code"><div class="highlight"><pre>The MIT License
Copyright (c) 2013 Michael Hartl
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:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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.
</pre></div>
</div>
<div class="code"><div class="highlight"><pre>/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Michael Hartl wrote this code. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
</pre></div>
</div>
<div id="top"></div>
<h1 class="chapter"><a id="sec-5" href="filling-in-the-layout.html#top" class="heading"><span class="number">Chapter 5</span> Filling in the layout</a></h1>
<p>In the process of taking a brief tour of Ruby in <a class="ref" href="rails-flavored-ruby.html#top">Chapter 4</a>, we learned about including the application stylesheet into the sample application—but, as noted in <a class="ref" href="rails-flavored-ruby.html#sec-css_revisited">Section 4.3.4</a>, this stylesheet is currently empty. In this chapter, we’ll change this by incorporating the <em>Bootstrap</em> framework into our application, and then we’ll add some custom styles of our own.<sup class="footnote" id="fnref-5_1"><a href="#fn-5_1">1</a></sup> We’ll also start filling in the layout with links to the pages (such as Home and About) that we’ve created so far (<a class="ref" href="filling-in-the-layout.html#sec-structure">Section 5.1</a>). Along the way, we’ll learn about partials, Rails routes, and the asset pipeline, including an introduction to Sass (<a class="ref" href="filling-in-the-layout.html#sec-sass_and_the_asset_pipeline">Section 5.2</a>). We’ll also refactor the tests from <a class="ref" href="static-pages.html#top">Chapter 3</a> using the latest RSpec techniques. We’ll end by taking a first important step toward letting users sign up to our site.</p>
<div class="label" id="sec-structure"></div>
<h2><a id="sec-5_1" href="filling-in-the-layout.html#sec-structure" class="heading"><span class="number">5.1</span> Adding some structure</a></h2>
<p>The <em>Rails Tutorial</em> is a book on web development, not web design, but it would be depressing to work on an application that looks like <em>complete</em> crap, so in this section we’ll add some structure to the layout and give it some minimal styling with CSS. In addition to using some custom CSS rules, we’ll make use of <a href="http://getbootstrap.com/">Bootstrap</a>, an open-source web design framework from Twitter. We’ll also give our <em>code</em> some styling, so to speak, using <em>partials</em> to tidy up the layout once it gets a little cluttered.</p>
<p>When building web applications, it is often useful to get a high-level overview of the user interface as early as possible. Throughout the rest of this book, I will thus often include <em>mockups</em> (in a web context often called <em>wireframes</em>), which are rough sketches of what the eventual application will look like.<sup class="footnote" id="fnref-5_2"><a href="#fn-5_2">2</a></sup> In this chapter, we will principally be developing the static pages introduced in <a class="ref" href="static-pages.html#sec-static_pages">Section 3.1</a>, including a site logo, a navigation header, and a site footer. A mockup for the most important of these pages, the Home page, appears in <a class="ref" href="filling-in-the-layout.html#fig-home_page_mockup">Figure 5.1</a>. You can see the final result in <a class="ref" href="filling-in-the-layout.html#fig-site_with_footer">Figure 5.7</a>. You’ll note that it differs in some details—for example, we’ll end up adding a Rails logo on the page—but that’s fine, since a mockup need not be exact.</p>
<div class="label" id="fig-home_page_mockup"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/home_page_mockup_bootstrap.png" alt="home_page_mockup_bootstrap" /></span></div><div class="caption"><span class="header">Figure 5.1: </span><span class="description">A mockup of the sample application’s Home page. <a href="http://railstutorial.org/images/figures/home_page_mockup_bootstrap-full.png">(full size)</a></span></div></div>
<p>As usual, if you’re using Git for version control, now would be a good time to make a new branch:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> git checkout -b filling-in-layout
</pre></div>
</div>
<div class="label" id="sec-adding_to_the_layout"></div>
<h3><a id="sec-5_1_1" href="filling-in-the-layout.html#sec-adding_to_the_layout" class="heading"><span class="number">5.1.1</span> Site navigation</a></h3>
<p>As a first step toward adding links and styles to the sample application, we’ll update the site layout file <code>application.html.erb</code> (last seen in <a class="ref" href="rails-flavored-ruby.html#code-application_layout_full_title">Listing 4.3</a>) with additional HTML structure. This includes some additional divisions, some CSS classes, and the start of our site navigation. The full file is in <a class="ref" href="filling-in-the-layout.html#code-layout_new_structure">Listing 5.1</a>; explanations for the various pieces follow immediately thereafter. If you’d rather not delay gratification, you can see the results in <a class="ref" href="filling-in-the-layout.html#fig-layout_no_logo_or_custom_css">Figure 5.2</a>. (<em>Note:</em> it’s not (yet) very gratifying.)</p>
<div class="label" id="code-layout_new_structure"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.1.</span> <span class="description">The site layout with added structure. <br /> <code>app/views/layouts/application.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="cp"><!DOCTYPE html></span>
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="nt"><title></span><span class="cp"><%=</span> <span class="n">full_title</span><span class="p">(</span><span class="k">yield</span><span class="p">(</span><span class="ss">:title</span><span class="p">))</span> <span class="cp">%></span><span class="nt"></title></span>
<span class="cp"><%=</span> <span class="n">stylesheet_link_tag</span> <span class="s2">"application"</span><span class="p">,</span> <span class="ss">media:</span> <span class="s2">"all"</span><span class="p">,</span>
<span class="s2">"data-turbolinks-track"</span> <span class="o">=></span> <span class="kp">true</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">javascript_include_tag</span> <span class="s2">"application"</span><span class="p">,</span> <span class="s2">"data-turbolinks-track"</span> <span class="o">=></span> <span class="kp">true</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">csrf_meta_tags</span> <span class="cp">%></span>
<span class="c"><!--[if lt IE 9]></span>
<span class="c"> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script></span>
<span class="c"> <![endif]--></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="nt"><header</span> <span class="na">class=</span><span class="s">"navbar navbar-fixed-top navbar-inverse"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"navbar-inner"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
<span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"sample app"</span><span class="p">,</span> <span class="s1">'#'</span><span class="p">,</span> <span class="nb">id</span><span class="p">:</span> <span class="s2">"logo"</span> <span class="cp">%></span>
<span class="nt"><nav></span>
<span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav pull-right"</span><span class="nt">></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Home"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Help"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Sign in"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"></ul></span>
<span class="nt"></nav></span>
<span class="nt"></div></span>
<span class="nt"></div></span>
<span class="nt"></header></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
<span class="cp"><%=</span> <span class="k">yield</span> <span class="cp">%></span>
<span class="nt"></div></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</pre></div>
</div></div>
<p>Let’s look at the new elements in <a class="ref" href="filling-in-the-layout.html#code-layout_new_structure">Listing 5.1</a> from top to bottom. As alluded to briefly in <a class="ref" href="static-pages.html#sec-passing_title_tests">Section 3.3.2</a>, Rails 4 uses HTML5 by default (as indicated by the doctype <code><!DOCTYPE html></code>); since the HTML5 standard is relatively new, some browsers (especially older versions Internet Explorer) don’t fully support it, so we include some JavaScript code (known as an “<a href="http://code.google.com/p/html5shim/">HTML5 shim</a>”) to work around the issue:</p>
<div class="code"><div class="highlight"><pre><span class="c"><!--[if lt IE 9]></span>
<span class="c"><script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script></span>
<span class="c"><![endif]--></span>
</pre></div>
</div>
<p>The somewhat odd syntax</p>
<div class="code"><div class="highlight"><pre><span class="c"><!--[if lt IE 9]></span>
</pre></div>
</div>
<p>includes the enclosed line only if the version of Microsoft Internet Explorer (IE) is less than 9 (<code>if lt IE 9</code>). The weird <code>[if lt IE 9]</code> syntax is <em>not</em> part of Rails; it’s actually a <a href="http://en.wikipedia.org/wiki/Conditional_comment">conditional comment</a> supported by Internet Explorer browsers for just this sort of situation. It’s a good thing, too, because it means we can include the HTML5 shim <em>only</em> for IE browsers less than version 9, leaving other browsers such as Firefox, Chrome, and Safari unaffected.</p>
<p>The next section includes a <code>header</code> for the site’s (plain-text) logo, a couple of divisions (using the <code>div</code> tag), and a list of elements with navigation links:</p>
<div class="code"><div class="highlight"><pre><span class="nt"><header</span> <span class="na">class=</span><span class="s">"navbar navbar-fixed-top navbar-inverse"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"navbar-inner"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
<span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"sample app"</span><span class="p">,</span> <span class="s1">'#'</span><span class="p">,</span> <span class="nb">id</span><span class="p">:</span> <span class="s2">"logo"</span> <span class="cp">%></span>
<span class="nt"><nav></span>
<span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav pull-right"</span><span class="nt">></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Home"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Help"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Sign in"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"></ul></span>
<span class="nt"></nav></span>
<span class="nt"></div></span>
<span class="nt"></div></span>
<span class="nt"></header></span>
</pre></div>
</div>
<p>Here the <code>header</code> tag indicates elements that should go at the top of the page. We’ve given the <code>header</code> tag three <em>CSS classes</em>,<sup class="footnote" id="fnref-5_3"><a href="#fn-5_3">3</a></sup> called <code>navbar</code>, <code>navbar-fixed-top</code>, and <code>navbar-inverse</code>, separated by spaces:</p>
<div class="code"><div class="highlight"><pre><span class="nt"><header</span> <span class="na">class=</span><span class="s">"navbar navbar-fixed-top navbar-inverse"</span><span class="nt">></span>
</pre></div>
</div>
<p>All HTML elements can be assigned both classes and <em>ids</em>; these are merely labels, and are useful for styling with CSS (<a class="ref" href="filling-in-the-layout.html#sec-custom_css">Section 5.1.2</a>). The main difference between classes and ids is that classes can be used multiple times on a page, but ids can be used only once. In the present case, all the navbar classes have special meaning to the Bootstrap framework, which we’ll install and use in <a class="ref" href="filling-in-the-layout.html#sec-custom_css">Section 5.1.2</a>.</p>
<p>Inside the <code>header</code> tag, we see a couple of <code>div</code> tags:</p>
<div class="code"><div class="highlight"><pre><span class="nt"><div</span> <span class="na">class=</span><span class="s">"navbar-inner"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
</pre></div>
</div>
<p>The <code>div</code> tag is a generic division; it doesn’t do anything apart from divide the document into distinct parts. In older-style HTML, <code>div</code> tags are used for nearly all site divisions, but HTML5 adds the <code>header</code>, <code>nav</code>, and <code>section</code> elements for divisions common to many applications. In this case, each <code>div</code> has a CSS class as well. As with the <code>header</code> tag’s classes, these classes have special meaning to Bootstrap.</p>
<p>After the divs, we encounter some embedded Ruby:</p>
<div class="code"><div class="highlight"><pre><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"sample app"</span><span class="p">,</span> <span class="s1">'#'</span><span class="p">,</span> <span class="nb">id</span><span class="p">:</span> <span class="s2">"logo"</span> <span class="cp">%></span>
<span class="nt"><nav></span>
<span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav pull-right"</span><span class="nt">></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Home"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Help"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Sign in"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"></ul></span>
<span class="nt"></nav></span>
</pre></div>
</div>
<p>This uses the Rails helper <code>link_to</code> to create links (which we created directly with the anchor tag <code>a</code> in <a class="ref" href="static-pages.html#sec-passing_title_tests">Section 3.3.2</a>); the first argument to <code>link_to</code> is the link text, while the second is the URL. We’ll fill in the URLs with <em>named routes</em> in <a class="ref" href="filling-in-the-layout.html#sec-named_routes">Section 5.3.3</a>, but for now we use the stub URL <code>’#’</code> commonly used in web design. The third argument is an options hash, in this case adding the CSS id <code>logo</code> to the sample app link. (The other three links have no options hash, which is fine since it’s optional.) Rails helpers often take options hashes in this way, giving us the flexibility to add arbitrary HTML options without ever leaving Rails.</p>
<p>The second element inside the divs is a list of navigation links, made using the <em>unordered list</em> tag <code>ul</code>, together with the <em>list item</em> tag <code>li</code>:</p>
<div class="code"><div class="highlight"><pre><span class="nt"><nav></span>
<span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav pull-right"</span><span class="nt">></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Home"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Help"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Sign in"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"></ul></span>
<span class="nt"></nav></span>
</pre></div>
</div>
<p>The <code>nav</code> tag, though formally unnecessary here, communicates the purpose of the navigation links. The <code>nav</code> and <code>pull-right</code> classes on the <code>ul</code> tag have special meaning to Bootstrap. Once Rails has processed this layout and evaluated the embedded Ruby, the list looks like this:</p>
<div class="code"><div class="highlight"><pre><span class="nt"><nav></span>
<span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav pull-right"</span><span class="nt">></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Home<span class="nt"></a></li></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Help<span class="nt"></a></li></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Sign in<span class="nt"></a></li></span>
<span class="nt"></ul></span>
<span class="nt"></nav></span>
</pre></div>
</div>
<p>The final part of the layout is a <code>div</code> for the main content:</p>
<div class="code"><div class="highlight"><pre><span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
<span class="cp"><%=</span> <span class="k">yield</span> <span class="cp">%></span>
<span class="nt"></div></span>
</pre></div>
</div>
<p>As before, the <code>container</code> class has special meaning to Bootstrap. As we learned in <a class="ref" href="static-pages.html#sec-layouts">Section 3.3.4</a>, the <code>yield</code> method inserts the contents of each page into the site layout.</p>
<p>Apart from the site footer, which we’ll add in <a class="ref" href="filling-in-the-layout.html#sec-partials">Section 5.1.3</a>, our layout is now complete, and we can look at the results by visiting the Home page. To take advantage of the upcoming style elements, we’ll add some extra elements to
the <code>home.html.erb</code> view (<a class="ref" href="filling-in-the-layout.html#code-signup_button">Listing 5.2</a>).</p>
<div class="label" id="code-signup_button"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.2.</span> <span class="description">The Home page with a link to the signup page. <br /> <code>app/views/static_pages/home.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="nt"><div</span> <span class="na">class=</span><span class="s">"center hero-unit"</span><span class="nt">></span>
<span class="nt"><h1></span>Welcome to the Sample App<span class="nt"></h1></span>
<span class="nt"><h2></span>
This is the home page for the
<span class="nt"><a</span> <span class="na">href=</span><span class="s">"http://railstutorial.org/"</span><span class="nt">></span>Ruby on Rails Tutorial<span class="nt"></a></span>
sample application.
<span class="nt"></h2></span>
<span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Sign up now!"</span><span class="p">,</span> <span class="s1">'#'</span><span class="p">,</span> <span class="ss">class:</span> <span class="s2">"btn btn-large btn-primary"</span> <span class="cp">%></span>
<span class="nt"></div></span>
<span class="cp"><%=</span> <span class="n">link_to</span> <span class="n">image_tag</span><span class="p">(</span><span class="s2">"rails.png"</span><span class="p">,</span> <span class="ss">alt:</span> <span class="s2">"Rails"</span><span class="p">),</span> <span class="s1">'http://rubyonrails.org/'</span> <span class="cp">%></span>
</pre></div>
</div></div>
<p>In preparation for adding users to our site in <a class="ref" href="sign-up.html#top">Chapter 7</a>, the first <code>link_to</code> creates a stub link of the form</p>
<div class="code"><div class="highlight"><pre><span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"btn btn-large btn-primary"</span><span class="nt">></span>Sign up now!<span class="nt"></a></span>
</pre></div>
</div>
<p>In the <code>div</code> tag, the <code>hero-unit</code> CSS class has a special meaning to Bootstrap, as do the <code>btn</code>, <code>btn-large</code>, and <code>btn-primary</code> classes in the signup button.</p>
<p>The second <code>link_to</code> shows off the <code>image_tag</code> helper, which takes as arguments the path to an image and an optional options hash, in this case setting the <code>alt</code> attribute of the image tag using symbols. To make this clearer, let’s look at the HTML this tag produces:<sup class="footnote" id="fnref-5_4"><a href="#fn-5_4">4</a></sup></p>
<div class="code"><div class="highlight"><pre><span class="nt"><img</span> <span class="na">alt=</span><span class="s">"Rails"</span> <span class="na">src=</span><span class="s">"/assets/rails.png"</span> <span class="nt">/></span>
</pre></div>
</div>
<p>(Note that the <code>src</code> attribute <em>doesn’t</em> include <code>images</code>; Rails automatically makes the association of the file with the <code>images</code> directory on the server. Placing all the assets in the same <code>assets</code> directory allows them to be served faster.) The <code>alt</code> attribute is what will be displayed if there is no image, and it is also what will be displayed by screen readers for the visually impaired. Although people are sometimes sloppy about including the <code>alt</code> attribute for images, it is in fact required by the HTML standard. Luckily, Rails includes a default <code>alt</code> attribute; if you don’t specify the attribute in the call to <code>image_tag</code>, Rails just uses the image filename (minus extension). In this case, though, we’ve set the <code>alt</code> text explicitly in order to capitalize “Rails”.</p>
<p>In previous versions of Rails, the <code>rails.png</code> logo was included automatically with every Rails project, but in the latest version it doesn’t get generated as part of <code>rails new</code>, so you should download it from the main Ruby on Rails page at <a href="http://rubyonrails.org/images/rails.png">http://rubyonrails.org/images/rails.png</a> and place it in the <code>app/assets/images/</code> directory. (You may also have to create that directory as well, either with <code>mkdir</code> or with a graphical file manager.) Because we used the <code>image_tag</code> helper in <a class="ref" href="filling-in-the-layout.html#code-signup_button">Listing 5.2</a>, Rails will automatically find any images in that directory using the asset pipeline (<a class="ref" href="filling-in-the-layout.html#sec-sass_and_the_asset_pipeline">Section 5.2</a>).</p>
<p>Now we’re finally ready to see the fruits of our labors (<a class="ref" href="filling-in-the-layout.html#fig-layout_no_logo_or_custom_css">Figure 5.2</a>). Pretty underwhelming, you say? Perhaps so. Happily, though, we’ve done a good job of giving our HTML elements sensible classes, which puts us in a great position to add style to the site with CSS.</p>
<div class="label" id="fig-layout_no_logo_or_custom_css"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/layout_no_logo_or_custom_css_bootstrap_rails_4.png" alt="layout_no_logo_or_custom_css_bootstrap_rails_4" /></span></div><div class="caption"><span class="header">Figure 5.2: </span><span class="description">The Home page (<a href="http://localhost:3000/static_pages/home">/static_pages/home</a>) with no custom CSS. <a href="http://railstutorial.org/images/figures/layout_no_logo_or_custom_css_bootstrap_rails_4-full.png">(full size)</a></span></div></div>
<div class="label" id="sec-custom_css"></div>
<h3><a id="sec-5_1_2" href="filling-in-the-layout.html#sec-custom_css" class="heading"><span class="number">5.1.2</span> Bootstrap and custom CSS</a></h3>
<p>In <a class="ref" href="filling-in-the-layout.html#sec-adding_to_the_layout">Section 5.1.1</a>, we associated many of the HTML elements with CSS classes, which gives us considerable flexibility in constructing a layout based on CSS. As noted in <a class="ref" href="filling-in-the-layout.html#sec-adding_to_the_layout">Section 5.1.1</a>, many of these classes are specific to <a href="http://getbootstrap.com/">Bootstrap</a>, a framework from Twitter that makes it easy to add nice web design and user interface elements to an HTML5 application. In this section, we’ll combine Bootstrap with some custom CSS rules to start adding some style to the sample application.</p>
<p>Our first step is to add Bootstrap, which in Rails applications can be accomplished with the <tt>bootstrap-sass</tt> gem, as shown in <a class="ref" href="filling-in-the-layout.html#code-bootstrap_sass">Listing 5.3</a>. (To fix a version incompatibility, <a class="ref" href="filling-in-the-layout.html#code-bootstrap_sass">Listing 5.3</a> also fixes the version of <em>Sprockets</em>, part of the asset pipeline covered in <a class="ref" href="filling-in-the-layout.html#sec-sass_and_the_asset_pipeline">Section 5.2</a>.) The Bootstrap framework natively uses the <a href="http://lesscss.org/">LESS CSS</a> language for making dynamic stylesheets, but the Rails asset pipeline supports the (very similar) Sass language by default (<a class="ref" href="filling-in-the-layout.html#sec-sass_and_the_asset_pipeline">Section 5.2</a>), so <tt>bootstrap-sass</tt> converts LESS to Sass and makes all the necessary Bootstrap files available to the current application.<sup class="footnote" id="fnref-5_5"><a href="#fn-5_5">5</a></sup></p>
<div class="label" id="code-bootstrap_sass"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.3.</span> <span class="description">Adding the <tt>bootstrap-sass</tt> gem to the <code>Gemfile</code>.</span> </div>
<div class="code"><div class="highlight"><pre><span class="n">source</span> <span class="s1">'https://rubygems.org'</span>
<span class="n">ruby</span> <span class="s1">'2.0.0'</span>
<span class="c1">#ruby-gemset=railstutorial_rails_4_0</span>
<span class="n">gem</span> <span class="s1">'rails'</span><span class="p">,</span> <span class="s1">'4.0.4'</span>
<span class="n">gem</span> <span class="s1">'bootstrap-sass'</span><span class="p">,</span> <span class="s1">'2.3.2.0'</span>
<span class="n">gem</span> <span class="s1">'sprockets'</span><span class="p">,</span> <span class="s1">'2.11.0'</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
</pre></div>
</div></div>
<p>To install Bootstrap, we run <code>bundle install</code> as usual:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle install
</pre></div>
</div>
<p>Then restart the web server to incorporate the changes into the development application. (On most systems, restarting the server will involve pressing <tt>Ctrl-C</tt> and then running <code>rails server</code>.) Finally, as of Rails 4.0 we need to add a line to <code>config/application.rb</code> to make <tt>bootstrap-sass</tt> compatible with the asset pipeline, as shown in <a class="ref" href="filling-in-the-layout.html#code-bootstrap_config">Listing 5.4</a>.</p>
<div class="label" id="code-bootstrap_config"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.4.</span> <span class="description">Adding a line for asset pipeline compatibility. <br /> <code>config/application.rb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="nb">require</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s1">'../boot'</span><span class="p">,</span> <span class="bp">__FILE__</span><span class="p">)</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="k">module</span> <span class="nn">SampleApp</span>
<span class="k">class</span> <span class="nc">Application</span> <span class="o"><</span> <span class="ss">Rails::Application</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="n">config</span><span class="o">.</span><span class="n">assets</span><span class="o">.</span><span class="n">precompile</span> <span class="o">+=</span> <span class="sx">%w(*.png *.jpg *.jpeg *.gif)</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div></div>
<p>The first step in adding custom CSS to our application is to open a file to contain it:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> subl app/assets/stylesheets/custom.css.scss
</pre></div>
</div>
<p>Here both the directory name and filename are important. The directory</p>
<div class="code"><div class="highlight"><pre><span class="go">app/assets/stylesheets</span>
</pre></div>
</div>
<p>is part of the asset pipeline (<a class="ref" href="filling-in-the-layout.html#sec-sass_and_the_asset_pipeline">Section 5.2</a>), and any stylesheets in this directory will automatically be included as part of the <code>application.css</code> file included in the site layout. Furthermore, the filename <code>custom.css.scss</code> includes the <code>.css</code> extension, which indicates a CSS file, and the <code>.scss</code> extension, which indicates a “Sassy CSS” file and arranges for the asset pipeline to process the file using Sass. (We won’t be using Sass until <a class="ref" href="filling-in-the-layout.html#sec-sass">Section 5.2.2</a>, but it’s needed now for the <tt>bootstrap-sass</tt> gem to work its magic.)</p>
<p>Inside the file for custom CSS, we can use the <code>@import</code> function to include Bootstrap, as shown in <a class="ref" href="filling-in-the-layout.html#code-bootstrap_css">Listing 5.5</a>.</p>
<div class="label" id="code-bootstrap_css"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.5.</span> <span class="description">Adding Bootstrap CSS. <br /> <code>app/assets/stylesheets/custom.css.scss</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="k">@import</span> <span class="s2">"bootstrap"</span><span class="p">;</span>
</pre></div>
</div></div>
<p>This one line includes the entire Bootstrap CSS framework, with the result shown in in <a class="ref" href="filling-in-the-layout.html#fig-sample_app_only_bootstrap">Figure 5.3</a>. (You may have to use <tt>Ctrl-C</tt> restart the local web server. It’s also worth noting that the screenshots use Bootstrap 2.0, whereas the tutorial currently uses Bootstrap 2.3, so there may be minor differences in appearance. These are not cause for concern.) The placement of the text isn’t good and the logo doesn’t have any style, but the colors and signup button look promising.</p>
<div class="label" id="fig-sample_app_only_bootstrap"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/sample_app_only_bootstrap_4_0.png" alt="sample_app_only_bootstrap_4_0" /></span></div><div class="caption"><span class="header">Figure 5.3: </span><span class="description">The sample application with Bootstrap CSS. <a href="http://railstutorial.org/images/figures/sample_app_only_bootstrap_4_0-full.png">(full size)</a></span></div></div>
<p>Next we’ll add some CSS that will be used site-wide for styling the layout and each individual page, as shown in <a class="ref" href="filling-in-the-layout.html#code-universal_css">Listing 5.6</a>. There are quite a few rules in <a class="ref" href="filling-in-the-layout.html#code-universal_css">Listing 5.6</a>; to get a sense of what a CSS rule does, it’s often helpful to comment it out using CSS comments, i.e., by putting it inside <code>/* … */</code>, and seeing what changes.
The result of the CSS in <a class="ref" href="filling-in-the-layout.html#code-universal_css">Listing 5.6</a> is shown in <a class="ref" href="filling-in-the-layout.html#fig-sample_app_universal">Figure 5.4</a>.</p>
<div class="label" id="code-universal_css"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.6.</span> <span class="description">Adding CSS for some universal styling applying to all pages. <br /> <code>app/assets/stylesheets/custom.css.scss</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="k">@import</span> <span class="s2">"bootstrap"</span><span class="p">;</span>
<span class="cm">/* universal */</span>
<span class="nt">html</span> <span class="p">{</span>
<span class="na">overflow-y</span><span class="o">:</span> <span class="no">scroll</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">body</span> <span class="p">{</span>
<span class="na">padding-top</span><span class="o">:</span> <span class="mi">60</span><span class="kt">px</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">section</span> <span class="p">{</span>
<span class="na">overflow</span><span class="o">:</span> <span class="no">auto</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">textarea</span> <span class="p">{</span>
<span class="na">resize</span><span class="o">:</span> <span class="n">vertical</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.center</span> <span class="p">{</span>
<span class="na">text-align</span><span class="o">:</span> <span class="no">center</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.center</span> <span class="nt">h1</span> <span class="p">{</span>
<span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div></div>
<div class="label" id="fig-sample_app_universal"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/sample_app_universal_4_0.png" alt="sample_app_universal_4_0" /></span></div><div class="caption"><span class="header">Figure 5.4: </span><span class="description">Adding some spacing and other universal styling. <a href="http://railstutorial.org/images/figures/sample_app_universal_4_0-full.png">(full size)</a></span></div></div>
<p>Note that the CSS in <a class="ref" href="filling-in-the-layout.html#code-universal_css">Listing 5.6</a> has a consistent form. In general, CSS rules refer either to a class, an id, an HTML tag, or some combination thereof, followed by a list of styling commands. For example,</p>
<div class="code"><div class="highlight"><pre><span class="nt">body</span> <span class="p">{</span>
<span class="na">padding-top</span><span class="o">:</span> <span class="mi">60</span><span class="kt">px</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>puts 60 pixels of padding at the top of the page. Because of the <code>navbar-fixed-top</code> class in the <code>header</code> tag, Bootstrap fixes the navigation bar to the top of the page, so the padding serves to separate the main text from the navigation. (Because the default navbar color changed between Boostrap 2.0 and 2.1, we need the <code>navbar-inverse</code> class to make it dark instead of light.) Meanwhile, the CSS in the rule</p>
<div class="code"><div class="highlight"><pre><span class="nc">.center</span> <span class="p">{</span>
<span class="na">text-align</span><span class="o">:</span> <span class="no">center</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>associates the <code>center</code> class with the <code>text-align: center</code> property. In other words, the dot <code>.</code> in <code>.center</code> indicates that the rule styles a class. (As we’ll see in <a class="ref" href="filling-in-the-layout.html#code-logo_css">Listing 5.8</a>, the pound sign <code>#</code> identifies a rule to style a CSS <em>id</em>.) This means that elements inside any tag (such as a <code>div</code>) with class <code>center</code> will be centered on the page. (We saw an example of this class in <a class="ref" href="filling-in-the-layout.html#code-signup_button">Listing 5.2</a>.)</p>
<p>Although Bootstrap comes with CSS rules for nice typography, we’ll also add some custom rules for the appearance of the text on our site, as shown in <a class="ref" href="filling-in-the-layout.html#code-typography_css">Listing 5.7</a>. (Not all of these rules apply to the Home page, but each rule here will be used at some point in the sample application.) The result of <a class="ref" href="filling-in-the-layout.html#code-typography_css">Listing 5.7</a> is shown in <a class="ref" href="filling-in-the-layout.html#fig-sample_app_typography">Figure 5.5</a>.</p>
<div class="label" id="code-typography_css"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.7.</span> <span class="description">Adding CSS for nice typography. <br /> <code>app/assets/stylesheets/custom.css.scss</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="k">@import</span> <span class="s2">"bootstrap"</span><span class="p">;</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="o">/*</span> <span class="nt">typography</span> <span class="o">*/</span>
<span class="nt">h1</span><span class="o">,</span> <span class="nt">h2</span><span class="o">,</span> <span class="nt">h3</span><span class="o">,</span> <span class="nt">h4</span><span class="o">,</span> <span class="nt">h5</span><span class="o">,</span> <span class="nt">h6</span> <span class="p">{</span>
<span class="na">line-height</span><span class="o">:</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">h1</span> <span class="p">{</span>
<span class="na">font-size</span><span class="o">:</span> <span class="mi">3</span><span class="kt">em</span><span class="p">;</span>
<span class="na">letter-spacing</span><span class="o">:</span> <span class="mi">-2</span><span class="kt">px</span><span class="p">;</span>
<span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">30</span><span class="kt">px</span><span class="p">;</span>
<span class="na">text-align</span><span class="o">:</span> <span class="no">center</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">h2</span> <span class="p">{</span>
<span class="na">font-size</span><span class="o">:</span> <span class="mi">1</span><span class="mf">.2</span><span class="kt">em</span><span class="p">;</span>
<span class="na">letter-spacing</span><span class="o">:</span> <span class="mi">-1</span><span class="kt">px</span><span class="p">;</span>
<span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">30</span><span class="kt">px</span><span class="p">;</span>
<span class="na">text-align</span><span class="o">:</span> <span class="no">center</span><span class="p">;</span>
<span class="na">font-weight</span><span class="o">:</span> <span class="no">normal</span><span class="p">;</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#999</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">p</span> <span class="p">{</span>
<span class="na">font-size</span><span class="o">:</span> <span class="mi">1</span><span class="mf">.1</span><span class="kt">em</span><span class="p">;</span>
<span class="na">line-height</span><span class="o">:</span> <span class="mi">1</span><span class="mf">.7</span><span class="kt">em</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div></div>
<div class="label" id="fig-sample_app_typography"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/sample_app_typography_4_0.png" alt="sample_app_typography_4_0" /></span></div><div class="caption"><span class="header">Figure 5.5: </span><span class="description">Adding some typographic styling. <a href="http://railstutorial.org/images/figures/sample_app_typography_4_0-full.png">(full size)</a></span></div></div>
<p>Finally, we’ll add some rules to style the site’s logo, which simply consists of the text “sample app”. The CSS in <a class="ref" href="filling-in-the-layout.html#code-logo_css">Listing 5.8</a> converts the text to uppercase and modifies its size, color, and placement. (We’ve used a CSS id because we expect the site logo to appear on the page only once, but you could use a class instead.)</p>
<div class="label" id="code-logo_css"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.8.</span> <span class="description">Adding CSS for the site logo. <br /> <code>app/assets/stylesheets/custom.css.scss</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="k">@import</span> <span class="s2">"bootstrap"</span><span class="p">;</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="o">/*</span> <span class="nt">header</span> <span class="o">*/</span>
<span class="nn">#logo</span> <span class="p">{</span>
<span class="na">float</span><span class="o">:</span> <span class="no">left</span><span class="p">;</span>
<span class="na">margin-right</span><span class="o">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
<span class="na">font-size</span><span class="o">:</span> <span class="mi">1</span><span class="mf">.7</span><span class="kt">em</span><span class="p">;</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#fff</span><span class="p">;</span>
<span class="na">text-transform</span><span class="o">:</span> <span class="no">uppercase</span><span class="p">;</span>
<span class="na">letter-spacing</span><span class="o">:</span> <span class="mi">-1</span><span class="kt">px</span><span class="p">;</span>
<span class="na">padding-top</span><span class="o">:</span> <span class="mi">9</span><span class="kt">px</span><span class="p">;</span>
<span class="na">font-weight</span><span class="o">:</span> <span class="no">bold</span><span class="p">;</span>
<span class="na">line-height</span><span class="o">:</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="nn">#logo</span><span class="nd">:hover</span> <span class="p">{</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#fff</span><span class="p">;</span>
<span class="na">text-decoration</span><span class="o">:</span> <span class="no">none</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div></div>
<p>Here <code>color: #fff</code> changes the color of the logo to white. HTML colors can be coded with three pairs of base-16 (hexadecimal) numbers, one each for the primary colors red, green, and blue (in that order). The code <code>#ffffff</code> maxes out all three colors, yielding pure white, and <code>#fff</code> is a shorthand for the full <code>#ffffff</code>. The CSS standard also defines a large number of synonyms for common <a href="http://www.w3schools.com/html/html_colornames.asp">HTML colors</a>, including <code>white</code> for <code>#fff</code>. The result of the CSS in <a class="ref" href="filling-in-the-layout.html#code-logo_css">Listing 5.8</a> is shown in <a class="ref" href="filling-in-the-layout.html#fig-sample_app_logo">Figure 5.6</a>.</p>
<div class="label" id="fig-sample_app_logo"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/sample_app_logo_4_0.png" alt="sample_app_logo_4_0" /></span></div><div class="caption"><span class="header">Figure 5.6: </span><span class="description">The sample app with nicely styled logo. <a href="http://railstutorial.org/images/figures/sample_app_logo_4_0-full.png">(full size)</a></span></div></div>
<div class="label" id="sec-partials"></div>
<h3><a id="sec-5_1_3" href="filling-in-the-layout.html#sec-partials" class="heading"><span class="number">5.1.3</span> Partials</a></h3>
<p>Although the layout in <a class="ref" href="filling-in-the-layout.html#code-layout_new_structure">Listing 5.1</a> serves its purpose, it’s getting a little cluttered. The HTML shim takes up three lines and uses weird IE-specific syntax, so it would be nice to tuck it away somewhere on its own. In addition, the header HTML forms a logical unit, so it should all be packaged up in one place. The way to achieve this in Rails is to use a facility called <em>partials</em>. Let’s first take a look at what the layout looks like after the partials are defined (<a class="ref" href="filling-in-the-layout.html#code-layout_with_partials">Listing 5.9</a>).</p>
<div class="label" id="code-layout_with_partials"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.9.</span> <span class="description">The site layout with partials for the stylesheets and header. <br /> <code>app/views/layouts/application.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="cp"><!DOCTYPE html></span>
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="nt"><title></span><span class="cp"><%=</span> <span class="n">full_title</span><span class="p">(</span><span class="k">yield</span><span class="p">(</span><span class="ss">:title</span><span class="p">))</span> <span class="cp">%></span><span class="nt"></title></span>
<span class="cp"><%=</span> <span class="n">stylesheet_link_tag</span> <span class="s2">"application"</span><span class="p">,</span> <span class="ss">media:</span> <span class="s2">"all"</span><span class="p">,</span>
<span class="s2">"data-turbolinks-track"</span> <span class="o">=></span> <span class="kp">true</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">javascript_include_tag</span> <span class="s2">"application"</span><span class="p">,</span> <span class="s2">"data-turbolinks-track"</span> <span class="o">=></span> <span class="kp">true</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">csrf_meta_tags</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">render</span> <span class="s1">'layouts/shim'</span> <span class="cp">%></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="cp"><%=</span> <span class="n">render</span> <span class="s1">'layouts/header'</span> <span class="cp">%></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
<span class="cp"><%=</span> <span class="k">yield</span> <span class="cp">%></span>
<span class="nt"></div></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</pre></div>
</div></div>
<p>In <a class="ref" href="filling-in-the-layout.html#code-layout_with_partials">Listing 5.9</a>, we’ve replaced the HTML shim stylesheet lines with a single call to a Rails helper called <code>render</code>:</p>
<div class="code"><div class="highlight"><pre><span class="cp"><%=</span> <span class="n">render</span> <span class="s1">'layouts/shim'</span> <span class="cp">%></span>
</pre></div>
</div>
<p>The effect of this line is to look for a file called <code>app/views/layouts/_shim.html.erb</code>, evaluate its contents, and insert the results into the view.<sup class="footnote" id="fnref-5_6"><a href="#fn-5_6">6</a></sup> (Recall that <tt class="verb"><%= ... %></tt> is the embedded Ruby syntax needed to evaluate a Ruby expression and then insert the results into the template.) Note the leading underscore on the filename <code>_shim.html.erb</code>; this underscore is the universal convention for naming partials, and among other things makes it possible to identify all the partials in a directory at a glance.</p>
<p>Of course, to get the partial to work, we have to fill it with some content; in the case of the shim partial, this is just the three lines of shim code from <a class="ref" href="filling-in-the-layout.html#code-layout_new_structure">Listing 5.1</a>; the result appears in <a class="ref" href="filling-in-the-layout.html#code-stylesheets_partial">Listing 5.10</a>.</p>
<div class="label" id="code-stylesheets_partial"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.10.</span> <span class="description">A partial for the HTML shim. <br /> <code>app/views/layouts/_shim.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="c"><!--[if lt IE 9]></span>
<span class="c"><script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script></span>
<span class="c"><![endif]--></span>
</pre></div>
</div></div>
<p>Similarly, we can move the header material into the partial shown in <a class="ref" href="filling-in-the-layout.html#code-header_partial">Listing 5.11</a> and insert it into the layout with another call to <code>render</code>.</p>
<div class="label" id="code-header_partial"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.11.</span> <span class="description">A partial for the site header. <br /> <code>app/views/layouts/_header.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="nt"><header</span> <span class="na">class=</span><span class="s">"navbar navbar-fixed-top navbar-inverse"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"navbar-inner"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
<span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"sample app"</span><span class="p">,</span> <span class="s1">'#'</span><span class="p">,</span> <span class="nb">id</span><span class="p">:</span> <span class="s2">"logo"</span> <span class="cp">%></span>
<span class="nt"><nav></span>
<span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav pull-right"</span><span class="nt">></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Home"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Help"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Sign in"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"></ul></span>
<span class="nt"></nav></span>
<span class="nt"></div></span>
<span class="nt"></div></span>
<span class="nt"></header></span>
</pre></div>
</div></div>
<p>Now that we know how to make partials, let’s add a site footer to go along with the header. By now you can probably guess that we’ll call it <code>_footer.html.erb</code> and put it in the layouts directory (<a class="ref" href="filling-in-the-layout.html#code-footer_partial">Listing 5.12</a>).<sup class="footnote" id="fnref-5_7"><a href="#fn-5_7">7</a></sup></p>
<div class="label" id="code-footer_partial"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.12.</span> <span class="description">A partial for the site footer. <br /> <code>app/views/layouts/_footer.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="nt"><footer</span> <span class="na">class=</span><span class="s">"footer"</span><span class="nt">></span>
<span class="nt"><small></span>
<span class="nt"><a</span> <span class="na">href=</span><span class="s">"http://railstutorial.org/"</span><span class="nt">></span>Rails Tutorial<span class="nt"></a></span>
by Michael Hartl
<span class="nt"></small></span>
<span class="nt"><nav></span>
<span class="nt"><ul></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"About"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li></span><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Contact"</span><span class="p">,</span> <span class="s1">'#'</span> <span class="cp">%></span><span class="nt"></li></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"http://news.railstutorial.org/"</span><span class="nt">></span>News<span class="nt"></a></li></span>
<span class="nt"></ul></span>
<span class="nt"></nav></span>
<span class="nt"></footer></span>
</pre></div>
</div></div>
<p>As with the header, in the footer we’ve used <code>link_to</code> for the internal links to the About and Contact pages and stubbed out the URLs with <code>’#’</code> for now. (As with <code>header</code>, the <code>footer</code> tag is new in HTML5.)</p>
<p>We can render the footer partial in the layout by following the same pattern as the stylesheets and header partials (<a class="ref" href="filling-in-the-layout.html#code-layout_with_footer">Listing 5.13</a>).</p>
<div class="label" id="code-layout_with_footer"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.13.</span> <span class="description">The site layout with a footer partial. <br /> <code>app/views/layouts/application.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="cp"><!DOCTYPE html></span>
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="nt"><title></span><span class="cp"><%=</span> <span class="n">full_title</span><span class="p">(</span><span class="k">yield</span><span class="p">(</span><span class="ss">:title</span><span class="p">))</span> <span class="cp">%></span><span class="nt"></title></span>
<span class="cp"><%=</span> <span class="n">stylesheet_link_tag</span> <span class="s2">"application"</span><span class="p">,</span> <span class="ss">media:</span> <span class="s2">"all"</span><span class="p">,</span>
<span class="s2">"data-turbolinks-track"</span> <span class="o">=></span> <span class="kp">true</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">javascript_include_tag</span> <span class="s2">"application"</span><span class="p">,</span> <span class="s2">"data-turbolinks-track"</span> <span class="o">=></span> <span class="kp">true</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">csrf_meta_tags</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">render</span> <span class="s1">'layouts/shim'</span> <span class="cp">%></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="cp"><%=</span> <span class="n">render</span> <span class="s1">'layouts/header'</span> <span class="cp">%></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
<span class="cp"><%=</span> <span class="k">yield</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">render</span> <span class="s1">'layouts/footer'</span> <span class="cp">%></span>
<span class="nt"></div></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</pre></div>
</div></div>
<p>Of course, the footer will be ugly without some styling (<a class="ref" href="filling-in-the-layout.html#code-footer_css">Listing 5.14</a>). The results appear in <a class="ref" href="filling-in-the-layout.html#fig-site_with_footer">Figure 5.7</a>.</p>
<div class="label" id="code-footer_css"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.14.</span> <span class="description">Adding the CSS for the site footer. <br /> <code>app/assets/stylesheets/custom.css.scss</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="nc">.</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="o">/*</span> <span class="nt">footer</span> <span class="o">*/</span>
<span class="nt">footer</span> <span class="p">{</span>
<span class="na">margin-top</span><span class="o">:</span> <span class="mi">45</span><span class="kt">px</span><span class="p">;</span>
<span class="na">padding-top</span><span class="o">:</span> <span class="mi">5</span><span class="kt">px</span><span class="p">;</span>
<span class="na">border-top</span><span class="o">:</span> <span class="mi">1</span><span class="kt">px</span> <span class="no">solid</span> <span class="mh">#eaeaea</span><span class="p">;</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#999</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">footer</span> <span class="nt">a</span> <span class="p">{</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#555</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">footer</span> <span class="nt">a</span><span class="nd">:hover</span> <span class="p">{</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#222</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">footer</span> <span class="nt">small</span> <span class="p">{</span>
<span class="na">float</span><span class="o">:</span> <span class="no">left</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">footer</span> <span class="nt">ul</span> <span class="p">{</span>
<span class="na">float</span><span class="o">:</span> <span class="no">right</span><span class="p">;</span>
<span class="na">list-style</span><span class="o">:</span> <span class="no">none</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">footer</span> <span class="nt">ul</span> <span class="nt">li</span> <span class="p">{</span>
<span class="na">float</span><span class="o">:</span> <span class="no">left</span><span class="p">;</span>
<span class="na">margin-left</span><span class="o">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div></div>
<div class="label" id="fig-site_with_footer"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/site_with_footer_bootstrap_4_0.png" alt="site_with_footer_bootstrap_4_0" /></span></div><div class="caption"><span class="header">Figure 5.7: </span><span class="description">The Home page (<a href="http://localhost:3000/static_pages/home">/static_pages/home</a>) with an added footer. <a href="http://railstutorial.org/images/figures/site_with_footer_bootstrap_4_0-full.png">(full size)</a></span></div></div>
<div class="label" id="sec-sass_and_the_asset_pipeline"></div>
<h2><a id="sec-5_2" href="filling-in-the-layout.html#sec-sass_and_the_asset_pipeline" class="heading"><span class="number">5.2</span> Sass and the asset pipeline</a></h2>
<p>One of the most notable additions in recent versions of Rails is the asset pipeline, which significantly improves the production and management of static assets such as CSS, JavaScript, and images. This section gives a high-level overview of the asset pipeline and then shows how to use a remarkable tool for making CSS called <em>Sass</em>, now included by default as part of the asset pipeline.</p>
<div class="label" id="sec-the_asset_pipeline"></div>
<h3><a id="sec-5_2_1" href="filling-in-the-layout.html#sec-the_asset_pipeline" class="heading"><span class="number">5.2.1</span> The asset pipeline</a></h3>
<p>The asset pipeline involves lots of changes under Rails’ hood, but from the perspective of a typical Rails developer there are three principal features to understand: asset directories, manifest files, and preprocessor engines.<sup class="footnote" id="fnref-5_8"><a href="#fn-5_8">8</a></sup> Let’s consider each in turn.</p>
<h4><a id="sec-5_2_1_1" href="filling-in-the-layout.html#sec-5_2_1_1" class="heading">Asset directories</a></h4>
<p>In versions of Rails before 3.0 (including 3.0 itself), static assets lived in the <code>public/</code> directory, as follows:</p>
<ul>
<li><code>public/stylesheets</code></li>
<li><code>public/javascripts</code></li>
<li><code>public/images</code></li>
</ul>
<p>Files in these directories are (even post-3.0) automatically served up via requests to http://example.com/stylesheets, etc.</p>
<p>Starting in Rails 3.1, and continuing in Rails 4, there are <em>three</em> canonical directories for static assets, each with its own purpose:</p>
<ul>
<li><code>app/assets</code>: assets specific to the present application</li>
<li><code>lib/assets</code>: assets for libraries written by your dev team</li>
<li><code>vendor/assets</code>: assets from third-party vendors</li>
</ul>
<p>As you might guess, each of these directories has a subdirectory for each asset class, e.g.,</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> ls app/assets/
<span class="go">images javascripts stylesheets</span>
</pre></div>
</div>
<p>At this point, we’re in a position to understand the motivation behind the location of the <code>custom.css.scss</code> file in <a class="ref" href="filling-in-the-layout.html#sec-custom_css">Section 5.1.2</a>: <code>custom.css.scss</code> is specific to the sample application, so it goes in <code>app/assets/stylesheets</code>.</p>
<h4><a id="sec-5_2_1_2" href="filling-in-the-layout.html#sec-5_2_1_2" class="heading">Manifest files</a></h4>
<p>Once you’ve placed your assets in their logical locations, you can use <em>manifest files</em> to tell Rails (via the <a href="https://github.com/sstephenson/sprockets">Sprockets</a> gem) how to combine them to form single files. (This applies to CSS and JavaScript but not to images.) As an example, let’s take a look at the default manifest file for app stylesheets (<a class="ref" href="filling-in-the-layout.html#code-app_css_manifest">Listing 5.15</a>).</p>
<div class="label" id="code-app_css_manifest"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 5.15.</span> <span class="description">The manifest file for app-specific CSS. <br /> <code>app/assets/stylesheets/application.css</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="cm">/*</span>
<span class="cm"> * This is a manifest file that'll automatically include all the stylesheets</span>
<span class="cm"> * available in this directory and any sub-directories. You're free to add</span>
<span class="cm"> * application-wide styles to this file and they'll appear at the top of the</span>
<span class="cm"> * compiled file, but it's generally better to create a new file per style</span>
<span class="cm"> * scope.</span>
<span class="cm"> *= require_self</span>
<span class="cm"> *= require_tree .</span>
<span class="cm">*/</span>
</pre></div>
</div></div>
<p>The key lines here are actually CSS comments, but they are used by Sprockets to include the proper files:</p>
<div class="code"><div class="highlight"><pre><span class="cm">/*</span>
<span class="cm"> .</span>
<span class="cm"> .</span>
<span class="cm"> .</span>
<span class="cm"> *= require_self</span>
<span class="cm"> *= require_tree .</span>
<span class="cm">*/</span>
</pre></div>
</div>
<p>Here</p>
<div class="code"><div class="highlight"><pre><span class="go">*= require_tree .</span>
</pre></div>
</div>
<p>ensures that all CSS files in the <code>app/assets/stylesheets</code> directory (including the tree subdirectories) are included into the application CSS. The line</p>
<div class="code"><div class="highlight"><pre><span class="go">*= require_self</span>
</pre></div>
</div>
<p>specifies where in the loading sequence the CSS in <code>application.css</code> itself gets included.</p>
<p>Rails comes with sensible default manifest files, and in the <em>Rails Tutorial</em> we won’t need to make any changes, but the <a href="http://guides.rubyonrails.org/asset_pipeline.html">Rails Guides entry on the asset pipeline</a> has more detail if you need it.</p>
<h4><a id="sec-5_2_1_3" href="filling-in-the-layout.html#sec-5_2_1_3" class="heading">Preprocessor engines</a></h4>
<p>After you’ve assembled your assets, Rails prepares them for the site template by running them through several preprocessing engines and using the manifest files to combine them for delivery to the browser. We tell Rails which processor to use using filename extensions; the three most common cases are <code>.scss</code> for Sass, <code>.coffee</code> for CoffeeScript, and <code>.erb</code> for embedded Ruby (ERb). We first covered ERb in <a class="ref" href="static-pages.html#sec-embedded_ruby">Section 3.3.3</a>, and cover Sass in <a class="ref" href="filling-in-the-layout.html#sec-sass">Section 5.2.2</a>. We won’t be needing CoffeeScript in this tutorial, but it’s an elegant little language that compiles to JavaScript. (The <a href="http://railscasts.com/episodes/267-coffeescript-basics">RailsCast on CoffeeScript basics</a> is a good place to start.)</p>
<p>The preprocessor engines can be chained, so that</p>
<p><code>foobar.js.coffee</code></p>
<p>gets run through the CoffeeScript processor, and</p>
<p><code>foobar.js.erb.coffee</code></p>
<p>gets run through both CoffeeScript and ERb (with the code running from right to left, i.e., CoffeeScript first).</p>
<h4><a id="sec-5_2_1_4" href="filling-in-the-layout.html#sec-5_2_1_4" class="heading">Efficiency in production</a></h4>
<p>One of the best things about the asset pipeline is that it automatically results in assets that are optimized to be efficient in a production application. Traditional methods for organizing CSS and JavaScript involve splitting functionality into separate files and using nice formatting (with lots of indentation). While convenient for the programmer, this is inefficient in production; including multiple full-sized files can significantly slow page-load times (one of the most important factors affecting the quality of the user experience). With the asset pipeline, in production all the application stylesheets get rolled into one CSS file (<code>application.css</code>), all the application JavaScript code gets rolled into one JavaScript file (<code>javascripts.js</code>), and all such files (including those in <code>lib/assets</code> and <code>vendor/assets</code>) are <em>minified</em> to remove the unnecessary whitespace that bloats file size. As a result, we get the best of both worlds: multiple nicely formatted files for programmer convenience, with single optimized files in production.</p>
<div class="label" id="sec-sass"></div>
<h3><a id="sec-5_2_2" href="filling-in-the-layout.html#sec-sass" class="heading"><span class="number">5.2.2</span> Syntactically awesome stylesheets</a></h3>
<p><em>Sass</em> is a language for writing stylesheets that improves on CSS in many ways. In this section, we cover two of the most important improvements, <em>nesting</em> and <em>variables</em>. (A third technique, <em>mixins</em>, is introduced in <a class="ref" href="sign-up.html#sec-rails_environments">Section 7.1.1</a>.)</p>
<p>As noted briefly in <a class="ref" href="filling-in-the-layout.html#sec-custom_css">Section 5.1.2</a>, Sass supports a format called SCSS (indicated with a <code>.scss</code> filename extension), which is a strict superset of CSS itself; that is, SCSS only <em>adds</em> features to CSS, rather than defining an entirely new syntax.<sup class="footnote" id="fnref-5_9"><a href="#fn-5_9">9</a></sup> This means that every valid CSS file is also a valid SCSS file, which is convenient for projects with existing style rules. In our case, we used SCSS from the start in order to take advantage of Bootstrap. Since the Rails asset pipeline automatically uses Sass to process files with the <code>.scss</code> extension, the <code>custom.css.scss</code> file will be run through the Sass preprocessor before being packaged up for delivery to the browser.</p>
<h4><a id="sec-5_2_2_1" href="filling-in-the-layout.html#sec-5_2_2_1" class="heading">Nesting</a></h4>
<p>A common pattern in stylesheets is having rules that apply to nested elements. For example, in <a class="ref" href="filling-in-the-layout.html#code-universal_css">Listing 5.6</a> we have rules both for <code>.center</code> and for <code>.center h1</code>:</p>
<div class="code"><div class="highlight"><pre><span class="nc">.center</span> <span class="p">{</span>
<span class="na">text-align</span><span class="o">:</span> <span class="no">center</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.center</span> <span class="nt">h1</span> <span class="p">{</span>
<span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>We can replace this in Sass with</p>
<div class="code"><div class="highlight"><pre><span class="nc">.center</span> <span class="p">{</span>
<span class="na">text-align</span><span class="o">:</span> <span class="no">center</span><span class="p">;</span>
<span class="nt">h1</span> <span class="p">{</span>
<span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Here the nested <code>h1</code> rule automatically inherits the <code>.center</code> context.</p>
<p>There’s a second candidate for nesting that requires a slightly different syntax. In <a class="ref" href="filling-in-the-layout.html#code-logo_css">Listing 5.8</a>, we have the code</p>
<div class="code"><div class="highlight"><pre><span class="nn">#logo</span> <span class="p">{</span>
<span class="na">float</span><span class="o">:</span> <span class="no">left</span><span class="p">;</span>
<span class="na">margin-right</span><span class="o">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
<span class="na">font-size</span><span class="o">:</span> <span class="mi">1</span><span class="mf">.7</span><span class="kt">em</span><span class="p">;</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#fff</span><span class="p">;</span>
<span class="na">text-transform</span><span class="o">:</span> <span class="no">uppercase</span><span class="p">;</span>
<span class="na">letter-spacing</span><span class="o">:</span> <span class="mi">-1</span><span class="kt">px</span><span class="p">;</span>
<span class="na">padding-top</span><span class="o">:</span> <span class="mi">9</span><span class="kt">px</span><span class="p">;</span>
<span class="na">font-weight</span><span class="o">:</span> <span class="no">bold</span><span class="p">;</span>
<span class="na">line-height</span><span class="o">:</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="nn">#logo</span><span class="nd">:hover</span> <span class="p">{</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#fff</span><span class="p">;</span>
<span class="na">text-decoration</span><span class="o">:</span> <span class="no">none</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Here the logo id <code>#logo</code> appears twice, once by itself and once with the <code>hover</code> attribute (which controls its appearance when the mouse pointer hovers over the element in question). In order to nest the second rule, we need to reference the parent element <code>#logo</code>; in SCSS, this is accomplished with the ampersand character <code>&</code> as follows:</p>
<div class="code"><div class="highlight"><pre><span class="nn">#logo</span> <span class="p">{</span>
<span class="na">float</span><span class="o">:</span> <span class="no">left</span><span class="p">;</span>
<span class="na">margin-right</span><span class="o">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
<span class="na">font-size</span><span class="o">:</span> <span class="mi">1</span><span class="mf">.7</span><span class="kt">em</span><span class="p">;</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#fff</span><span class="p">;</span>
<span class="na">text-transform</span><span class="o">:</span> <span class="no">uppercase</span><span class="p">;</span>
<span class="na">letter-spacing</span><span class="o">:</span> <span class="mi">-1</span><span class="kt">px</span><span class="p">;</span>
<span class="na">padding-top</span><span class="o">:</span> <span class="mi">9</span><span class="kt">px</span><span class="p">;</span>
<span class="na">font-weight</span><span class="o">:</span> <span class="no">bold</span><span class="p">;</span>
<span class="na">line-height</span><span class="o">:</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">&</span><span class="nd">:hover</span> <span class="p">{</span>
<span class="na">color</span><span class="o">:</span> <span class="mh">#fff</span><span class="p">;</span>
<span class="na">text-decoration</span><span class="o">:</span> <span class="no">none</span><span class="p">;</span>
<span class="p">}</span>