#329 More on Twitter Bootstrap pro
- Download:
- source codeProject Files in Zip (167 KB)
- mp4Full Size H.264 Video (35.7 MB)
- m4vSmaller H.264 Video (17.3 MB)
- webmFull Size VP8 Video (16.9 MB)
- ogvFull Size Theora Video (44.3 MB)
이전 연제에서는 레일스에서 트위터 부트스트랩을 사용하는 방법에 대해서 알아봤습니다. 이번 연제에서는 지난 번에 시작했던 프로젝트에 기능을 추가해 보도록 하겠습니다. Simple Form을 이용하여 폼을 개선하는 방법과 LESS를 이용하여 트위터 부트스트랩을 입맛에 맞게 변경하는 방법, 그리고 SASS를 선호할 경우 LESS에서 SASS로 전환하는 방법에 대해서 알아 보도록 하겠습니다.
사용자 경험 개선하기
아래는 지난번 연제에서 마지막으로 작업을 마쳤던 내용입니다. 이번 연제에서는 이 어플리케이션이 가지고 있는 사용자 경험상의 몇가지 문제점들에 초점을 맞추어 시작하고자 합니다.
여러가지 문제점 중에 하나는 flash 메시지가 보이지 않는 것입니다. 수정 폼을 이용해서 product에 대한 데이터를 업데이트하더라도 product가 업데이트되었다는 어떠한 flash 메시지도 보이지 않습니다. 문서 내용 중의 components 섹션을 보면 Alerts에 대한 내용이 있는데, 사용자에게 flash 메시지를 보여주는 완벽한 해결방법이 소개되어 있습니다. 기본 옵션에는 success(성공), information(안내), warning(경고) 세가지 alert 형이 있습니다. 업데이트 메시지를 보여주기 위해서는 flash 메시지를 alert-success
클래스를 가지는 div
태그로 감싸주기만 하면 됩니다.
이제, 어플리케이션 레이아웃 파일의 container
내부에, 특히 페이지 내용 이전에, flash 메시지를 추가할 것입니다.
<div class="container"> <% flash.each do |name, msg| %> <div class="alert alert-<%= name == :notice ? "success" : "error" %>"> <%= msg %> </div> <% end %> <!-- Rest of content --> </div>
여기서 flash 메시지들을 루프를 돌려서 하나씩 보여 주게 됩니다. 각각의 메시지를 div
태그로 감싸고 flash 메시지의 이름을 이용해서 success alert 또는 error alert 중에 어떤 것을 보여 줄 것인지를 결정합니다.
트위터 부트스트랩은 alert 클래스를 가지는 div
태그에 닫기 버튼을 쉽게 추가할 수 있어서 코드라인 하나만 추가하기만 하면 됩니다.
<div class="container"> <% flash.each do |name, msg| %> <div class="alert alert-<%= name == :notice ? "success" : "error" %>"> <a class="close" data-dismiss="alert">x</a> <%= msg %> </div> <% end %> <!-- Rest of content --> </div>
이제 product를 업데이트하면 ‘x’ 버튼이 보이게 될 것이고 이것을 클릭하면 alert가 사라지게 될 것입니다.
이 기능은 자바스트립트로 구현되어 있습니다. 아직 부트스트랩에 제공하는 자바스크립에 대해서 많은 것을 말하지 않았지만 여기에는 상당히 많은 유용한 jQuery 플러그인 들이 있습니다. 이것들을 이용하면 modal dialog, drowpdown, tab, tooltip, 마우스를 엘리먼트 위로 이동하면 정보를 보여주는 popover, 그리고 그 외에도 많은 것을 만들 수 있습니다. 이 모든 플러그인들은 이미 레일스 어플리케이션에 포함되어 있습니다. application.js
파일을 들여다 보면 twitter/bootstrap
파일이 포함되어 있는 것을 알 수 있는데 이것이 모든 플러그인들을 로드하게 되는 것입니다. 또한 bootstrap.js
파일은 일부 플러그인들의 기능을 가능하게 해 줍니다.
jQuery -> $("a[rel=popover]").popover() $(".tooltip").tooltip() $("a[rel=tooltip]").tooltip()
유효성 검증하기
작업 중인 레일스 어플리케이션에서 사용자 경험을 개선할 수 있는 다른 것으로는 폼(form), 특히, 유효성검증에 대한 것입니다. 아직 Product
모델에는 유효성 검증이 없기 때문에 검증 코드를 추가하여 시작해 보겠습니다.
class Product < ActiveRecord::Base validates_presence_of :name, :price end
product를 수정하여 특정 필드를 blank로 남겨두게 되면 다시 폼으로 돌아오게 되지만 에러의 원인을 알려주는 어떠한 메시지도 보이지 않습니다. 트위터 부트스트랩은 이러한 에러 메시지를 폼에서 보여주는 멋진 방법을 제공해 주는데, 유효하지 않는 필드에 대한 폼 필드에 색상으로 표시를 해 줍니다. 여기서도 Product
폼에 이것을 이용할 것입니다. 이 때에 발생하는 문제는 폼을 구성하는 마크업 태그들이 현재 상태에서도 꽤나 복잡하다는 것입니다. 즉, 여기에 유효성 검증을 위해서 로직을 추가한다면 페이지는 금방 복잡해 질 것입니다.
<%= form_for @product, :html => { :class => 'form-horizontal' } do |f| %> <fieldset> <legend><%= controller.action_name.capitalize %> Product</legend> <div class="control-group"> <%= f.label :name, :class => 'control-label' %> <div class="controls"> <%= f.text_field :name, :class => 'text_field' %> </div> </div> <div class="control-group"> <%= f.label :price, :class => 'control-label' %> <div class="controls"> <%= f.text_field :price, :class => 'text_field' %> </div> </div> <div class="form-actions"> <%= f.submit nil, :class => 'btn btn-primary' %> <%= link_to 'Cancel', products_path, :class => 'btn' %> </div> </fieldset> <% end %>
gem 'simple_form'
다음에는, SimpleForm 설치 제너레이터를 실행할 것입니다. 주목할 것은 이 때 --bootstrap
옵션을 사용하여 트위터 부트스트랩용이 사용되도록 했다는 것입니다.
$ rails g simple_form:install --bootstrap
이제 현재 폼 대신에 SimpleForm을 사용할 수 있게 되엇습니다. 폼의 상단에서 form_for
대신에 simple_form_for
으로 변경하면 Simpleform의 input 메소드를 이용해서 name과 price 필드를 정의할 수 있게 됩니다.
<%= simple_form_for @product, :html => { :class => 'form-horizontal' } do |f| %> <fieldset> <legend><%= controller.action_name.capitalize %> Product</legend> <%= f.input :name %> <%= f.input :price %> <div class="form-actions"> <%= f.submit nil, :class => 'btn btn-primary' %> <%= link_to 'Cancel', products_path, :class => 'btn' %> </div> </fieldset> <% end %>
SimpleForm의 동작 방법을 잘 알지 못할 경우에는 이에 대해 자세히 다룬 234번 연제를 보기 바랍니다. 이제 페이지를 다시 로드하고 name 필드를 비운 상태에서 product를 업데이트한다면 name 필드 옆에 에러 메시지가 보일 것입니다.
폼 스타일을 입맛에 맞게 변경하기
어플리케이션이 이전보다 더 좋게 보이지만 좀 더 우리의 입맛에 맞게 수정해서 독특하게 만들고자 한다면 어떻게 해야 할까요? 예를 들면, 링크와 버튼의 색상은 바꾸고자 하거나 헤더부분의 모양을 변경하고자 할 때는 어떻게 해야 할까요? 문서의 Using LESS 부분을 보면 여러가지 변수들이 정의되어 있는데, 이것들을 수정하면 웹사이트의 모양을 바꿀 수가 있게 됩니다. 즉, 색상, 크기 등을 변경할 수 있습니다. 이 페이지에는 모든 변수들이 열거되어 있지 않지만 소스코드를 보면 모든 변수들을 다 볼 수 있습니다.
이 변수들은 variables.less
파일에 정의되어 있는데 여기서 열거된 것들 중에 몇개는 문서상에 언급되어 있지 않습니다. bootstrap_and_overrides.css.less
파일에서 이러한 변수들을 설정할 수 있습니다. 이 때 주의해야 할 것은 파일 상단에 있는 bootstrap
파일을 불러 들이는 코드라인 이후에 변수들의 값을 지정해야 한다는 것입니다. iconSpritePath
와 iconWhiteSpritePath
, 이 두개의 변수는 이미 이 파일에서 설정이 되어 있고 다른 변수값들을 설정하는 방법에 대한 설명도 볼 수 있습니다.
@import "twitter/bootstrap/bootstrap"; body { padding-top: 60px; } @import "twitter/bootstrap/responsive"; // Set the correct sprite paths @iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png'); @iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png'); // Your custom LESS stylesheets goes here // // Since bootstrap was imported above you have access to its mixins which // you may use and inherit here // // If you'd like to override bootstrap's own variables, you can do so here as well // See http://twitter.github.com/bootstrap/less.html for their names and documentation // // Example: // @linkColor: #ff0000;
예를 들어, 헤더부분을 밝게 하고 싶다고 가정해 봅시다. 아래와 같이 변수값들을 설정해 주면 됩니다.
@navbarBackground: #555; @navbarBackgroundHighlight: #888; @navbarText: #eee; @navbarLinkColor: #eee;
페이지를 다시 로드하면 헤더부분이 밝은 회색톤으로 변경될 것입니다.
그러나 어떤 것들은 변수값을 설정해도 쉽게 변경되지 않을 수 있습니다. 헤더의 brand 텍스트를 변경할 경우을 생각해 보겠습니다. 이 색상값을 정의하는 CSS는 navbar.less
파일에 있기 때문에 이 헤더를 정의하는 brand
클래스를 보면 @white
변수에 정의된 값을 기준으로 색상을 지정하고 있다는 것을 알게 될 것입니다. 따라서 이 변수값을 변경해도 되겠지만, 이렇게 되면 원치않는 부작용이 수반될 수도 있습니다. 단지 특정 장소에서만 이 색상값을 변경하고자 하므로 변수값을 변경하는 것은 이런 상황에서는 약간 제한점이 있게 됩니다. 그러나 이 문제는 뭐 그리 대단한 이슈꺼리가 되지는 않습니다. CSS로 작업을 하고 있기 때문에 bootstrap_and_overrides
에서 기본 스타일 변수값을 변경할 수 있습니다.
.navbar .brand { color: #FAFFB8; }
이제 brand 텍스트는 연한 노랑색을 띄게 됩니다. 뭐 이것이 최선의 디자인은 아니지만, 이렇게 해 봄으로써 우리가 원하는데로 스타일을 변경할 수 있는 방법을 알게 되었다는데 의미를 찾을 수 있습니다.
포함시킬 파일 정하기
어플리케이션 개발이 진행되면서 사용하지 않는 트위터 부트스트랩의 부분이 있다는 것을 알게 될 것입니다. 크라언트로 보내지는 코드량을 줄이기 위해서 이런 부분을 제거하는 것은 바람직한 일일 것입니다. 부투스트랩 웹사이트에 있는 유용한 페이지를 보면 우리가 포함시키고자하는 부분을 선택하여 다운로드받을 수 있게 해 줍니다. 그러나 이것은 정적(변수값이 이미 정해져 있는) 파일이어서 LESS를 사용할 때는 적절치 못합니다. 대신에 레일스 어플리케이션에 불러오게 될 파일들을 수정해서 사용해야 합니다. bootstrap_and_overrides
파일은 twitter/bootstrap/bootstrap
를 불러들이는데 이 파일의 소스코드를 보게 되면 이 파일이 또 다시 많은 파일들을 불러들인다는 것을 알게 되는데, 이러한 것을 잘 이용하면 정확하게 우리가 불러들이고자 하는 파일들을 지정할 수 있게 됩니다.
이렇게 하기 위해서는, bootstrap_and_overrides
페이지 상단에 있는 @import "twitter/bootstrap/bootstrap";
코드라인을 bootstrap.less
파일에 있는 내용으로 교체해 주어야 합니다. 이것은 기본적으로 동일한 효과를 보일 것이지만, 이제 부트스트랩에서 포함시킬 파트들을 정확하게 지정해 줄 수 있게 됩니다. 자바스크립트에 대해서 동일하게 적용할 수 있습니다. bootstrap.js
파일은 부트스트랩이 제공하는 모든 jQuery 플러그인을 불러들이기 때문에, application.js
파일에서 //=require twitter/bootstrap
라인을 그 파일의 내용으로 교체하여 우리가 정확하게 필요로하는 것들만 선택하면 됩니다.
LESS 대신 SASS 사용하기
원할 경우 LESS 대신 SASS를 사용하는 방법을 소개하고 이번 연제를 마치도록 하겠습니다. LESS 보다 SASS를 선택하게 되는 이유는 무엇입니까? 트위터 부트스트랩의 스타일을 광범위하게 수정하여 사용하고자 한다면 SASS를 사용해야 합니다. 그 이유에 대해서는 less-rails와 less-rails-bootstrap 젬을 만든 Ken Collins가 작성한 최근의 블로그 게시물에 잘 설명되어 있습니다.
asset pipeline을 사용할 때 동일한 어플리케이션에서 SASS와 LESS 를 동시에 사용할 수는 있습니다. 예를 들면, 이전에 이미 변경한 바 있는 navbar의 brand와 같이, CSS로 무언가를 변경하고 할 때는, 이것을 .css.scss
파일로 옮길 수는 있지만, bootstrap_and_overrides
가 먼저 로드되어야 합니다. 그러나 이러한 방법의 제한점은 트위터 부트스트랩의 변수와 mix-in들이 LESS코드로 정의되었기 때문에 SASS파일로 옮겨진 코드는 이들과 상호작용을 할 수 없다는 것입니다.
SASS를 사용해서 이들 변수와 mix-in들과 상호작용을 하기 원한다면 bootstrap-sass
젬을 사용해야 합니다. 이 젬은 트위터 부트스트랩을 SASS로 변환하여 부트스트랩의 변수들과 상호작용하여 변수값들을 변경할 수 있게 해 줍니다. 이제 어플리케이션을 LESS를 사용하는 twitter-bootstrap-rails
젬으로부터 bootstrap-sass
로 전환하는 방법을 알아보도록 하겠습니다. 먼저, gemfile에 있는 이전 젬을 교체해서 bundle
명령을 다시 실행합니다.
gem 'bootstrap-sass'
다음으로 bootstrap_and_overrides.css.less
파일명의 마지막 확장자를 .scss
으로 변경해 줍니다. 그리고 나서 이 파일의 내용을 SASS 코드로 바꿔줍니다.
// Set the correct sprite paths $iconSpritePath: image-path('glyphicons-halflings.png'); $iconWhiteSpritePath: image-path('glyphicons-halflings-white.png'); $navbarBackground: #555; $navbarBackgroundHighlight: #888; $navbarText: #eee; $navbarLinkColor: #eee; @import "bootstrap"; body { padding-top: 60px; } @import "bootstrap-responsive"; .navbar .brand { color: #FAFFB8; }
한가지 중요한 차이점은 SASS와 LESS가 동작하는 방식의 차이 때문에 bootstrap
을 로드하기 전에 변수들을 설정해 주어야 한다는 것입니다. 이렇게 부트스트랩이 로드된 후에 변경하고자 하는 CSS 코드를 추가해 주면 됩니다.
application.js
파일에서는 twitter/bootstrap
대신에 bootstrap
으로 변경해 주어야 합니다. 이전과 같이 특정 플러그인만 로드하고자 한다면 개별 파일들을 별도로 로드할 수 있습니다. bootstrap-sass의 README 파일에는 이런 방법에 대한 예가 포함되어 있습니다. 이제 어플리케이션을 다시 로드하면 이전과 동일하게 보일 것이지만, LESS 대신에 SASS를 사용하고 있는 것입니다.