Ruby Layout Inheritance - ruby-on-rails

I was wondering if there is any layout inheritance implementation in ruby.
In symfony, you can do this:
layoutmain.html
Give <head> and all that here
<body>
<h3>{{title}}</h3>
{{block view}}
<div class="row">
<div class="span3">
{{content}}
</div>
</div>
{{end block}}
</body>
layout2.html
{{inherits layoutman}}
{{block view}}
<div class="container">
Structure it differently
</div>
{{end block}}
So to speak, it let's you inherit the whole template and override parts for a different layout. So the scripts etc stay as they are in the main template, but you can change the view structure. So you can reuse bits of code in the first layout
I found some liquid inheritance project on github, but it looked outdated

I use the following approach to achieve "nesting" of layouts which is the form of layout inheritance that I've found to be most useful.
In the main application helper module app/helpers/application_helper.rb I define a helper method parent_layout:
module ApplicationHelper
def parent_layout(layout)
#view_flow.set(:layout, self.output_buffer)
self.output_buffer = render(:file => layout)
end
end
This helper is responsible for capturing the output of the current layout and then rendering the specified parent layout with the child layout inserted when the parent yields.
Then in my views I can set up the layout inheritance as follows. I start with my main application layout app/views/layouts/application.html.erb which is the child layout in this configuration:
<div class="content">
<h1><%= content_for?(:title) ? yield(:title) : 'Untitled' %></h1>
<div class="inner">
<%= yield %>
</div>
</div>
<%= parent_layout 'layouts/container' %>
The call to the helper method parent_layout specifies that application.html.erb is a child layout of container.html.erb. I then define the parent layout app/views/layouts/container.html.erb as follows:
<!DOCTYPE html>
<html>
<head>
<title>Sample</title>
</head>
<body>
<%= yield %>
</body>
</html>
The yield in container.html.erb yields to the "derived" (or child) layout application.html.erb, i.e. it inserts the output of rendering application.html.erb into the <body> of container.html.erb. Note that the parent_layout call needs to come at the end of the template since it captures the output of the layout up until the point at which it is invoked.
This is based on this article but updated to work in Rails 3.2 (and, hopefully, later). I haven't tried it in Rails 4, but you'll be able to get something similar working.

Ruby on Rails views have a feature called "partials". I partial is a view that generates a bit of html and can be included in other views. The partials can also accept arguments (local variables) that customize their behavior. The partials can include other partials.
This is probably a good place to start learning about that: http://guides.rubyonrails.org/layouts_and_rendering.html
I have never needed to do some kind of layout inheritance thing like you are describing but I could imagine doing it pretty easily with partials and passing around ruby variables that say which partial to use in which situation.

Related

How can I change a body tag ID based on the page title in rails?

Using Ruby on Rails (5) I want to use an if statement to change the ID of the body tag based on what view I am rendering.
Specifically I want to use a background image on my home page only, and not on any other. I want this to fill the screen, but if I put it on the page it's self it comes up with a border. So I want to attache it to the body tag in the application.html.erb view so the ID will tell CSS to load the background image. But I can't get the :title to tell ERB that it is there and make the statement true.
I am using provide on the view page as so:
<% provide(:title, "Home") %>
Then in the application.html.erb page I am trying to use an if statement to put in the body tag with or without the CSS ID for the background image based on the provided :title, like so:
<!DOCTYPE html>
<html>
<head>
<title><%= yield(:title) %></title>
...
</head>
<% if :title == "Home" %>
<body id="home-background">
<% else %>
<body>
<% end %>
But it doesn't seem to work. The title will 'yield' and display in the address bar, but not in the if statement. I have also tried to put the yield(:title) in a variable and rails didn't like that. This is my first solo rails project, and I know This should be possible, but I can't find how to do it correctly, any help would be appreciated.
i wont recommend you for the body tag...but you can use a wrapper just after the body for a background image...it can be like this:-
The only thing you will need is to create an instance variable(#title) to use below
###application.html.erb
<body>
<div class="<%= #title=="USER" ? 'user_wrapper' : 'default_wrapper' %>">
</div>
</body>
##css
.user_wrapper{
background: url(user_background.jpg) no-repeat center center fixed;
}
.default_wrapper{
background: url(default_background.jpg) no-repeat center center fixed;
}
HOPE IT HELPS.. :)

set a class dynamically in Rails application layout file

the problem is this:
I have my application layout file looks like this:
app/views/layouts/application.html.erb
...
<section>
<%= yield %>
</section>
...
Now what I would like to do is set the class of the section element dynamically, depending on what view I'm rendering
for instance, if I'm rendering a Dashboard view from:
/app/views/admin/news_items/index.html.erb
I would like the class of the section element dynamically be set to "dashboard":
<section class="dashboard">
<%= yield %>
</section>
Is this possible with Rails?
thanks for your help,
Anthony
As far as i can understand you want specific namespaces to have different layouts right?
You can achieve easily this by specifying different layout for different controllers/namespaces
# In DashboardController
layout 'dashboard'
The above will use the dashboard.html.erb under app/views/layouts for all the actions that are inside the DashboardController or inherit from it.
I hope that helps
Maybe you could do something like this?
<section class="<%= controller.controller_name %>-<%= controller.action_name %>">
This will add a class like so
<section class="dashboard-show">
Source: https://stackoverflow.com/a/16813823/3651372

Changing between layouts requires refresh to see changes

In my controller, I've got my show action using a different layout (e.g., foo.html.erb) than my application.html.erb. foo.html.erb has styles loading directly in the <head>, for example:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
{styles here}
</style>
</head>
<body>
<%= yield %>
</body>
</html>
Here is the controller code for how I'm resolving the layout:
class FoosController < ApplicationController
layout :resolve_layout
def show
end
private
def resolve_layout
case action_name
when 'show'
'foo'
else
'application'
end
end
end
The problem is, the application seems to cache the templates too heavily, and when I click through to a view that should be using the show template, I don't see those <head> styles without a refresh.
Am I handling this correctly, or is there a more "rails way" of doing this? What I'm really trying to accomplish here is having styles unique to a particular template only load with that single template. I think this may be an asset pipeline question, but I'm not sure, as I'm still new to Rails.
Seems like it was an issue with the styles living in the head. I had a relatively simple page, so I was able to move them to be inline styles, and the problem seems to be solved.

Rails - use code(css, js, html) from server on client side

I had a application rails built with bootstrap and simple form.
Here I have to show the UI patterns how they actually look like. That means I have to show the
patterns like menu bar, accordian patterns examples in my application. For that I am storing the pattern code html,css,js in database.
Here my requirement is I have to show the actual code pattern view from the stored record(css,js,html) without any css/js conflicts.
How can eneter the html,css,js code dynamically in a partial or page to show that
in a fancybox in rails.
Thanks for the help in advance.
just use html_safe or raw to render your content as a normal string on views. For instance:
in your controller:
#x = YOUR_CODE_FROM_DB
in your view:
<%= #x.html_safe %>
# <%= raw #x %> is also ok in this case
NOTICE: you can use html_safe on models, but raw is declared on a helper, so you can just use it on controllers and views.
-- edit --
more example:
on controller:
#hello = 'alert("hi");'
#body = 'body{ background: red; }'
on view:
<script type="text/javascript" charset="utf-8">
<%= raw #hello %>
</script>
<style type="text/css" media="all">
<%= #body.html_safe %>
</style>

Yii: how to define partials for layout in a view?

In Rails it's easy:
View has:
<% content_for :sidebar do %>
... sidebar HTML ...
<% end %>
Layout has:
<%= yield :sidebar %>
Can I do same in Yii?
UPDATE: How can use both dynamic header, content and footer in main.php layout?
View has:
<?php $this->beginClip('sidebar'); ?>
Hi there!
<?php $this->endClip(); ?>
Layout has:
<?= $this->clips['sidebar'] ?>
For more look at CController docs.
But in all fairness, this is the wrong way to do sidebars.
You can define public $sidebar in your base Controller component. Then you can assign to $this->sidebar in your views or controllers and retrieve $this->sidebar in your layouts. You should also look into renderPartial() which can be used in layouts, controllers, and views to render partial HTML content (content without layout). e.g. $this->renderPartial('/some/view')
Yep, in yii you can render partial content using renderPartial(),
you can have a look on renderpartial() here
You can use it as $this->renderPartial('/folder/view')

Resources