Grails—url映射中的语言前缀

Grails—url映射中的语言前缀,grails,url-routing,friendly-url,link-tag,Grails,Url Routing,Friendly Url,Link Tag,你好,我在语言映射方面有问题。我希望它的工作方式是,语言被编码在url中,比如/appname/de/mycontroller/随便什么 如果您转到/appname/mycontroller/action,它应该检查您的会话,如果没有会话,则根据浏览器首选项选择语言,并重定向到以语言为前缀的站点。如果您有会话,那么它将显示英语。英语没有英语前缀(使它更难) 因此,我创建了如下映射: class UrlMappings { static mappings = { "/$la

你好,我在语言映射方面有问题。我希望它的工作方式是,语言被编码在url中,比如/appname/de/mycontroller/随便什么

如果您转到/appname/mycontroller/action,它应该检查您的会话,如果没有会话,则根据浏览器首选项选择语言,并重定向到以语言为前缀的站点。如果您有会话,那么它将显示英语。英语没有英语前缀(使它更难)

因此,我创建了如下映射:

class UrlMappings {
    static mappings = {
        "/$lang/$controller/$action?/$id?"{
            constraints {
                lang(matches:/pl|en/)
            }
        }
        "/$lang/store/$category" {
            controller = "storeItem"
            action = "index"
            constraints {
                lang(matches:/pl|en/)
            }
        }
        "/$lang/store" {
            controller = "storeItem"
            action = "index"
            constraints {
                lang(matches:/pl|en/)
            }
        }


        "/$controller/$action?/$id?"{
            lang="en"
            constraints {
            }
        }
        "/store/$category" {
            lang="en"
            controller = "storeItem"
            action = "index"
        }
        "/store" {
            lang="en"
            controller = "storeItem"
            action = "index"
        }


      "/"(view:"/index")
      "500"(view:'/error')
    }
}
它还没有完全工作,LAGS只是暂时硬编码的。我想我做错了什么。有些反向映射可以工作,但有些不添加语言

如果我使用link标记并传递参数:[lang:'pl'],那么它可以工作,但如果我添加参数:[lang:'pl',page:2],那么它就不能工作。在第二种情况下,lang和page number都成为查询字符串中的参数。更糟糕的是,它们不影响区域设置,因此页面以英语显示

有谁能告诉我反向映射的规则是什么,或者更好的方法是如何以一种好的方式实现这种语言前缀


谢谢

你要解决的最大问题是英语没有前缀。您的大多数映射看起来都完全正常。我建议您使用命名映射

但首先,我建议您使用过滤器为每个用户设置语言参数

def filters = {
    languageCheck(controller: '*', action: '*') {
        before = {
            if( params.lang == null) {
                redirect( controller: params.controller, action: params.action, params:[ "lang": request.locale.language.toString() ] + params )
            }
        }
    }
}
如果缺少语言参数的用户进入您的站点,该语言将由过滤器设置,并将其重定向到具有语言参数的控制器。如果您使用的安全框架也在重定向,请小心。您只能重定向一次。在这种情况下,您必须从过滤器中排除这些URL或控制器

现在我们来看看你的映射问题。自从Grails1.2以来,就有所谓的命名URL映射。例如

name storeCategory: "/$lang/store/$category" {
        controller = "storeItem"
        action = "index"
        constraints {
            lang(matches:/pl|en/)
        }
    }
在GSP中,您可以使用

<g:link mapping="storeCategory" params="[lang:'en', category:'new']">Category</g:link>
类别

这应该能解决你的问题。您可以在

中找到有关命名映射的所有信息。您必须解决的最大问题是没有英文前缀。您的大多数映射看起来都完全正常。我建议您使用命名映射

但首先,我建议您使用过滤器为每个用户设置语言参数

def filters = {
    languageCheck(controller: '*', action: '*') {
        before = {
            if( params.lang == null) {
                redirect( controller: params.controller, action: params.action, params:[ "lang": request.locale.language.toString() ] + params )
            }
        }
    }
}
如果缺少语言参数的用户进入您的站点,该语言将由过滤器设置,并将其重定向到具有语言参数的控制器。如果您使用的安全框架也在重定向,请小心。您只能重定向一次。在这种情况下,您必须从过滤器中排除这些URL或控制器

现在我们来看看你的映射问题。自从Grails1.2以来,就有所谓的命名URL映射。例如

name storeCategory: "/$lang/store/$category" {
        controller = "storeItem"
        action = "index"
        constraints {
            lang(matches:/pl|en/)
        }
    }
在GSP中,您可以使用

<g:link mapping="storeCategory" params="[lang:'en', category:'new']">Category</g:link>
类别

这应该能解决你的问题。您可以在

中找到有关命名映射的所有信息。我想补充一点:如果您有额外的参数,应该使用?param=value进行附加,如果您不将它们显式添加到URL映射中,您将遇到麻烦。这是因为URL映射解析器将控制器和操作参数视为具有特殊含义的参数,并且只匹配具有用于生成链接的完全相同参数集的映射

然而,当您使用分页时,您将遇到麻烦

因此,除了上述操作外,还应执行以下操作:

class LangAwareUrlMappingsHolderFactoryBean extends UrlMappingsHolderFactoryBean {

    @Override
    public UrlMappingsHolder getObject() throws Exception {
        def obj = super.object
        obj.DEFAULT_CONTROLLER_PARAMS = [UrlMapping.CONTROLLER, UrlMapping.ACTION,     "lang"] as Set
        obj
    }   
}
并调整资源。groovy:

你会得到

/en/controller/action?offset=10
而不是

/controller/action?offset=10&lang=en

我想补充一点:如果您有额外的参数,这些参数应该使用?param=value追加,如果您不显式地将它们添加到URL映射中,您将遇到麻烦。这是因为URL映射解析器将控制器和操作参数视为具有特殊含义的参数,并且只匹配具有用于生成链接的完全相同参数集的映射

然而,当您使用分页时,您将遇到麻烦

因此,除了上述操作外,还应执行以下操作:

class LangAwareUrlMappingsHolderFactoryBean extends UrlMappingsHolderFactoryBean {

    @Override
    public UrlMappingsHolder getObject() throws Exception {
        def obj = super.object
        obj.DEFAULT_CONTROLLER_PARAMS = [UrlMapping.CONTROLLER, UrlMapping.ACTION,     "lang"] as Set
        obj
    }   
}
并调整资源。groovy:

你会得到

/en/controller/action?offset=10
而不是

/controller/action?offset=10&lang=en
真棒:-)谢谢命名映射似乎是我的选择。真棒:-)谢谢命名映射似乎是我的选择。