1

I have a Grails app which pulls in several Grails Plugins. These plugins need to be reused by several other Grails apps not just my own.

In a Resources Bundle in one of the Grails Plugins I have the following defined: leaving this for completeness, but I have since switched to the Asset-Pipline

modules = {
    directivea {
        resource url: 'directives/directivea/directivea.js'
        resource url: 'services/restapis.js'
    }
}

In a Javascript file in one of the plugins I have the following directive defined:

ModuleA.directive('directivea',function() {
    return {
        restrict: 'EA',
        scope: {
            'objId' : '='
        },
        replace: true,
        link: function(){
            $scope.ObjId = attributes[''];
            $scope.someFunction($scope.ObjId);
        },
        controller: function(){
            $scope.someFunction = function(objId){
                //some stuff happens here
            };
        },
        templateUrl: 'directives/directivea/directivea.html'
    }
});

It seems to be executing the controller just fine but when it tries to pull in the template it chokes on:

GET /appname/directives/directivea/directivea.html 404 (Not Found)

This makes sense because that's not where the partial template will be. Where would it be though? How can I keep that information isolated to within the plugin but usable by all the downstream applications? I'd like to avoid defining in-line templates if I can.

**EDIT TO INCLUDE STRUCTURE**

Structure of Plugin:

  • grails-app
    • conf
      • PluginNameForGrailsResources.groovy
      • BuildConfig.groovy
    • controllers
      • PluginControllerA.groovy
      • PluginControllerB.groovy
    • domain
      • PluginDomainA.groovy
  • web-app
    • css
    • directives
      • directivea
        • directivea.js
        • directivea.html
    • services
      • restapis.js
  • application.properties
  • PluginNameForGrailsGrailsPlugin.groovy

Structure of the application referencing my Plugin:

  • grails-app
  • conf
    • BuildConfig.groovy
  • controllers
  • domain
  • views
    • layouts
      • main.gsp
    • index.gsp (references to directivea via resources r:require tag)
  • web-app
  • css
    • main.css
  • js
    • index.js
  • application.properties

**EDIT TO INCLUDE STRUCTURE POST-ASSET-PLUGIN-SWITCHOVER** no more Resources defined, BuildConfig.groovy now references the asset pipline instead of Resources, no more files in web-app

  • grails-app
    • conf
      • BuildConfig.groovy
    • controllers
      • PluginControllerA.groovy
      • PluginControllerB.groovy
    • domain
      • PluginDomainA.groovy
    • assets
      • javascripts
        • directivea
          • directivea.js
          • directivea.html
        • services
          • restapis.js
      • application.properties
      • PluginNameForGrailsGrailsPlugin.groovy
Randyaa
  • 2,935
  • 4
  • 36
  • 49
  • Have you tried `templateUrl: 'static/directives/directivea/directivea.html'` ? Resources plugin's default structure for static resources is `/static/..`. It will be great if you show the project structure or share an app in github show casing the problem. – dmahapatro Aug 15 '14 at 20:17
  • Is it resolved by using `static/..` as mentioned in previous comment? – dmahapatro Aug 18 '14 at 15:39
  • No, static/.. does not work – Randyaa Aug 18 '14 at 19:31
  • I've updated the quesiton to include the project structure – Randyaa Aug 18 '14 at 19:42
  • 1
    Looks like `directivea.js` and `directivea.html` are siblings of `directivea` directory. Is that correct? – dmahapatro Aug 19 '14 at 00:13
  • No they are children. Sorry about that. – Randyaa Aug 19 '14 at 00:13
  • Ok. Works for me. Will add an answer in few minutes. – dmahapatro Aug 19 '14 at 01:25
  • I actually just tried to fix the indenting and it seems that StackOverflow doesnt support nested lists that deep? The question is formatted correctly but it clearly displays them at the same level :( – Randyaa Aug 19 '14 at 13:15
  • It's ok. Did you get a chance to look at the sample app and plugin? – dmahapatro Aug 19 '14 at 13:30
  • I didn't run it but yes I looked. everything looks great with the exception of using the /static reference means I won't be able to run the plugin as a standalone app as well. I didn't include that in my question description but it's a secondary requirement for me. – Randyaa Aug 19 '14 at 13:32
  • I think you can still run it (with /static/..) as stand alone app as long as you are using resources plugin in the plugin. – dmahapatro Aug 19 '14 at 13:44

2 Answers2

2

Using the Grails Resource plugin

Refer this sample grails app which uses this grails plugin.

Plugin hosts an angular module. I tried to keep it simple by just adding a directive and no other module. Also note that I have used static/.. in the templateUrl in directive.

Also refer Config.groovy in the app which uses below config

grails.resources.adhoc.includes = ['/images/**', '/css/**', '/js/**', '/img/**']

as mentioned in the answer to this question. May be you are hitting this issue.

Give it a try. "Hello World" is rendered from the directive present in an angular module inside the plugin.

If you are using latest version of Grails then I would suggest to switch to asset pipeline whenever convenient.

Using the Grails Asset Plugin

Use the Grails asset-pipeline plugin (v 1.9.7 as of this posting) and the Grails Angular-template-asset-pipeline plugin (v 1.2.5 as of this posting).

For details on exactly how to set this up, see the answers to How to reference a static HTML resource using the Grails Asset Pipeline plugin.

Primarily, ensure your Angular JS module is lowercase or uses _'s or -'s in the name and that your template file has a slightly different filename (ignoring the extension) than any of the javascript assets you're including.

Community
  • 1
  • 1
dmahapatro
  • 49,365
  • 7
  • 88
  • 117
  • Thanks I'll take a look in a bit. I have actually switched to the asset pipeline plugin but I'm still unable to reference the angular template. – Randyaa Aug 19 '14 at 01:44
  • Gr8. I do not have a asset pipeline variant of the sample app and plugin, but it would work similarly except the configuration as compared to resources plugin. – dmahapatro Aug 19 '14 at 01:50
0

Note that the javascript is referencing things from the web-app root, not from the resources or assets directory. You can find more about Angular routing from the core documentation: $route

So templateUrl: directives/directivea/directivea.html needs to actually reference a file in the /web-app/directives/directivea/directivea.html directory.

Note that the resources plugin does not seem to be very modular, and global files need to be specified for sharing (and most other things). If you move to grails 2.4 and the assets plugin, you can do modular file paths.

tmarthal
  • 1,498
  • 19
  • 28
  • I understand how the paths are referencing the web-app root & I understand that directives/directivea/directivea.html would need to reference a file there. What I need to know is how to properly reference it given the real location (coming from the web-app directory of the included plugin). I am using grails 2.4.1 so I'll take a look at the Assets plugin you mention. – Randyaa Aug 18 '14 at 13:58
  • I've switched things around to use the asset pipeline and while everything seems a lot cleaner, I'm unable to find a way to reference the HTML templates. I found an asset pipeline angular js plugin which looked very promising but it didn't do the trick either. – Randyaa Aug 19 '14 at 00:16
  • With the assets plugin, put the angular html into the `javascripts` directory called `views` or something, and reference them from the angular code using relative paths (e.g. views/directives/). Should be encapsulated within the plugin. – tmarthal Aug 19 '14 at 07:15
  • this seemed very promising but with the new structure (see updated question) I get : GET http://localhost:8080/pluginName(or-app-name)/directivea/directivea.html 404 (Not Found) – Randyaa Aug 19 '14 at 13:25
  • You're going to have to make it work via debugging. Load up the app and find the angular template. Modify the paths accordingly; Check to make sure the filepaths are relative (no '/' prefix), etc. – tmarthal Aug 19 '14 at 22:07