Reputation: 187499
In my Grails app, I have the following controller & action
class FestivalController {
def show() {
[festival: Festival.get(params.id)]
}
}
I would like all of the following URLs to map to this controller
/festival/show/1
/festival/show/1/glastonbury
/1/music/glastonbury
where glastonbury
and music
are the name and type of the festival respectively. Notice that only the ID (1) is actually needed to identify the festival, so the name and type are included in the URL for reasons of SEO and readability (of the URLs).
I attempted to support these different URLs with the following URL mappings
// this supports the 3rd mapping above
name showFestival: "/$id/$type?/$name?" {
controller = "festival"
action = "show"
}
// this supports the 1st mapping above
"/$controller/$action?/$id?/$name?"{
constraints {
}
}
These support the 1st and 3rd URL mappings, but if I try the 2nd
/festival/show/1/glastonbury
it doesn't work. Ideally, I would like Grails to always generate a URL of the form:
/1/music/glastonbury
when I use g.createLink
or g.link
, but I would also like the following URLs to map to this action (for historical reasons):
/festival/show/1
/festival/show/1/glastonbury
Upvotes: 0
Views: 2496
Reputation: 122364
Without seeing your other mapping rules it's hard to know what's relevant and what isn't... The behaviour you're seeing is inconsistent with the usual precedence rules, which I extracted from the source a while back and which say that when two mappings could apply to the same incoming URI, the one that wins is the one that has:
**
or $var**
), or if both are equal then*
or $var
), or if both are equal then/foo/*/baz
beats /foo/bar/*
), or if both have their leftmost wildcard in the same place thenconstraints
By these rules, /festival/show/1/glastonbury
matches only the second mapping, so should work correctly, but /festival/show/1
matches both, so should be picked up by /$id/$type/$name
(fewer wildcards), resulting in [controller:'festival', action:'show', id:'festival', type:'show', name:'1']
.
Adding an explicit rule for "/festival/$action?/$id?/$name?"(controller:'festival')
should fix things as /festival/show/1
will match both this mapping and the /id/type/name
one, but the explicit /festival/...
mapping has more non-wildcard path segments (1 vs none).
Upvotes: 3