I'm setting a variable in grails-app/views/layout/main.gsp to a value, like
<g:set var="welcometext" scope="session">Hello, pleased to meet you!</g:set>
But when I try to access it in my view grails/app/views/index.gsp with
<html>
<head>
<meta name="layout" content="main"/>
</head>
${welcometext}
<body>
</html>
Nothing gets printed out. So the variable set in main.gsp is not accessible to my view index.gsp. I tried also to set the scope to page, request and session, but success.
How can I set a variable in my layout main.gsp and reference it in other views?
You can define variables in your page (index) and your layout can see them (which is really useful for breadcrumb for example).
However, you can't access to a variable defined in your layout from your page (index) because the page is rendered like there was no layout, and then we apply the layout to the page rendered.
As a shortcut, you can see the rendering flow like this: (render Index) THEN (render Layout)
So, in your case, you have to find another solution, depending on your content:
Put the welcometext in session (not the best solution)
Pass it as a parameter of each view (not the best solution)
Create a custom tag to automatically print it
Create a template and render it where you need
Hardcode it ? (I don't like this one, but it's closer to what you're trying to do)
Use JavaScript to add the text ?
...
Try to see which one is the best for you ;)
Related
I have a layout file. I want something like this in each of my pages inheriting that layout:
Just ${step} Steps Away From The Awesome!!
So in my layout I have defined a string as above with a placeholder step. I dont want to pass the value of this placeholder from controller. I wish to define it in the gsp that inherits this layout.
I was looking for something like <g:set var="step" value="1"/> (or 2 or 3 depending on the gsp). But it does not work if I define it like that.So how do I dereference the value of "step" inside each extending layout?
One of the best ways to accomplish this is to make use of content blocks and page properties. These are both features derived from Sitemesh.
I assume you only want to conditionally include this information when the page using the layout provides a value. So in my example here I have wrapped it in a quick if check.
In your layout:
<g:if test="${pageProperty(name: 'page.step')}">
Just <g:pageProperty name="page.step" /> Steps Away From The Awesome!!
</g:if>
Then in any page that uses the layout you can include the content for the variable step
<content tag="step">3</content>
Note that the value within the content tag can be whatever you like. It will be evaluated when the page is rendered.
I have a plugable scenario on asp.net mvc. My Layout file contains a method for Head and body. Methods are rendering related plugin. So I have only one Controller/Action (Page/Index) and I dont need any view file for this action. Is that posible working without View file or only Layout file?
Thanks.
Layout example.
<html>
<head>
<title></title>
</head>
<body>
<div> MENU </div>
<div>
Plugin.Render("body"); //Render plugin method.
</div>
</body>
</html>
It seems an odd situation, but regardless:
It all depends on what you expect your one method to return. If it returns non-HTML (e.g. JSON, any primitive type, ...), you don't need it, obviously.
A HTML-layout is generally rendered via Views. I'm not sure if you can address your Master/Layout page as a view in and of itself. What I would suggest is adding a View file, setting it up with the correct Master/Layout page, and then basically empty out the view file.
So you'd have a View file, but it wouldn't have any content in it (except for the Master/Layout page setting).
It'd be slightly more understandable for future developers (although not that much), and I don't see any real downside to this (performance-wise or other).
I have seen in documentation that fields are not rendered in the view, and instead it can be used in helpers, partials etc. but I can't find a way how they are used.
The documentation says to use it like this:
{{ cms:field:some_label }}
But I am courios how can I use that? I wanted to be able to define some text in the snippet and then, use that field in my partial or in my helper function to form some data that will be used in the view. Can somebody tell me how can I use fields in this CMS?
Imagine you have a CMS site set up so it's using an application layout. Somewhere in that layout you have: <meta name="description" content="Something about the page"> Now, how do you dynamically populate content of that tag from the page? We can define {{cms:field:meta_description}} tag.
In the admin area you'll be able to populate it and. Now you need to output that like this:
<meta name="description" content="<%= cms_block_content(:meta_description) %>">
What I mean is this: I've got a layout page that shows a different favicon depending on what action is being invoked. So I've got some code in the layout that looks like this:
<link href="/images/favicon/#(AmbientPage.ShortName).ico" type="image/ico" rel="icon" />
The AmbientPage variable is a global value that's set in the Index action, and read by the layout file, which dynamically writes the icon filename for whatever page was requested. This seems really kludgy to me, but I'm not seeing a great way around it either.
What do you do when the Layout page needs to know something that happened in the action?
Usually I would use a child action or section to avoid having logics in the layout page. So in the case above, other ways of doing it would be passing the name of the current page to an child action and let child action determine what icon/action to use.
It would be something like:
#Html.Action("Icon", "Default", new { #ViewContext.RouteData["Action"] })
Or using an section, in layout page, you add the following code
//true since they all required to have an icon
#RenderSection("Icon", true)
then in your view you just do
#section Icon{
<link href="/images/favicon/currentpage.ico" type="image/ico" rel="icon" />
}
Personally, I would suggest you to use the section approach to make the code "less dependent" on each other
I am using .NET MVC, and within view pages I set a contentplaceholder that contains an ID to be used on the master page like so:
View page:
<asp:Content ID="CDomBodyId" ContentPlaceHolderID="DomBodyId" runat="server">LmpDemoRequests</asp:Content>
Master page:
<body id='<asp:ContentPlaceHolder ID="DomBodyId" runat="server"></asp:ContentPlaceHolder>'>
So in this particular case, the body tag would render like this on the final HTML page:
<body id='LmpDemoRequests'>
I would like to have double quotes around the body id tag, but inverting the quotes like the following makes intellisense unable to find the contentplaceholder, giving me a lot of warnings when I compile.
<body id="<asp:ContentPlaceHolder ID='DomBodyId' runat='server'></asp:ContentPlaceHolder>">
Is there any way around this?
This is an issue with ASP.NET editor. It's not specific to MVC. I think the workaround is pretty good and I don't see a specific drawback.
Try declaring BodyID as a property of your MasterPage. Set its value in the View pages. Then you can do something like
<html>
<body='<%= BodyID %>'>
</body
</html>
Not sure if I have misunderstood your question, but you can also add:
<body id="site" runat="server"></body>
And then access it on your page
HtmlControl body = (HtmlControl)Master.FindControl("site");
body.Attributes.Add("class", "LmpDemoRequests");
I hope I understood your correctly.