Layout and Rendering
====
Based on guides.rubyonrails.org
Creating response
Communication between View and
Controller
3 Ways to create HTTP response
Call "render"
to create a full response to send back to the browser
Call
"redirect_to" to send an HTTP redirect status code to the browser
Call "head"
to create a response consisting solely of HTTP headers to send back to the
browser
Convention over configuration
By default, controllers
automatically render views with names of
the route.
Ex:
In
route.rb:
resources
:books
class
BooksController < ApplicationController
def index
@books = Book.all
end
end
- Try to
render app/views/books/index.html.erb
which is the same name as the methods(index)
Using render
It is possible to
render text, JSON or XML. Can specify
content type or HTTP status of the rendered response.
If use
render_to_string, just returns a string instead to send to the response to
browser.
Rendering nothing
render
nothing: true
Rendering a action's view
render "edit"
#OR
render :edit
Render template
render template:
"books/edit"
render template:
"books/edit.html.erb"
To render a specific file
render file:
"/u/apps/warehouse_app/current/app/views/products/show"
Render inline
render inline:
"<% products.each do |p| %><%= p.name
%>
<% end %>"
<% end %>"
Render text
render text:
"OK"
Render JSON
render json: @product
Render XML
render xml: @product
Render JavaScript
render js:
"alert('Hello Rails');"
Options
:content_type
-
text/html, application/json, application/xml
ex: render
file: filename, content_type: "application/rss"
:layout
render
layout: "special_layout"
render
layout: false
:location
To set HTTP
Location header
render xml:
photo, location: photo_url(photo)
:status
render
status: 500
#OR
render
status: :forbidden
Fiding Layouts
First Rails try to set
the same layout as the Controller, if it doesn't find, look for the
layouts/application.html.erb.
It is possible to
specify a layout.
ex:
class
ProductsController < ApplicationController
layout "inventory"
#...
end
To assign a specific
layout for the entire application, use layout in ApplicationController
ex:
class
ApplicationController < ActionController::Base
layout "main"
#...
end
Specifying a layout in runtime
class
ProductsController < ApplicationController
layout :products_layout
def show
@product = Product.find(params[:id])
end
private
def products_layout
@current_user.special? ?
"special" : "products"
end
end
Or with inline method
class
ProductsController < ApplicationController
layout Proc.new { |controller|
controller.request.xhr? ? "popup" : "application" }
end
Conditionanl Layouts
class
ProductsController < ApplicationController
layout "product", except: [:index,
:rss]
end
Using redirect_to
Tells the browser to send a
new request from a different URL.
Ex:
redirect_to
photos_url #Redirect to index of photos
Send back to the previous page
redirect_to :back
Differences
render action:
"index" # Doesn't run the target code
redirect_to action:
:index #Browser redirect to the action
Drawback is
that it sends a 302 redirect response to the browser
Head only response
ex:
head :bad_request
head :created,
location: photo_path(@photo)
Structuring Layout
Asset tags : Asset tag helpers
provide methods for generating HTML that link views to feeds, JavaScript,
stylesheets, images, videos and audios. There are six asset tag helpers
available in Rails:
auto_discovery_link_tag
javascript_include_tag
Rails looks
for java scripts in the following directories:
app/assets, lib/assets or vendor/assets
If use:
<%=
javascript_include_tag "main", "columns" %>
Executes:
<script src='/assets/javascript/main.js'></script>
<script src='/assets/javascript/columns.js'></script>
stylesheet_link_tag
Similar to
JavaScript.
If use:
<%=
stylesheet_link_tag "main", "photos/columns" %>
Includes
app/assets/stylesheets/main.css
and app/assets/stylesheets/photos/columns.css
External:
<%=
stylesheet_link_tag "http://example.com/main.css" %>
image_tag
Builds an
HTML tag. Loaded by
public/images or app/assets/images
Ex:
<%=
image_tag "home.gif", alt: "Go Home",
id:
"HomeImage",
class:
"nav_bar" %>
video_tag
Builds an
HTML 5
Ex:
<%= video_tag
"movie.ogg" %>
Executes:
<video src="/videos/movie.ogg" />
Multiple
videos
<%=
video_tag ["trailer.ogg", "movie.ogg"] %>
Executes:
<video><source src="trailer.ogg" /><source src="movie.ogg" /></video>
options:
poster, autoplay, loop, controls, autobuffer
audio_tag
Builds an HTML 5
<%= audio_tag "music.mp3" %>
Options: autoplay, controls, autobuffer
yield
Identify a section
where the content of a view should be inserted
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
content_for
To render content into
a named yield, you use the content_for method.
Useful when the layout
contains distinct regions such as sidebars and footers with their own blocks.
<% content_for :head do %>
<title>A simple page</title>
<% end %>
<p>Hello, Rails!</p>
Partials
Files in the format
_xxxx.html.erb that is inserted in the view.
ex:
<%=
render "shared/menu" %>
Inset the file
app/views/shared/_menu.html.erb.
Partial can have
different layout
<%=
render partial: "link_area", layout: "graybar" %>
Passing
local variables
EX:
<h1>New zone</h1>
<%= error_messages_for :zone %>
<%= render partial: "form", locals: {zone: @zone} %>
the _form.html.erb
<%= form_for(zone) do |f| %>
<p>
<b>Zone name</b><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Passing variables
<%=
render partial: "customer", object: @new_customer %>
Rending the same name
as the object
<%=
render @customer %>
Assumes
that _custumer exists.
Colections
Will call
the parcial as many times as the collection size rendering every elements of
the collection.
<%=
render partial: "product", collection: @products %>
and
_product.html.erb
Product
Name: <%= product.name %>
Array
Render each
element of array
<%=
render [customer1, employee1, customer2, employee2] %>
should have
customers/_customer.html.erb
Customer:
<%= customer.name %>
employees/_employee.html.erb
Employee:
<%= employee.name %>
Spacer template
Render the
spacer_template without any paremeter between each call to partials in
collection.
<%=
render partial: @products, spacer_template: "product_ruler" %>
Nenhum comentário:
Postar um comentário