Is Rails going "backwards" in the code in this example? - html

I have following html page home.html.erb:
<% provide(:title, 'Home') %>
<h1>Sample App</h1>
<p>
This is the home page for the
Ruby on Rails Tutorial
sample application.
</p>
And I have the following layout application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
...
</head>
<body>
<%= yield %>
</body>
</html>
full_title() is a function that checks if there was a title passed as a parameter. If there was, it will place it into the HTML. If no parameter is given, it will place a base title into the HTML.
I'm assuming rails begins by going through the application.html.erb and then upon reaching <%= yield %>, it will embed the contents of home.html.erb into application.html.erb at that location, resulting in the following document:
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
...
</head>
<body>
<% provide(:title, 'Home') %>
<h1>Sample App</h1>
<p>
This is the home page for the
Ruby on Rails Tutorial
sample application.
</p>
</body>
</html>
In the 4th line <%= full_title(yield(:title)) %>, the value "Home" is definitely being passed for :title, but the code <% provide(:title, 'Home') %> doesn't come until several lines later. Is Rails going backwards to accomplish this? How is this happening?

No it's don't. This is kind of string interpolation, this value will be replaced after every call of provide(:title, ...)

My understanding is that the home.html.erb is processed before the application layout. In other words, the view and helper are prepared and 'plugged-in' to the application layout before the whole thing is complete. I guess "going backwards" depends on which way you look at it / how it actually works. I'm still learning too, but it's not necessarily a 'top to bottom' sequence in terms of how the code is layed out on the page.

Related

ASP classic .NET How do I inherit a layout [duplicate]

Is it possible to build some kind of master page with Classic ASP without frames or iframes?
I’m wondering if there is a way to include content pages in the main page like ASP.NET master pages do. From what I have researched, ASP Classic does support inclusion of other ASP/HTML pages into a page, but the value put into this include means the function cannot be dynamic.
You could just create functions (say, a Header() function and a Footer() function) which do nothing but output some set of markup. Those functions can take parameters too, and be called conditionally. It's not quite the same as a Master page, but it sounds like it accomplishes what you are trying to do. You would have an <!--#include file="headerfooter.asp"--> on each page, and each page would call Header() & Footer().
Or you can just use <!--#include file="header.asp"--> at the top and <!--#include file="footer.asp"--> at the bottom of each page too. I've seen both approaches.
If you are looking for the reverse, that is, a single template page which calls individual pages in it's "middle" section, then that's not really something you can do easily with ASP classic. It's a fundamental difference in approach: ASP.NET has a concept of a control tree, events, etc, while ASP Classic is essentially just a script that runs top to bottom.
This idea is from Classic ASP Master Pages | Godless Code. I’ve transcribed the code in images on that page, extended its example a bit, and also explored the limitations of this technique.
The idea is that each page has only one Server-Side Include (one <!--#include file="" --> call). The single inclusion is a master template file, which you could name master.asp. The master page calls custom subroutines on each page in place of each content area. Each child page defines those subroutines with Sub, with content unique to that child page.
master.asp
<!DOCTYPE html>
<html>
<head>
<title><% Title() %></title>
</head>
<body>
<% BodyContent() %>
</body>
</html>
aboutUs.asp
<!--#include file="master.asp" -->
<% Sub Title %> About Us <% End Sub %>
<% Sub BodyContent %>
<h1>About Us</h1>
<p>
We do things!
</p>
<% End Sub %>
That turns into this HTML when you visit aboutUs.asp on an IIS server:
<!DOCTYPE html>
<html>
<head>
<title> About Us </title>
</head>
<body>
<h1>About Us</h1>
<p>
We do things!
</p>
</body>
</html>
However, this approach does not allow nesting:
subtemplate.asp
<div class="innerLogo <% LogoSide() %>">
<% LogoImg() %>
</div>
template_user.asp
<!--#include file="master.asp" -->
<% Sub Title %> Our Logo <% End Sub %>
<% Sub BodyContent %>
<!--#include file="subtemplate.asp" -->
<% Sub LogoSide %> leftside <% End Sub %>
<% Sub LogoImg %>
<img src="img/about.png" alt="About" />
<% End Sub %>
<% End Sub %>
This will not work, because nested Subs are a syntax error:
Microsoft VBScript compilation error '800a03ea'
Syntax error
/template_user.asp, line 9
Sub LogoSide
^
Since nesting is not allowed, this templating system is, in effect, a one-time solution. If your individual pages’ subroutines become too unwieldy, you can’t use this technique again. So when using this technique, you should carefully choose where to carve out your set of templates in order to provide the best balance between flexibility and DRYness.
Rory wrote a great example for master pages in Classic ASP, but demonstrated that the "master page" approach had its limitations because Subs cannot be nested.
However, for the sake of demonstration, and because JavaScript in Classic ASP has hardly any documentation anywhere on the Internet, here's the same example that fails in ASP VBScript but won't fail in ASP JavaScript.
master.asp
<!DOCTYPE html>
<html>
<head>
<title><% Title() %></title>
</head>
<body>
<% BodyContent() %>
</body>
</html>
subtemplate.asp
<div class="innerLogo <% LogoSide() %>">
<% LogoImg() %>
</div>
template_user.asp
<%# Language= "Javascript" %>
<!--#include file="master.asp" -->
<% function Title() { %> About Us <% } %>
<% function BodyContent() { %>
<!--#include file="subtemplate.asp" -->
<% function LogoSide() { %> leftside <% } %>
<% function LogoImg() { %>
<img src="img/about.png" alt="About" />
<% } %>
<% } %>
It works! here are the juicy results:
<!DOCTYPE html>
<html>
<head>
<title> About Us </title>
</head>
<body>
<div class="innerLogo leftside ">
<img src="img/about.png" alt="About" />
</div>
</body>
</html>
Remember, JavaScript, even the ECMAScript 3 version in Classic ASP, is often way more powerful and expressive than the VBScript engine that was favoured and heavily promoted by Microsoft. If you ever have to use Classic ASP, use JavaScript!
One of the ugliest problems in classic ASP is that #includes always happen, so putting two includes in an if-then-else construct always includes both – even though you only see the output that applies to your conditional value.
Even when includes work, they don't give you the result you're really looking for, which is to select a template or skin “on the fly”.
One way to handle this situation is to use a template engine such as KudzuASP that surpasses the traditional #include methodology. Here is a very simple example:
<!-- An HTML Template -->
<html>
<head><title><!--[Replace|PageTitle]-->PageTitle<!--[/Replace]--></title></head>
<body>
<table border="1" cellpadding="4" callspacing="2" width="640">
<tr>
<td colspan="2"><!--[HeaderContent/]--></td>
</tr>
<tr>
<td width="160"><!--[LeftColumnContent/]--></td>
<td><!--[MainContent/]--></td>
</tr>
<tr>
<td colspan="2"><!--[FooterContent/]--></td>
</tr>
</table>
</body>
</html>
And the ASP code looks like this:
<%# Language=VBScript %>
<!-- #include file="./KudzuASP/_kudzu.asp" -->
<%
Dim PageTitle : PageTitle = "This is a Master Page"
'
' Create the template engine
'
Dim T_ENGINE
Set T_ENGINE = New CTemplateEngine
T_ENGINE.PutValue "PageTemplate", PageTemplate
T_ENGINE.SetHandler "HeaderContent", New CTXHeaderContent
T_ENGINE.SetHandler "LeftColumnContent", New CTXLeftColumnContent
T_ENGINE.SetHandler "MainContent", New CTXMainContent
T_ENGINE.SetHandler "FooterContent", New CTXFooterContent
'
' Custom Tage Handlers
'
Class CTXHeaderContent
Public Sub HandleTag(vNode)
vNode.Engine.ContentAppend "Header"
End Sub
End Class
Class CTXLeftColumnContent
Public Sub HandleTag(vNode)
vNode.Engine.ContentAppend "Left<br/>Content"
End Sub
End Class
Class CTXMainContent
Public Sub HandleTag(vNode)
vNode.Engine.ContentAppend "Main<br/>Content"
End Sub
End Class
Class CTXFooterContent
Public Sub HandleTag(vNode)
vNode.Engine.ContentAppend "Footer"
End Sub
End Class
'
' Evaluate the template
'
T_ENGINE.ParseFile Server.MapPath("./MasterPage.html")
T_ENGINE.EvalTemplate
%>
The template engine makes calls to your custom objects defined in the hosting ASP code page when the appropriate tags are processed. The function members of your custom classes have direct access to the hosting page and its variables and methods, as well as the template engine’s object hierarchy. In other words, the template is driving the output and the hosting ASP page during output.
This beats the include mechanism hands down, because the template engine can dynamically select which HTML template to process at runtime, and it can dynamically include libraries of custom tag handlers using the built in <!--[import/]--> tag.
UPDATE 2016.01.13: I have open sourced this project and you can find the latest code maintained at this address: https://github.com/Mumpitz/KudzuASP
I just use a Default.asp page with html, then put my code in the content area.
<%# Language="VBScript" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<div id="topNav"> <!--begin top Nav-->
<ul>
<!--Be sure that all links are like this href="?page=contentPageEx"-->
<li>Home</li>
</ul>
</div> <!--end top Nav-->
<div id="content">
<%
Dim default
default= Request.QueryString
If default= "" Then
Server.execute "includes/home.html"
Else
Server.execute "includes/" & request("page") & ".html"
end if
%>
</div>
<div id="botNav"> <!--begin bot Nav-->
<ul>
<li>Home</li>
</ul>
</div> <!--end Bot Nav-->
</body>
</html>
Then I put all my content into an includes file with html pages.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<!--Search engines use this title ect...-->
<title>Hello SEO! This is a content page!</title>
<!--Can be styled independently-->
<style>
p {
color: #0094ff;
}
</style>
</head>
<body>
<p>Hello World!</p>
</body>
</html>

Wanting same banner/nav menu on each page in Rails

I'm new to rails. I currently have 3 pages in my web app. I am wondering what is the "cool rails way" where I can easily implement the same banner (pic/website logo/text) and horizontal navigation menu on each page with out having to copy and paste the code or create separate CSS files for each page. Is this possible? Would like to stick with Ruby/Rails/CSS/HTML.
Also, It seems that if I create a css element titled banner for one view of one controller another view of a different controller has the same styling. Is there something going on behind the scenes here?
Thanks.
This is usually accomplished through application.html.erb. You put the header of your web site in that page followed by a <%= yield %> statement and then the footer. The yield statement inserts the content from whatever action is being processed.
For example:
application.html.erb
<html>
<head>
</head>
<body>
<h1>My cool web site header and menu!</h1>
<%=yield %>
<p>Web site footer</p>
index.html.erb
<h2>Index</h2>
<ul>
<% #stuff.each do |thing| %>
<li><%=thing.name%></li>
<% end %>
</ul>
The contents of index.html.erb will be inserted into the application.html.erb at the spot where <%=yield %> appears.
Following this tutorial: http://ruby.railstutorial.org/ruby-on-rails-tutorial-book ,
the way to do it is to use rendermethod.
example code from the tutorial:
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" =>
true %>
<%= javascript_include_tag "application", "data-turbolinks-track" =>
true %>
<%= csrf_meta_tags %>
<%= render 'layouts/shim' %>
</head>
<body>
<%= render 'layouts/header' %>
<div class="container">
<%= render 'layouts/flash' %>
<%= yield %>
<%= render 'layouts/footer' %>
</div>
</body>
</html>
According to the tutorial, the way in rails to pack up a logical unit in one place is to use a facility called partials.
For example, you can pack up your navigation bar in app/views/layouts/_navbar.html.erb
then it can be rendered in the layout with <%= render 'layouts/navbar' %>
More about the parials: http://ruby.railstutorial.org/chapters/filling-in-the-layout#sec-partials
Rails defaults to concatenating all CSS files into one master. http://guides.rubyonrails.org/asset_pipeline.html

Rails reading in and rendering seperate html doc, need <base> to only apply to the read in html

I am writing a mobile web application using Rails and jQuery mobile. I am reading all of my data at runtime from Amazon AWS S3 using HTTParty.
One of the screens that I need to render is just straight html, which can and usually does have images embedded into it which are hosted in the same folder on S3. This is where my problem is. I can easily pull in the html with HTTParty and use the html_safe option to render it, but the images don't render as they are relative path names. So I have been trying to find a way around this.
I have tried multiple things, but I have mainly been looking into using an html tag to get the images to point to the right location. The problem is that I cant specify a base tag and then have other links on the page, because they then use that same base and the links are not pointing atand the correct location. So I looked into framesets and frame and pointing the base tag only at the frame, which I believe I used correctly, but to no avail. I tried using but to no avail.
So basically I am looking for a way that I can set the base for relative path names in an html string that I read in from S3, if that wasn't clear. I am open to any suggestions! And thanks in advance for even reading and try to solve this very specific problem!
Oh and one more thing, when I look at the page with Firebug, the first line in the header is a base tag with href set to the current page. I can't find out where it is coming from but I am guessing rails is throwing it in there? I don't know if this matters since I then put another base tag below it with the yield :intro_base? Or is that one of my problems since there is a conflict there?
And then there was code:
My 'intro' method:
def intro
#intros = []
#app_config.intro_screens.each do |intro_screen|
intro_screen_response =
ApplicationController.get("#{#diandr_url}/#{intro_screen['filename']}.html")
#intros << intro_screen_response.body
end
#intros.reverse!
#intros_length = #intros.length
respond_to do |format|
format.html
end
end
My 'intro.html.erb' file:
<% page_num = params[:id].to_i %>
<% content_for :intro_base do %>
<base href="https://s3.amazonaws.com/our_bucket_name<%=#dir_url%>/" target="intro" />
<% end %>
<% content_for :mobile_header do %>
*some jQuery mobile paging and header stuff is in here, shouldn't matter*
<% end %>
<% content_for :mobile_content do %>
<!-- <iframe src=<%= #intros[page_num] %> height="100%" width="100%"> -->
<!-- <p> This browser does not support iframes </p> -->
<!-- </iframe> -->
<frameset cols="100%">
<frame name="intro" <%= #intros[page_num].html_safe %>
</frameset>
<% end %>
My layout's header:
<head>
<title> our Mobile App </title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- These are the jQuery Mobile scripts -->
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js">
</script>
<%= yield :intro_base %>
<%= stylesheet_link_tag "master" %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>

Aptana studio 3 automatically includes html markup in rhtml files

I am learning ruby on rails using aptana studio 3. I created a view hello.rhtml. When i run the view and see the source i get to see js files automatically included. Even if my rhtml file is empty for eg
hello world
Without the html markup, and if i see the source, i can see the entire markup from html doctype etc already present. How do i stop the inclusion of automatic markup?
Thanks
EDIT :
OK i create a hello.html.erb file. And put this code inside it
Hello
When i save and run the file, i get the output, but when i view source i get the following result.
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<script src="/javascripts/prototype.js?1312799421" type="text/javascript"></script>
<script src="/javascripts/effects.js?1312799421" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1312799421" type="text/javascript"></script>
<script src="/javascripts/controls.js?1312799421" type="text/javascript"></script>
<script src="/javascripts/rails.js?1312799421" type="text/javascript"></script>
<script src="/javascripts/application.js?1312799421" type="text/javascript"></script>
<meta name="csrf-param" content="authenticity_token"/>
<meta name="csrf-token" content="82LBP1pI5h0QzNW54PYSq/zdkS8kF4Z/nKSUHgKvv1g="/>
</head>
<body>
<html>
<head><title>Hello</title></head>
<body>
</body>
</html>
</body>
</html>
SO if you see, i get html inside html and when in browser my title shows "Demo" instead of "Hello"
UPdate :
Here is the content of application layout. And i now understand that, the code is coming from this layout.
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
</head>
<body>
<%= yield %>
</body>
</html>
I am new to this, so what is the best practice and what code should be present in application_layout.html.erb. I would like all my view files to have its own html code.
Thanks a lot
Your view should have .html.erb extension not rhtml (That's a hang over from Rails 1.x).
Check out your application layout file. in the head section you'll see an entry for including javascript. Just comment that out and you js will not be included.
Which just leaves me with a question. What's the actual problem with what you have? Why does it bother you? Perhaps the answer to this will get you to the right question in order to find a more appropriate solution.
UPDATE
Have a close look at your application_layout.html.erb.
Can you post the contents of that?
This is not an error, this is the way Rails works!
Rails will generate views/layouts/application.html.erb for you, this is the basic template of the website. With this template, you don't have to copy and paste the same html declarations on each page you make.
Rails uses a convention called MVC which stands for Model, View, Controller. I suggest you read a bit more on how this works. Basically, <%= yield %> will insert the contents of your view, but you must tell Rails which url points to which view. Now you can have views/pages/home.html.erb, the contents of which might be..
<h1>Home Page</h1>
<p>Congratulations, you made a web page with Rails!</p>
And then in routes.rb
YourApp::Application.routes.draw do
match 'home' => 'pages#home'
end
When you go to http://localhost:3000/home, you should see your web page. If you look at the source code, you will see the output generated by Rails.
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
</head>
<body>
<h1>Home Page</h1>
<p>Congratulations, you made a web page with Rails!</p>
</body>
</html>
This is definitely the proper way to use Rails. The goal is DRY (Don't Repeat Yourself). Michael Hartl has a wonderful tutorial and introduction to using Ruby on Rails. I would suggest anyone new to Ruby on Rails to start here: http://ruby.railstutorial.org/. If you have any questions about using Ruby on Rails or web design in general, I'd be happy to help. You can email me at draco#dragonstarwebdesign.com. Cheers and good luck to you!

What happens with Rails indentation in outputted HTML?

I'm writing code for a Rails view in TextMate (using the 2-space indentation standard). Whenever I view the output of my webpages (View Source), the HTML brackets always seem weirdly indented. For example, my application.html.erb looks like this:
<!DOCTYPE html>
<html>
<head>
<title>Rainleader</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :all %>
<%= csrf_meta_tag %>
</head>
<body>
<div id="outer">
<div class="contentwidth main">
<%= render 'layouts/header' %>
</div>
<%= yield %>
</body>
</html>
And the partial it's rendering (_header.html.erb) looks like this:
<div class="logo">
<h1>minimal.</h1>
</div><!-- end logo -->
But, an excerpt of the outputted HTML has misplaced (mis-indented) brackets (see my notes in the code below):
<body>
<div id="outer">
<div class="contentwidth main">
<div class="logo"> <<<Why is this so far to the right?
<h1>minimal.</h1> <<<Why is this so far to the left?
</div><!-- end logo -->
What's going on here? If my call to the _header.html.erb partial in application.html.erb is indented four spaces, do I need to indent the code in the partial by at least that same amount to have it nest properly?
The first line of the partial that is rendered is indented as <%= render 'layouts/header' %> in application.html.erb. But all other lines of code are not indented further, just left-aligned as they are in your partial. It bugged me too, which is part of why I started using haml.