This GSP:
<g:link controller="book" action="show" id="5">Example</g:link>
results in this HTML:
Example
This is relative to the HTTP host. If your site is running at http://localhost:8080 that's fine.
During development, an app will more commonly be running at http://localhost:8080/appName.
In such cases, the above link will not work - it will result in an absolute URL of http://localhost:8080/book/show/5 instead of the required http://localhost:8080/appName/book/show/5
What changes are required of the above GSP for the app name to be present in the resulting anchor's href?
The configuration setting grails.app.context should be equal to the context where you want your application deployed. If it's not set, as in the default configuration, it defaults to your application name, like http://localhost:8080/appName. If you want to deploy your app in the root context (e.g. http://locahost:8080/), add this to your Config.groovy:
grails.app.context = "/"
If the context is properly set, the URLs generated by g:link tags will include the context before the controller name.
I found that the meta tag is very useful for getting information in GSP files.
For example, if you want your application name, you can get it like this:
<g:meta name="app.name"/>
You can get any property in your application.properties file like that.
And if you, like me, need to concatenate it to another value, here is my example. Remember that any tag can be used as a method without the g: namespace. For example:
<g:set var="help" value="http://localhost:8080/${meta(name:"app.name")}/help" />
Grails documentation about this is a little poor, but it is here.
For me the single best reason to use <g:link> is that it adds the context if there is one, or omits it if you're running at http://localhost:8080 or in prod at http://mycoolsite.com - it's trivial to just concatenate the parts together yourself otherwise.
The same goes for using g:resource with css, javascript, etc. - it lets you have one GSP that works regardless of what the context is (e.g. 'appName'), since it's resolved at runtime.
I think that is what grails.serverURL is for. You defined this config variable in the Config.groovy, check the configuration documentation for Grails for more details.
Hope this helps!
createLink tag includes your appname / context parameter automatically in the link.
Here is reference doc for it.
Related
I am trying to set up my grails config locations but I am not sure what to put instead of userHome, I changed the app name to file_down which is what my app is called. So how does it work ?
grails.config.locations = [ "classpath:${file_down}-config.properties",
"classpath:${file_down}-config.groovy",
"file:${userHome}/.grails/${file_down}-config.properties",
"file:${userHome}/.grails/${file_down}-config.groovy"]
First and for maintaining default settings, you don't have to modify those statements; they will be resolved to their appropriate values when the app is running because that location needs to get to the ".grails" directory. If you want to see what the value is, add this statement in some controller or a gsp page (no println and quotes are needed then):
println "${System.properties.'user.home'}"
And that will tell you what the path resolves to, it would be something like c:\Users\katkut for example for a username being katkut. If you have your .grails folder in some other place then go ahead and put the absolute path as you wish instead, but, I hope you are maintaining the default installation settings.
One more thing. If userHome gives you null when you try to print it, just replace it with user.home as you see in the above statement, I believe they are the same, but the latter is accessible inside your .groovy and .gsp files.
When I create a tag <g:javascript src="highcharts/highcharts.js?v=255" /> i get the error:
I can't work out the type of /tools/js/highcharts/highcharts.js?v=205 with type [text/javascript]. Please check the URL, resource definition or specify [type] attribute
The docs say that g:javascript doesn't have a type attribute and after looking through the grails source I found that it's using FileNameUtils.getExtension() to determine the type of resource. Since that just does a lastIndexOf('.') and returns the right side of that, it obviously won't be found. In this case we don't really need to add the v=255 so I can remove it for now however I'd still like to be able to do so in the future. What are my options here?
Grails version is 2.1.2
What about using the HTML tag?
<script src="highcharts/highcharts.js?v=255 type="text/javascript"/>
If all you want is deal with versioning javascript includes so you can set the cache high and change the number as needed you should look at the grails cached resources plugin.
Personally I think you would want to make highcharts.js part of a module for the resources plugin to deal with for you. It will take care of versioning and minification etc as you let it. The quick start should give you enough to get going.
I have a web application that can be accessed either directly as http://host.foo.loc:8080/foo/ or via a secure reverse proxy as http://www.company.com/apps/foo/
By default, Grails will generate relative URLs with relative paths, for example:
<g:form action="bar">
will produce:
<form action="/foo/bar" method="post" >
This will be OK locally but the reverse proxy will not accept http://www.company.com/foo/bar (it's missing /apps/)
If I do:
<g:form action="bar" base=".">
it's fine. But I don't really want to specify it on each and every tag that generates a link.
The best way to deal with this would be to get Grails to generate relative paths in its relative URLs. Alternatively, I could live with setting a global "baseUrl" to "." but I don't know how to do that either.
Any idea ?
[edit] In fact, setting the "base" to "." doesn't work. The first page "/foo/controller/action" will generate the link as "./controller/nextaction" which the browser will translate as "/foo/controller/controller/action" => 404. I guess this is why they're using absolute paths: they're not paths.
I've never been able to make this kind of scenario work, so I always keep the proxied and unproxied context paths the same, i.e. I would put the app at http://host.foo.loc:8080/apps/foo. You can have a multi-level context path like this in Tomcat by naming the WAR file apps#foo.war.
Add grails.app.context = "/foo/bar" to your Config.groovy.
I want to include a spark view in another spark view.
I've tried to use the include tag.
But it doesn't seem to support variables as part of the href attribute.
Eg.
<include href="_group_${groupData.Type}.spark" />
Does anyone know of any workaround to do this?
The <include> tag is part of the Spark language that gets parsed on the first pass and cannot include variables of its own because the view class file has not yet been generated for the variables to be evaluated. Using <include> is a means of including a static resource of some kind.
I think the thing you may be looking for is the <use import="myFile.spark"/> tag for including other Spark files, or you could just use Spark Partials built in. The problem however is that you're trying to have the included spark files dynamically determined at runtime which I don't think will be possible.
Is there any way you can pre-generate the views for each groupData.Type value using the pre-compilation ability in Spark?
The other option potentially (if you really do need these dynamic at runtime) is to create and maintain an InMemoryViewFolder instance and you can add "virtual" files to it as you pull them out of the database but you still won't get away with using variables inside any Spark language elements because variables "don't exist" at that point in the parsing/rendering pipeline.
Hope that helps,
Rob
I am trying to develop a grails application that has "root" content (www.mydomain.com/about for example) but will also support "projects" based upon the subdomain of the request; for example myproject.mydomain.com > www.mydomain.com/myproject. As a first pass, i have the URL configuration below:
"/$controller/$action?/$id?" {
...
}
"/$project/$controller/$action?/$id?" {
constraints {
}
}
The main drawback so far is that the $project variable must be injected manually into every link (tedious and not DRY):
<g:link controller="foo" action="bar" params="${[project: params.project]}">link</g:link>
Is there a way to automatically inject the $project parameter into all links if it is present, or is there a better way to approach this problem?
Basically you can create a grails plugin that will inject into the controller a new project param with a value based on a custom TagLib <g:project bean="myproject"/> (for instance)
It will force you to define this tagLib on each gsp page of your project but it is still DRYer than each link.
Hope it helps,
Fabien.
I can think of a couple of things.
a) You can place a proxy (Apache or something else) in front of your app-server and do some url-rewriting. Bonus: This would also allow you to do some caching of static resources.
b) This solution is a little more technically interesting. You can look up the project based on the http host header (the subdomain part). This will save you from rewriting all urls, all Grails conventions will still apply so you shouldn't run into any problems with third party plugins and so on.