Skip to content

Commit

Permalink
Clean up Layouts guide
Browse files Browse the repository at this point in the history
  • Loading branch information
cllns committed Sep 27, 2016
1 parent cc9579d commit b3c4394
Showing 1 changed file with 22 additions and 22 deletions.
44 changes: 22 additions & 22 deletions source/guides/views/layouts.md
Expand Up @@ -4,12 +4,11 @@ title: Guides - View Layouts

# Layouts

Layouts are special views.
Their role is to render the _"fixed"_ part of the HTML markup that doesn't change from page to page.
Think of the navigation, sidebar, header, footer, etc..
Layouts are special views, that render render the _"fixed"_ part of the HTML markup.
This is the part that doesn't change from page to page (perhaps navigation, sidebar, header, footer, etc.)

When we generate a new application, there is a default layout called `Web::Views::ApplicationLayout` with a `apps/web/templates/application.html.erb` template.
It comes with a really basic HTML5 wireframe.
It comes with a very basic HTML5 wireframe.

```erb
<!doctype HTML>
Expand All @@ -23,19 +22,19 @@ It comes with a really basic HTML5 wireframe.
</html>
```

The interesting part is `<%= yield %>`.
The most interesting part is `<%= yield %>`.
It's replaced at the runtime with the output of a view.
**The order for a rendering is view first, layout as second step.**
**The order for rendering is first the view, and then the layout.**

The context for a layout template is made of the layout and the current view.
The latter has higher priority.

Imagine to have the following line `<title><%= page_title %></title>`.
If both the layout and the view implement `#page_title`, Hanami will use the one from the view.
Imagine having the following line `<title><%= page_title %></title>`.
If both the layout and the view implement `page_title`, Hanami will use the one from the view.

## Configure Layout

Default layout is defined in application's configuration.
The default layout is defined in an application's configuration.

```ruby
# apps/web/application.rb
Expand All @@ -49,10 +48,10 @@ end
```

<p class="convention">
Hanami transforms layout name in application's configuration, by appending the <code>Layout</code> suffix. Eg. <code>:application</code> for <code>Web::Views::ApplicationLayout</code>.
Hanami transforms the layout name in the application's configuration, by appending the <code>Layout</code> suffix. For example, <code>layout :application</code> corresponds to <code>Web::Views::ApplicationLayout</code>.
</p>

If we want to disable a layout for a view, we can use a DSL for that.
If we want to disable a layout for a view, we can use a DSL for that:

```ruby
# apps/web/views/dashboard/index.rb
Expand All @@ -68,11 +67,12 @@ If we want to turn off this feature entirely, we can set `layout nil` into the a

## Using Multiple Template Layouts

Sometimes it's useful to have more than one layout. For example, if the `application.html.erb` template contains navigation elements, and you want an entirely different layout - without navigation - for a login page, you can create a `login.html.erb` layout template.
Sometimes it's useful to have more than one layout.
For example, if the `application.html.erb` template contains navigation elements, and we want an entirely different layout, without navigation elements, for a login page, we can create a `login.html.erb` layout template.

Assuming you have created something like a `user_sessions#new` action to log a user in, you create the `login.html.erb` template right next to your default `application.html.erb` in `apps/web/templates/`.
Assuming we have a `Web::Actions::UserSessions::New` action to log a user in, we can create a `login.html.erb` template right next to the default `application.html.erb` in `apps/web/templates/`.

We now need to create a new `Web::Views::LoginLayout` object to utilize the new template. Create a `login_layout.rb` right next to default `application_layout.rb` in `apps/web/views`:
Then we need to create a new `Web::Views::LoginLayout` class, which will use the new layout template. This file can be named `app/web/views/login_layout.rb`(right next to the default `application_layout.rb`):

```ruby
module Web
Expand All @@ -84,23 +84,23 @@ module Web
end
```

Now, in your `app/web/views/user_sessions.rb` you can specify you'd like to use the login layout for this View:
Now, in our `app/web/views/user_sessions/new.rb` we can specify you'd like to use the login layout for this View:

```ruby
module Web::Views::UserSessions
class Login
class New
include Web::View
layout :login
end
end
```

Now, only `user_sessions#new` will use the special layout, but you can now use `layout :login` in any other View in this app.
And we can add `layout :login` to any other View in this app that should use this same layout.

## Optional Content

There are some cases when we want to render a content only for certain resources.
Think of some javascripts to include only in specific pages.
Sometimes it's useful to render content only on certain pages.
For example, this could be used to have page-specific javascript.

Given the following template for a layout:

Expand All @@ -111,7 +111,7 @@ Given the following template for a layout:
<body>
<!-- ... -->
<footer>
<%= local :javascripts %>
<%= local :javascript %>
</footer>
</body>
</html>
Expand All @@ -134,12 +134,12 @@ module Web::Views::Books
class Show
include Web::View

def javascripts
def javascript
raw %(<script src="/path/to/script.js"></script>)
end
end
end
```

The first view doesn't respond to `#javascripts`, so it safely ignores it.
The first view doesn't respond to `#javascript`, so it safely ignores it.
Our second object (`Web::Views::Books::Show`) responds to that method, so the result will be included in the final markup.

0 comments on commit b3c4394

Please sign in to comment.