Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Grails Url Mapping config

Tags:

grails

groovy

How can I dynamically build a list of mappings - instead of:

class UrlMappings {
static mappings = {
   "/helpdesk/user/$action?/$id?" (controller="helpdeskuser")
   "/helpdesk/group/$action?/$id?" (controller="helpdeskgroup")
   "/helpdesk/company/$action?/$id?" (controller="helpdeskcompany")
   "/helpdesk/account/$action?/$id?" (controller="helpdeskaccount")
   "/admin/company/$action?/$id?" (controller="admincompany")
   "/admin/account/$action?/$id?" (controller="adminaccount")
 }
}

something like this pseudo code:

class UrlMappings {
static mappings = {
   application.controllerClasses.each {
     if(it.name.startsWith('helpdesk'))
        "/helpdesk/${it.name}/$action?/$id?" (controller="${it.name}")
     if(it.name.startsWith('admin'))
        "/admin/${it.name}/$action?/$id?" (controller="${it.name}")
   }
 }
}

(I don't understand what the static mappings are - a hash map? free variables?)

What I am trying to achieve are mappings based on the controller type - e.g. helpdesk, admin or user controllers. Once I have set up the mappings I want to add security based on URLs but I don't want to map each controller individually:

grails.plugins.springsecurity.interceptUrlMap = [
   '/helpdesk/**':   ['ROLE_HELPDESK','ROLE_ADMIN'],
]
like image 869
DavidC Avatar asked Nov 20 '10 13:11

DavidC


3 Answers

I've just done the following in my application:

import org.codehaus.groovy.grails.commons.ApplicationHolder

class UrlMappings {
  static mappings = {        
    for( controllerClass in ApplicationHolder.application.controllerClasses) {
      // Admin Controllers first
      if( controllerClass.name.startsWith("Admin")){
        // note... fixes the case so that AdminUserController maps to /admin/user
        "/admin/${controllerClass.name[5].toLowerCase() + controllerClass.name[6..-1]}/$action?/$id?" {
          controller = "admin${controllerClass.name[5..-1]}".toString()
        }
      }
    }
  }
}

I'd not actually done this before, your question prompted me to fix this is my app. It's been one of those things I've been trying to do for a while.

like image 89
Gareth Davis Avatar answered Nov 16 '22 05:11

Gareth Davis


The grailsUrlMappingsHolder bean is available in services and controllers. Although it's concrete implementation of UrlMappingsHolder doesn't have an add method, its superclass does. Simple as this in grails 2.3.4

def grailsUrlMappingsHolder

def addMapping() {        
    grailsUrlMappingsHolder.addMappings({
        "/admin"(controller:"admin" action:"index")  
    });        
}
like image 36
sparkyspider Avatar answered Nov 16 '22 05:11

sparkyspider


I wanted to achieve something similar for my application and found a nice way provided by grails. It goes like

name admin: "/admin/$cName/$action/$id?" {
    controller = {
        "admin" + params.cName.capitalize()
    }
}

Watch out, this does not work if you use $controller vs. $cName (or whatever you like to have there) and will throw a NullpointerException instead.

As a bonus you can then use the mapping name like

<g:createLink 
    controller="adminBackend" action="login" 
    mapping="admin" params="[cName:'backend']"
/>

to get a link to /admin/backend/login - Hope this helps!

Stay fresh!

like image 2
fluxon Avatar answered Nov 16 '22 07:11

fluxon