diff --git a/docs/views.md b/docs/views.md index 429c66d..f30f072 100644 --- a/docs/views.md +++ b/docs/views.md @@ -13,3 +13,45 @@ And you should have an `hello.ecr` view. It will have the same context as the me ```erb Hello <%= env.params["name"] %> ``` + +## Using Layouts + +You can use **layouts** in Kemal. You should pass a second argument. + +```crystal +get '/:name' do + render "views/subview.ecr", "views/layouts/layout.ecr" +end +``` + +And you should use `content` variable (like `yield` in Rails) in layout file. + +```erb + + + <%= $title %> + + + <%= content %> + + +``` + +## Using Common Paths + +Since Crystal does not allow using variables in macro literals, you need to generate +another *helper macro* to make the code easier to read and write. + +```crystal +macro my_renderer(filename) + render "my/app/view/base/path/#{{{filename}}}.ecr", "my/app/view/base/path/layouts/layout.ecr" +end +``` + +And now you can use your new renderer. + +```crystal +get '/:name' do + my_renderer "subview" +end +``` diff --git a/spec/view_spec.cr b/spec/view_spec.cr index 355ea3e..176029d 100644 --- a/spec/view_spec.cr +++ b/spec/view_spec.cr @@ -1,5 +1,9 @@ require "./spec_helper" +macro render_with_base_and_layout(filename) + render "spec/asset/#{{{filename}}}", "spec/asset/layout.ecr" +end + describe "Views" do it "renders file" do kemal = Kemal::Handler.new @@ -11,6 +15,16 @@ describe "Views" do response.body.should contain("Hello world") end + it "renders file with dynamic variables" do + kemal = Kemal::Handler.new + kemal.add_route "GET", "/view/:name" do |env| + render_with_base_and_layout "hello.ecr" + end + request = HTTP::Request.new("GET", "/view/world") + response = kemal.call(request) + response.body.should contain("Hello world") + end + it "renders layout" do kemal = Kemal::Handler.new kemal.add_route "GET", "/view/:name" do |env|