Rails render string with blank spaces in html file - ruby-on-rails

When I do something like:
<%= c.title %>
Rails render it like this:
"
Title
"
This behavior isn't the same if I wrap the string with a tag. Can someone please explain me why Rails acts like this?
UPDATE
Github's Repo link

This has to do with ERB instead of Rails. When the template is processed it outputs any values from output ERB tags (<%= %>) to the output buffer and simply executes any other code.
Everything else is left untouched. Whitespace before and after the ERB tags is untouched. The most that you can do is to use - in the tags to have it strip some of the whitespace.
<!-- -->
<% for i in 1..10 %>
<%= i -%>
<% end %>
<!-- -->
Will output
<!-- foo -->
1 2 3 4 5 6 7 8 9 10<!-- foo -->
Note the two spaces that still show up before each number, take out that whitespace and it will look like one long number.
Compare this with
<% for i in 1..10 %>
<%= i %>
<% end %>
Will output
<!-- -->
1
2
3
4
5
6
7
8
9
10
<!-- -->
Here's the output from your test page after select View Source from the context menu.
<!DOCTYPE html>
<html>
<head>
<title>Testapp</title>
<link href="/assets/application-1b13569e9620782f423d4cd3ce931750.css" media="all" rel="stylesheet" type="text/css" />
<script src="/assets/application-9a717ea62eac3463d689b2ba0a4e85b4.js" type="text/javascript"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="/hfgtJZWzxaQ2d7txQMAt2b+21MWSTYcf6/2F7Pei1k=" name="csrf-token" />
</head>
<body>
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
What's wrong with me?
<!-- -->What's wrong with me surrounded by html commet<!-- -->
</body>
</html>

You probably have some indentation in your layout file or another file that renders this view.
Your application.html.erb may look like this :
<html>
<head>...</head>
<body>
<%= yield %> <!-- Some whitespaces at the beginning of this line -->
</body>
</html>
Rails simply replaces the <%= %> tags with the value of the expression in it, nothing more.

I don't see the problem. Here's the rendered HTML:
<!DOCTYPE html>
<html>
<head>
<title>Testapp</title>
<link href="/assets/application.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/home.css?body=1" media="all" rel="stylesheet" type="text/css" />
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/home.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="cOfMPm5S/tCHCEHkeRTeQTITAiz800s+3Q4ZgNWCNlY=" name="csrf-token" />
</head>
<body>
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
What's wrong with me?
</body>
</html>
The relevant layout section:
<body>
<%= yield %>
</body>

I got the same problem with you!
The solution for me is to change the file Encoding from UTF-8 to UTF-8 without BOM
I'm using sinatra, glad to share with you!

Related

HTML Entity not converting to its result when passing into HTML from ViewData

When I pass an HTML entity into HTML via the View Data object, it does not convert to it's result. (i.e. the ™ entity remains ™ and does not convert to ™)
This is the destination page
#{
ViewData["Title"] = "Assess Mental Health";
ViewData["HeaderTitle"] = "Assess Mental Health";
ViewData["HeaderLine1"] = "with";
ViewData["HeaderLine2"] = "Intelligent Assessments™";
ViewData["HeaderImage"] = "url(../img/headers/AI_Head.png)";
}
<main data-zanim-timeline="{}" data-zanim-trigger="scroll">
<partial name="_Header" />
</main>
This is the partial
<!--
####################################################
H E A D E R
####################################################
-->
<section class="overflow-hidden py-0" id="top">
<div class="bg-holder overlay parallax" style="background-image:#ViewData["HeaderImage"];background-position: center 58%;">
</div>
<!-- / bg-holder-->
<div class="header-overlay"></div>
<div class="container" data-zanim-xs='{"duration":"1.5","delay":"0.1"}'>
<div class="d-flex align-items-center pt-10 pb-8">
<div class="header-text">
<div class="overflow-hidden">
<h1 class="display-3 text-white fs-4 fs-md-6">#ViewData["HeaderTitle"]</h1>
<p class="text-uppercase text-400 ls-2 mt-2 my-0 pb-0 pt-2">#ViewData["HeaderLine1"]</p>
<p class="my-0 py-0"><span class="fs-7 logo-secondary-style-light">pr<span class="logo-primary-style-light">e</span>vidence<sup class="fs-3 font-weight-light">™</sup></span></p>
<p class="text-uppercase fs-1 text-400 ls-2 my-0 py-0">#ViewData["HeaderLine2"]</p>
</div>
<partial name="_CallToActionLight" />
<div class="header-indicator-down"><a class="indicator indicator-down opacity-75" href="#Content" data-fancyscroll="data-fancyscroll" data-offset="64"><span class="indicator-arrow indicator-arrow-one" data-zanim-xs='{"from":{"opacity":0,"y":30},"to":{"opacity":1,"y":0},"ease":"Back.easeOut","duration":1,"delay":1.5}'></span></a></div>
</div>
</div>
</div>
</section>
<!-- / end H E A D E R -->
This is my layout
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex">
<title>#ViewBag.Title | Previdence | Mental Healthcare Platform</title>
<partial name="_Favicons" />
<link href="https://fonts.googleapis.com/css?family=Josefin+Sans&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://kit.fontawesome.com/971f8efccd.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link href="~/lib/non-npm/owl.carousel/owl.carousel.css" rel="stylesheet">
<link href="~/lib/non-npm/remodal/remodal.css" rel="stylesheet">
<link href="~/lib/non-npm/remodal/remodal-default-theme.css" rel="stylesheet">
<link href="~/lib/non-npm/theme/theme.css" rel="stylesheet">
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/css/cookiealert.css" />
</head>
<body>
<partial name="_Preloader" />
<partial name="_TopNavbar" />
#*<partial name="_CookieConsentPartial" />*#
#RenderBody()
<partial name="_Footer" />
<partial name="_GDPR_Alert" />
<!--
####################################################
J A V A S C R I P T - jquery, bootstrap, plugins
Place at the end of the document so the pages load faster
####################################################
-->
<script src="~/lib/jquery/dist/jquery.min.js"></script>
#RenderSection("Scripts", required: false)
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/non-npm/plugins/plugins.min.js"></script>
<script src="~/lib/non-npm/stickyfilljs/stickyfill.min.js"></script>
<script src="~/lib/non-npm/fortawesome/all.min.js"></script>
<script src="~/lib/non-npm/rellax/rellax.min.js"></script>
<script src="~/lib/non-npm/progressbar/progressbar.min.js"></script>
<script src="~/lib/non-npm/isotope-layout/isotope.pkgd.min.js"></script>
<script src="~/lib/non-npm/isotope-packery/packery-mode.pkgd.min.js"></script>
<script src="~/lib/non-npm/owl.carousel/owl.carousel.js"></script>
<script src="~/lib/non-npm/remodal/remodal.min.js"></script>
<script src="~/lib/non-npm/hover-dir/jquery.hoverdir.js"></script>
<script src="~/lib/non-npm/typed/typed.js"></script>
<script src="~/lib/non-npm/theme/theme.min.js"></script>
<script src="~/lib/non-npm/GDPR_Alert/cookiealert.js"></script>
<!-- / end J A V A S C R I P T -->
</body>
</html>
Try with #Html.Raw(string) to render html string :
#Html.Raw(#ViewData["HeaderLine2"])
Thanks to #Nan Yu's answer above, I was able to find the answer.
Try with #Html.Raw(string) to render html string
#Html.Raw() was part of the answer, the other part was that I am using a text-uppercase text transformation so I also needed to add a text-transform-none to remove the text-uppercase text transformation (this text-transformation was not shown in my code example).
#Html.Raw(<span class=\"text-transform-none\">™</span>)
I now get the correct output where the ™ output is ™ instead of ™

Angular 2 with ASP.NET Core duplicating <html><body>

I have setup Angular 2 with ASP.NET core, using:
dotnet new --install Microsoft.AspNetCore.SpaTemplates::*
I followed the standard setup but the App.component.html is duplicating the html and body tags.
When Pressing Control U (to view source) the html looks like:
<html>
<head>
....
</head>
<body>
<app>
<html>
<head>
<style>
...
</style>
</head>
</app>
</body>
</html>
</app>
...
</body>
</html>
redacted
None of my components have html or body tags in them. the only one that has html or body tag is the initial page
My _Layout.cshtml html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - HotSnail</title>
<base href="/" />
<script src="~/content/modules/jquery/jquery-3.2.1.min.js"></script>
<script src="~/content/modules/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
<link rel="stylesheet" href="~/dist/vendor.css" asp-append-version="true" />
<link href="~/content/modules/font-awesome-4.7.0/css/font-awesome.css" rel="stylesheet" />
<link href="~/content/modules/animate/animate.css" rel="stylesheet" />
<link href="~/content/global.css" rel="stylesheet" />
</head>
<body>
#RenderBody()
#RenderSection("scripts", required: false)
</body>
</html>
My Index.cshtml
<script src="~/dist/vendor.js" asp-append-version="true"></script>
#section scripts {
<script src="~/dist/main-client.js" asp-append-version="true"></script>
}
The above code is what should be served, now the first bit of angular should be the app.component
app.component.html
<ribbon></ribbon>
<div id="content">
<router-outlet></router-outlet>
</div>
ribbon.component.html:
<div id="ribbon">
<span class="ribbon-button-alignment">
<span id="refresh" class="btn btn-ribbon" data-action="resetWidgets" data-title="refresh" rel="tooltip" data-placement="bottom" data-original-title="<i class='text-warning fa fa-warning'></i> Warning! This will reset all your widget settings." data-html="true" data-reset-msg="Would you like to RESET all your saved widgets and clear LocalStorage?"><i class="fa fa-refresh"></i></span>
</span>
<!-- breadcrumb -->
<ol class="breadcrumb"><li>Home</li><li>Outlook</li><li>Inbox</li></ol>
</div>
This is all the components that should be injected on the first page
UPDATE*
So I have done some more research and it seems to be a known bug. As it says here:
https://github.com/aspnet/JavaScriptServices/issues/662
I cant quiet figure out their hacky solution
Here is hacky code that fixes this:
return requestZone.run>(() =>
platform.serializeModule(AppModule)).then(html => { resolve({ html:
html.slice(27, html.length - 14).replace('', '') }); },
reject);
Also in index.cshtml I advice changing app to div because we already
have app tag returned from Universal.
Loading...
I'm not sure where that code would go..
UPDATE
This also happens in the DEFAULT project created when doing
dotnet new angular
Does anyone know who maintains these templates as I'd like to post a bug with the development team
Same problem for angular 5.
I fixed it like in suggestion from last comment on https://github.com/aspnet/JavaScriptServices/issues/662 (last comment by salarcode):
boot.server.ts file change the code to this:
resolve({
html: (() => {
let apphtml = state.renderToString();
apphtml = apphtml.replace('<html><head><style>', '<style>').replace('</head><body><app', '<app').replace('</app></body></html>', '</app>');
return apphtml;
})()});

Laravel Blade does not include css and .js present in template

I need, from a view-blade, to search a database in order to fetch data and display them in another view-blade when a link is clicked.
I made the following:
In the view-blade who will acting on database:
#foreach($pending as $p)
<tr>
<td>
Click here
</td>
</tr>
#endforeach
the connected 'route' is
Route::get("/getMyForm/{ident}", ['as' => "openMyPage", 'uses' => "BusinessController#seeMyForm"]);
the method on BusinessController has
public function seeMyForm($ident){
$myResult=DB::select(...);
return view('MyViewBlade')->with('myResult', $myResult);
}
the master template (PrincipalView.blade.php) (as was included in the view-blade to display
<!DOCTYPE html>
<html>
<head>
<meta name="csrf_token" content="{{ csrf_token() }}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="assets/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/css/bootstrap-theme.min.css" rel="stylesheet">
<link href="assets/css/bootstrap-datepicker.min.css" rel="stylesheet">
<!-- <link rel="stylesheet" href="assets/js/jquery-ui/jquery-ui.css"> -->
<script src="assets/js/jquery.js"></script>
<!-- <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> -->
<script src="assets/js/bootstrap-datepicker.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
<script src="assets/js/jquery-ui-1.11.4.custom/jquery-ui.js"></script>
<link rel="stylesheet" href="assets/js/jquery-ui-1.11.4.custom/jquery-ui.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="assets/js/jquery-pessoal.js"></script>
<script src="assets/js/jquery-pessoal2.js"></script>
<link rel="stylesheet" href="assets/plugins/multiple-select-master/multiple-select.css"></script>
<script src="assets/plugins/multiple-select-master/multiple-select.js"></script>
<link href="assets/css/custom.css" rel="stylesheet">
</head>
...
<div class="container">
#yield("corpo")
</div>
...
the view-blade which will display (ToAproveView.blade.php)
#extends('PrincipalView')
#section('corpo')
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label>Cliente Principal: </label><br>
<input type="text" id="idTxtFaturamentoAprovacaoCliente"
name="namTxtFaturamentoAprovacaoCliente"
readonly value="{{$myResult[0]->clienteprincipal}}"/>
</div>
</div>
is not working. The last view-blade do not render its elements. The view opens itself not well formatted.
Other actions make all other views-blade ok.
I found out, the problem is connected with the line code
Click here
because it was created on the fly (I guess).
Looking at the console of Chrome, is there
GET http://172.16.0.30/laravel/tempo/public/pesquisar-Faturamento-verFormulario/assets/css/bootstrap-theme.min.css
29638_1472048778961_121:16 GET http://172.16.0.30/laravel/tempo/public/pesquisar-Faturamento-verFormulario/assets/css/bootstrap-datepicker.min.css
29638_1472048778961_121:18 GET http://172.16.0.30/laravel/tempo/public/pesquisar-Faturamento-verFormulario/assets/js/jquery.js
29638_1472048778961_121:13 GET http://172.16.0.30/laravel/tempo/public/pesquisar-Faturamento-verFormulario/assets/css/bootstrap.min.css
29638_1472048778961_121:22 GET http://172.16.0.30/laravel/tempo/public/pesquisar-Faturamento-verFormulario/assets/js/bootstrap-datepicker.js
29638_1472048778961_121:28 GET http://172.16.0.30/laravel/tempo/public/pesquisar-Faturamento-verFormulario/assets/js/jquery-ui-1.11.4.custom/jquery-ui.js
net::ERR_CONNECTION_RESET
29638_1472048778961_121:29 GET http://172.16.0.30/laravel/tempo/public/pesquisar-Faturamento-verFormulario/assets/js/jquery-ui-1.11.4.custom/jquery-ui.css
net::ERR_CONNECTION_RESET
29638_1472048778961_121:23 GET http://172.16.0.30/laravel/tempo/public/pesquisar-Faturamento-verFormulario/assets/js/bootstrap.min.js
net::ERR_CONNECTION_RESET
The including css and js files do not work (the names in the path are different of that I was wrote abore because I made a translation to better comprehension)
I found out where the error is.
I changed the path to .js and css files in default template and the view rendered correctly:
<link href="../assets/css/bootstrap.min.css" rel="stylesheet">
Although there is not the correct answer, since this template serves several views-blade that work perfectly, for now it is ok to me.

using 3 layouts on same gsp page

this is edit of my question that was first how to apply 2 layouts in the same gsp page but now i got problem with 3 layouts :) :
I am fairly new to all that css and layout stuff and i'm using grails 2.0 version
i have the following moduls in my problem:
1. main.gsp layout which basically have a nice header with company logo for all pages.
2. mainTabPanle.gsp layouts which basically contain some main tabs all pages should have
3. reportTab.gsp layout which basically contain nice report tabs and short javascript code to manipulate chosen tab color that all reports gsp pages should have.
what i am trying to do is to use this reportTab layout in all the reports gsp pages.
so this is what i got so far:
main.gsp:
<!doctype html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}"type="text/css">
<g:layoutHead/>
<r:layoutResources />
</head>
<body style="height:100%">
<div>some nice header in here </div>
<g:layoutBody/>
<r:layoutResources />
</body>
</html>
mainTabPanle.gsp (also located in layout folder)
<g:applyLayout name="main">
<!doctype html>
<html>
<head>
<g:layoutHead/>
<r:layoutResources />
</head>
<body>
<div>some main tabs here </div>
<g:layoutBody/>
</body>
<script type="text/javascript">
//script to manipulate main tabs
</script>
<r:layoutResources />
</body>
</html>
</g:applyLayout>
reportTabPanel.gsp:
<g:applyLayout name="mainTabPanel">
<!doctype html>
<html>
<head>
<g:layoutHead/>
<r:layoutResources />
</head>
<body>
<div>some reports tab panel </div>
<g:layoutBody/>
</body>
<script type="text/javascript">
//some script to manipulate report tab item
</script>
<r:layoutResources />
</body>
</html>
</g:applyLayout>
and now im using in moneyreport.gsp header the following line:
<meta name="layout" content="reportTabPanel" />
what i want to see is the nice header and the maintabsPanel and the reportTabPanel but all i see is the body of moneyreport.gsp
the weird thing is that if i use this:
<meta name="layout" content="mainTabPanel" />
inside moneyreport.gsp i see mainTab and the body of moneyreport.gsp as expected.
what am i doing wrong? i cannot use 3 layout on the same page?
thanks for your help guys ...
You can apply 2 layouts on the same page. In order to apply a different layout in a layout file, you need to use the applyLayout tag. Your reportTab should be something like this:
<g:applyLayout name="main">
<!doctype html>
<head>
<g:layoutHead/>
<r:layoutResources />
</head>
<body>
<div> some nice tabs here </div>
<g:layoutBody/>
</body>
<script type="text/javascript">
few line script handling chosen tab color in here
</script>
<r:layoutResources />
</body>
</html>
</g:applyLayout>
The best way is using templates because you can use as many as you want. I have this main HTML where I want to include different templates, like a menu and a generic content page:
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>
<g:layoutTitle default="Loto Tasks"/>
</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<g:layoutHead/>
</head>
<!-- Including menu -->
<g:render template="/templates/menu" />
<!-- Including generic content page -->
<g:render template="/templates/genericcontent" />
<g:layoutBody/>
</body>
</html>
I have a package named templates inside a views package, and inside templates I have two files, _menu.gsp and _genericcontent.gsp. The _genericcontent.gsp file looks like the following simple code. I could see that this is a little confusing if I insert a <head> with imports to other files, but you can import in the main file and it works:
_genericcontent.gsp
<div id="mainSearchPanel" class="searchPanel">
×
Filter panel here
</div>
<div id="search-icon" class="animate__animated animate__heartBeat animate__infinite animate__slower">
<i class="fas fa-search fa-2x"></i>
</div>
first thanks for your reply Anuj !
it kind of work but in a wrong way cuz i was getting weird html source:
i was getting 2 headers and 2 body tags so basically grails just copy paste all the layout
together and that wasn't good html page even that the browser display it right!
i found what i needed and that is simply using templates!
for example i have file called "_mainHeader.gsp" which look like this:
<!-- this is my main header for all gsp pages -->
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>IntentIQ Management System</title>
<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}"type="text/css">
<link rel="shortcut icon" href="${resource(dir:'images/myImg',file:'favicon.ico')}" type="image/x-icon">
and from all pages i can use those lines like for example in page1.gsp:
<g:render template="/templates/mainHeader" />
</head>
<body>
<h1> this is page1 with header from mainHeader.gsp template </h1>
</body>
</html>
pay attention for who ever who read this to:
1.temmplate file name are with '_' character
2.the closing body tag in "page1.gsp" is closing the body tag started at "_mainHeader.gsp" file.
so basically this tempaltes stuff is kind of copy paste of parts of gsp pages and its working great!
thanks for your reply never the less!

rails haml ugly weird behaviour

I have the following helper:
def feeder value=true
if feeder? == value
haml_tag :span, :<, :class => 'selected' do
yield
end
else
yield
end
end
And the following in a view:
- feeder(false) do
= link_to 'Leda', :root
This works as expected in haml non-ugly mode (development environment == haml indented code).
However in production mode (e.g. haml ugly rendering) i get this html:
<h1>
Leda
<!-- THIS SHOULD NOT BE HERE >>> -->
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Feeder</title>
<meta name="csrf-param" content="authenticity_token"/>
<meta name="csrf-token" content="8kp4xt6ZJU2nL5uLgVBW6BcB/RTA75QwynKvZTMtNF8="/>
<link href="/leda/stylesheets/jquery-ui/smoothness/jquery-ui.css?1297978005" media="screen" rel="stylesheet" type="text/css" />
<link href="/leda/stylesheets/admin.css?1298951622" media="screen" rel="stylesheet" type="text/css" />
<script src="/leda/javascripts/jquery.js?1297978005" type="text/javascript"></script>
<script src="/leda/javascripts/jquery-ui.js?1297978004" type="text/javascript"></script>
<script src="/leda/javascripts/rails.js?1297978005" type="text/javascript"></script>
<script src="/leda/javascripts/application.js?1300153136" type="text/javascript"></script>
</head>
<body>
<div id='wrapper'>
<div id='header'>
<h1>
Leda
<!-- <<< END -->
»
<span class='selected'>gvm1</span>
</h1>
Replacing the else clause with this:
else
haml_tag :span do
yield
end
end
fixes the problem, but i can't possibly understand why/how. What puzzles more is that it only fails on haml ugly rendering mode.
Why not just do it all in the view, like this?
%span{:class => blah.feeder? && "selected"}= link_to 'Blah', blah
(haml docs on this are right here.)
Your helper version seems unnecessarily complex.

Resources