sparkyspider
sparkyspider

Reputation: 13529

Grails: How do I use the resources plugin to add a CSS "link" tag into the head?

I have a page that uses quite a lot of include files. It dynamically selects the correct include file to use. I'd like to (in the include file) be able to specify to grails that I'd like it to include a specific <link rel="stylesheet"/> tag into the head, on the fly.

Something output like this..

<html>
  <head>
    <title>My Life :: My Pets</title>
    <link rel="stylesheet" href="style.css" type="text/css"> <!-- Normal Site Style -->
    <link rel="stylesheet" href="include-my-pets" type="text/css"> <!-- Dynamic Style for Include -->
  </head>
  <body>
    <h1>My Pets</h1>
    <!-- This is the include file start -->
       In the GSP here I said something like:
       <r:require disposition="head">
         <link rel="stylesheet" href="include-my-pets" type="text/css"> <!-- Dynamic Style -->
       </r:require>
       to get the CSS link tag pushed into the head.
    <!-- This is the include file end -->
  </body>
</html>

This has worked very well for me using the <r:script/> tag. I can specify anywhere in any include file:

<r:script disposition="head">
  alert ('hello')
</r:script>

And my layout automatically gets the alert hello stuck inside a <script/> tag in the head of the page. It is also removed from the body.

Upvotes: 1

Views: 4191

Answers (3)

Ingo Kegel
Ingo Kegel

Reputation: 48105

This is not supported by the resources plugin. If you look at the r.script implementation in ResourcesPlugin:

def script = { attrs, body ->
    def dispos = attrs.remove('disposition') ?: 'defer'
    storePageFragment('script', dispos, body())
}

it would seem to be easy to do something similar for an "r.stylesheet" tag, but storePageFragment and other helper methods are private, so you cannot do it from outside without duplicating a lot of stuff.

I would suggest you fork the resources plugin, implement a stylesheet tag along the lines of the script tag and send a pull request.

Upvotes: 1

sparkyspider
sparkyspider

Reputation: 13529

This is not the "grails" way of doing things, but this is how I implemented it. Part of the reason I did this is because I feel that defining resources in ApplicationResources.groovy may not be obvious to non-grails developers that are not familiar with the resources plugin. I preferred the idea of having explicit resource links in the include files which are obvious.

The way I've done it now is such.

Kitty and Doggy needed custom CSS and JavaScript (they're both part of pets), but the other links, such as MyLife don't need them.

In URLMappings.groovy

"/mypets/kitty" {
    controller="pets",
    subpage="kitty.gsp"
    action="index"
    css="kitty.css",
    js="kitty.js",
}
"/mypets/doggy" {
    controller="pets",
    subpage="doggy.gsp"
    action="index"
    css="doggy.css",
    js="doggy.js",
}
"/mylife" {
    controller="life",
    action="index"
}

layout.gsp

...contains all the usual site-wide resources...

In pets.gsp

<html>
  <head>
    <title>${title}</title>
    <link rel="stylesheet" type="text/css" href="${resource(dir: 'resources/modules/css', file: css)}"/>
    <script src="${resource(dir: 'resources/modules/js', file: js)}"></script>
  </head>
  <body>
    Select your pet: <select.../>
    <!-- It's kitty.gsp and doggy.gsp (below) that need access to their own kitty and doggy js and css files -->
    <g:include view="$page"/>
  </body>
</html>

Upvotes: 0

Tom Metz
Tom Metz

Reputation: 919

The advantage of the resource plugin is, that you can create logical groups of resources (both css and js) and use them, where you need. Alo don't forgett to call <r:layoutResources /> at the end of head sectioc and at the end of the body section. Without that, the resources are not generated correctly.

Upvotes: 0

Related Questions