How can I dynamically add an attribute to a body element in a GSP page - grails

In Grails 2.3.7, is there a way to use an expression in a GSP page to add an attribute to a body element? In the code below, the expression in the p element works, but the same expression in the body element causes a error: Expecting '=' after attribute name (${raw('this="that"')}).
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body ${raw('this="that"')}>
<p ${raw('this="that"')}>Hello!</p>
</body>
</html>
I'm trying to do this in a layout and pick up the corresponding attribute from the original page with pageProperty, but the same error occurs on the body element in the page layout as well.
Replacing an attribute value does work in a body element like this:
<body this="${that}">
but this won't work because I do not want the attribute to appear at all if it has no value.

the problem is, that the body tag is replaced by the <g:layoutBody /> tag and therefore could not be set like this.
One solution is to use to set different stuff in the sitemesh layout.
An example of this is shown here:
<html>
<head>
<g:layoutHead/>
</head>
<body class="${pageProperty( name:'body.class' )}">
<g:layoutBody/>
</body>
</html>

Related

why does .net core "Return" verb inside a controller adds "plaintext.css" ?

I was doing some testing with MVC6 .net core, and did a quick hack to return a bootstrap html code by putting dirtyHTML directly inside a controller.
The HTML contains the official example of bootstrap inside a literal string.
Just a quick way of returning some bootstrap html, (as i experiment with controller functionality), to my surprise when i go to a page using a web browser, all html text is shown like plain text, its not rendered.
namespace WebApplication1.Controllers
{
public class MariaController
{
[HttpGet("/index")]
public string index()
{
string dirtyHtml;
dirtyHtml =
#"<!DOCTYPE html>
<html lang=""en"">
<head>
<title>Bootstrap Example</title>
<meta charset=""utf-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1"">
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"">
<script src=""https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js""></script>
<script src=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js""></script>
</head>
<body>
<div class=""container"">
<h1>My First Bootstrap Page</h1>
";
return dirtyHtml;
}
}
When going to debug mode, initially they show the same asci text, but using firefox i see there is a line inserted before my page code:
<HTML><head>
<link rel="alternate stylesheet" type="text/css"
href="resource://gre-resources/plaintext.css"
title="Wrap Long Lines">`
So then i thought, let's look around in the solution and search for "Wrap Long Lines".. as to see where it comes from,... this is however not found.
So where does that come from ? (as the solution doesnt contain plaintext.css either). And more important to me, can it be disabled?.
I am not sure what you want to achive but following thing is way to go.
"Wrap Long Lines" and css related to that are internal to firefox browser.
You are saying that you return html and it display like html but it does not render html and for that do following thing.
[HttpGet("/index")]
public IActionResult index()
{
string dirtyHtml;
dirtyHtml =
#"<!DOCTYPE html>
<html lang=""en"">
<head>
<title>Bootstrap Example</title>
<meta charset=""utf-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1"">
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"">
<script src=""https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js""></script>
<script src=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js""></script>
</head>
<body>
<div class=""container"">
<h1>My First Bootstrap Page</h1>
";
return Content(dirtyHtml,"text/html");
}
See I have return IActionResult and Use Content from return.
Reason for this is when you return string it will display as string and if it is html then it will become encoded as you did not tell browser content type so it consider "text/plain".
An alternative of #dotnetstep's way is using Produces attribute:
[HttpGet("/index")]
[Produces("text/html")]
public string Index()
{
...
}

angular.dart seems to be slow

I am trying angular.dart and saw that its slow. When am html page is loaded containing angular, angular directive is seen first, which are then converted appropriately. Shouldn't it be converted instantaneously and the user should not see whether we are using angular ?
<!DOCTYPE html>
<html ng-app>
<head>
<title>Hello, World!</title>
</head>
<body>
<h3>Hello {{name}}!</h3>
name: <input type="text" ng-model="name">
<script type="application/dart" src="main.dart"></script>
<script type="text/javascript" src="packages/browser/dart.js"></script>
</body>
</html>
Surround {{name}} with a tag having class="ng-cloak". I used span tag. Keep it hidden by specifying css rule .ng-cloak{ display:none; }.
When angular is loaded, it will remove class="ng-cloak" from the span tag and everything will work as expected.
<!DOCTYPE html>
<html ng-app>
<head>
<title>Hello, World!</title>
<style>
.ng-cloak{ display:none;}
</style>
</head>
<body>
<h3>Hello <span class="ng-cloak">{{name}}</span>!</h3>
name: <input type="text" ng-model="name">
<script type="application/dart" src="main.dart"></script>
</body>
</html>
An alternative way is to use ng-bind as demonstrated in this youtube video: AngularJS MTV Meetup: Best Practices (2012/12/11) (after about 12 minutes)
Quoted from the API doc of NgBindDirective class
Typically, you don't use ngBind directly, but instead you use the
double curly markup like {{ expression }} which is similar but less
verbose.
It is preferrable to use ngBind instead of {{ expression }} when a
template is momentarily displayed by the browser in its raw state
before Angular compiles it. Since ngBind is an element attribute, it
makes the bindings invisible to the user while the page is loading.
This way you can display default content that get's replaced when Angular is ready
instead of showing a blank page or a progress icon.

Querying a custom element, is returned as UnknownElement

I've defined a custom element, chat-view and have it displaying on a page:
<!DOCTYPE html>
<html>
<head>
<title>index</title>
<script src="packages/polymer/boot.js"></script>
<link rel="import" href="chat_view.html">
</head>
<body>
<chat-view id="chat">
</chat-view>
<script type="application/dart" src="index.dart"></script>
</body>
</html>
I then query for the chat-view:
final ChatView chatView = query("#chat");
The previous line causes the following exception:
Exception: type 'UnknownElement' is not a subtype of type 'ChatView' of 'chatView'.
Is there a way to query for my custom element in such a way that I get an object of ChatView, instead of UnknownElement?
After some digging, I found that the custom element instance is accessed through the UnknownElement's xtag property.
final ChatView chatView = query("#chat").xtag;

Difference between <body> and <g:layoutBody>

may I know what's the difference between <body> and <g:layoutBody>, and how do I use these tags?
body tag is a HTML tag. (nothing to do with grails)
g:layoutBody should be used in templates to allow the concrete views to inject their data into the template.
Official documentation on g:layoutBody is quite helpful.
In particular, this is their example of a decorator layout a.k.a. main.gsp. In this example <g:layoutBody /> will be replaced with the body of the document to be decorated (e.g. index.gsp) and, of course, <g:layoutHead /> will be replaced with the head of the document to be decorated.
<html>
<head>
<script src="global.js" />
<g:layoutHead />
</head>
<body><g:layoutBody /></body>
</html>

Multi-lines string in Dart

I'm still working on Dart. I just want to output my string defined in .dart to my html. I look into the documentation on https://sites.google.com/site/dartlangexamples/learn/variables/strings
I understand that I need to use the """.
When I print my query, I got the good result, but when I output it in html, They are side to side.
There it is:
.dart :
var symbole = """
*
***
*****
*******
*********""";
var element03 = query('#exercice03');
element03.innerHTML = symbole;
print(symbole);
}
The Print give me exactly what I set into my var symbole BUT, in my HTML i got this:
My html is :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HelloWorld</title>
<link rel="stylesheet" href="HelloWorld.css">
</head>
<body>
<div id="container">
<p class="question">Exercice : Pritn the * : <span id="exercice03"></span></p>
</div>
<script type="application/dart" src="web/HelloWorld.dart"></script>
<script src="https://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js"></script>
</body>
</html>
I don't understand why in my output html I dont get the same result as my Print in my dart editor, can some one help me to figure this out?
I'm not sure if I follow you here -- do you want this?
var symbole = """
*<br />
***<br />
*****<br />
*******<br />
*********<br />""";
var element03 = query('#exercice03');
element03.innerHTML = symbole;
I just added the break lines
So as Matt B said, the output of print() is differently formatted than HTML on the browser.
This is because HTML is not whitespace sensitive. That is, a new line in html does not display when parsed. You need to use a line break <br> or you need to wrap it in a preformated <pre> tag

Resources