12/08/2018, 16:43
All about layout in Rails
Trong Rails, layout là tập tin định nghĩa các đoạn html bao quanh template được render bởi action của các controller. Một layout có thể được sử dụng bởi nhiều controller khác nhau. Bài viết này sẽ sử dụng UsersController có 2 action là index và new để làm ví dụ về cách sử dụng các ...
- Trong Rails, layout là tập tin định nghĩa các đoạn html bao quanh template được render bởi action của các controller.
- Một layout có thể được sử dụng bởi nhiều controller khác nhau.
- Bài viết này sẽ sử dụng UsersController có 2 action là index và new để làm ví dụ về cách sử dụng các layout trong Rails.
1. Application layout:
- Khi khởi tạo rails project, ApplicationController và file layouts/application.html.erb được tạo ra.
- Dòng code <%= yield %> sẽ chỉ định nơi template của action của các controller được render bên trong layout.
<!DOCTYPE html> <html> <head> <title>Layout</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track": "reload" %> <%= javascript_include_tag "application", "data-turbolinks-track": "reload" %> </head> <body> <h1>Application Layout</h1> <%= yield %> </body> </html>
- Khi các controller khác thực hiện kế thừa ApplicationController thì cũng kế thừa luôn layout của ApplicationController.
class UsersController < ApplicationController def index end def new end end
- Khi đó teamplete được render bởi các action của UsersController sẽ được render bên trong layouts/application.html.erb
2. Controller specific layout:
- Khi một file layout được tạo ra có tên trùng với tên của controller thì tập tin đó sẽ được sử dụng như layout của controller có tên tương ứng thay cho file layouts/application.html.erb.
- Để tạo controller specific layout cho UsersController, ta tạo file layouts/users.html.erb
<!DOCTYPE html> <html> <head> <title>Layout</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track": "reload" %> <%= javascript_include_tag "application", "data-turbolinks-track": "reload" %> </head> <body> <h1>Users Layout</h1> <%= yield %> </body> </html>
- Khi đó các template được render bởi các acton của controller UsersController sẽ được render bên trong layouts/users.html.erb
- Nếu muốn sử dụng layout khác thay cho layouts/users.html.erb cho tất cả các action của UsersController, ta có thể sử dụng phương thức layout() và truyền vào tên của layout ta muốn sử dụng.
class UsersController < ApplicationController layout "application" def index end def new end end
- Ta có thể thêm tham số only hoặc except vào hàm layout() để chỉ định các action sử dụng hoặc không sử dụng layout được truyển vào trong hàm.
- Các action không sử dụng layout được truyền vào hàm sẽ sử dụng layout mặc định của UsersController, trong trường hợp này là layouts/users.html.erb
class UsersController < ApplicationController layout "application", only: :new def index end def new end end
3. Dynamic layout:
- Khi gặp trường hợp layout của action có thể thay đổi tùy theo trường hợp, không còn cố định là application layout hoặc controller specific layout, ta có thể dử dụng dynamic layout.
- Ví dụ đối với UserController, khi user là admin thì ta sử dụng layouts/admin.html.erb, khi là user thường thì ta sử dụng layouts/user.html.erb
- Nội dung file layouts/admin.html.erb
<!DOCTYPE html> <html> <head> <title>Layout</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track": "reload" %> <%= javascript_include_tag "application", "data-turbolinks-track": "reload" %> </head> <body> <h1>Admin Layout</h1> <%= yield %> </body> </html>
- Khi đó ta sử dụng hàm layout() và truyền vào symboy tên hàm xử lý việc chọn layout.
class UsersController < ApplicationController layout :dynamic_layout def index end def new end private def dynamic_layout if true # replace for if current_user.admin? "admin" else "users" end end end
- Kết quả thu được
- https://github.com/LeTanThanh/layout