Grails - языковой префикс в отображениях URL

Привет, у меня возникли проблемы с отображением языка. То, как я хочу, чтобы это работало, заключается в том, что язык закодирован в URL, как /appname/de/mycontroller/ что угодно

Если вы перейдете в /appname/mycontroller/action, он должен проверить ваш сеанс и, если нет сеанса, выбрать язык в зависимости от предпочтений браузера и перенаправить на сайт с префиксом языка. Если у вас есть сессия, то он будет отображаться на английском языке. Английский не имеет префикса en (чтобы сделать его сложнее).

Итак, я создал сопоставления, как это:

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')
    }
}

Он не полностью работает, и языки на данный момент жестко запрограммированы. Я думаю, что сделал что-то не так. Некоторые обратные отображения работают, но некоторые не добавляют язык.

Если я использую тег ссылки и передаю params:[lang:'pl'], то это работает, но если я добавлю params:[lang:'pl', page:2], то это не так. Во втором случае и язык, и номер страницы становятся параметрами в строке запроса. Что еще хуже, они не влияют на локаль, поэтому страница отображается на английском языке.

Может ли кто-нибудь указать мне на документацию, каковы правила обратного отображения или, что еще лучше, как правильно реализовать такой языковой префикс?

СПАСИБО

2 ответа

Решение

Самая большая проблема, с которой вам приходится иметь дело, это отсутствие префикса для английского языка. Большая часть твоего картографирования кажется совершенно нормальной. Я бы порекомендовал вам работать с именованными сопоставлениями.

Но сначала я бы порекомендовал вам поработать с фильтрами для установки языкового параметра для каждого пользователя.

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. Например

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

Я хотел бы добавить следующее: если у вас есть дополнительные параметры, которые должны быть добавлены с помощью? 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
    }   
}

И настроить ресурсы.

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

И вы получите

/en/controller/action?offset=10

вместо

/controller/action?offset=10&lang=en
Другие вопросы по тегам