Grails - url映射中的语言前缀

时间:2010-05-12 14:33:09

标签: grails url-routing friendly-url link-tag

您好我有语言映射问题。我希望它工作的方式是语言编码在url中,如/ appname / de / mycontroller / whatever

如果你去/ 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')
    }
}

它还没有完全正常工作,langs目前只是硬编码。我想我做错了什么。一些反向映射可以工作,但有些不添加语言。

如果我使用链接标记并传递params:[lang:'pl']那么它可以工作,但如果我添加params:[lang:'pl',page:2]则它不会。在第二种情况下,lang和页码都成为查询字符串中的参数。更糟糕的是,它们不会影响语言环境,所以页面用英语显示。

任何人都可以请指出文档反向映射的规则是什么,甚至更好地如何以良好的方式实现这样的语言前缀?

感谢

2 个答案:

答案 0 :(得分:3)

您必须处理的最大问题是没有英语前缀。你的大部分映射似乎完全没问题。我建议你使用命名映射。

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

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或控制器。

现在我们来看看你的映射问题。从Grails 1.2开始,就有所谓的命名URL映射。 E.g。

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>

这应该可以解决您的问题。您可以在Grails Reference

中找到有关命名映射的所有信息

答案 1 :(得分:0)

我想补充一点:如果你有额外的params应该使用?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
    }   
}

并调整 resources.groovy

"org.grails.internal.URL_MAPPINGS_HOLDER"(LangAwareUrlMappingsHolderFactoryBean) { bean ->
    bean.lazyInit = true
}

你会得到

/en/controller/action?offset=10

而不是

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