2011-12-30 26 views
20

Tôi đã tạo bộ điều khiển này, bộ điều khiển này sẽ được sử dụng để gửi email. Tôi cần truy cập i18n để gửi email được bản địa hóa.Grails: Cách truy cập i18n từ bộ điều khiển hoặc dịch vụ?

class MailController { 

    MessageSource messageSource 

    static transactional = false 

    public void sendEmail() { 
     String name = "some name..." 
     String subject = message(code:"somemessagekey", args:[name]) 
     // do some fancy stuff here... 
    } 
} 

Có file i18n sau đó (nằm trong thư mục i18n):

file name: messages.properties 
content: somemessagekey = Blabla {0} - blablabla 

Sau khi tôi chạy này, nó ném (trong một thử nghiệm tích hợp):

groovy.lang.MissingPropertyException: No such property: messageSource for class: org.codehaus.groovy.grails.support.MockApplicationContext 

Tôi trong số các ý tưởng làm thế nào để xử lý nội địa hoá trong bộ điều khiển (tôi cũng đã thử nó trong một dịch vụ, nhưng điều đó thậm chí còn phức tạp hơn).

+0

bạn không cần phải gọi g.message()? –

+0

Tại sao tôi nên làm như vậy? Tôi đã không tìm thấy thông tin nào về "g". –

Trả lời

22

Nếu bạn đang sử dụng grails 1.3.7, bạn cần khai báo nguồn tin như:

def messageSource 

Bằng cách này nó sẽ được tiêm vào điều khiển của bạn. Tôi nghĩ rằng trong 2.0 bạn có thể làm điều đó theo cách bạn đăng, nhưng nó thậm chí như vậy, tôi nghĩ rằng nó là giá trị một cố gắng tuyên bố nó như đã nêu ở trên.

+3

Vâng, điều đó đã giúp, cảm ơn. Mã làm việc là: 'def messageSource public void sendEmail() { String subject = message (mã:" somemessagekey ", args: [name]) ...' –

5

Trong Grails 2.2.3 cần làm việc:

import org.springframework.context.MessageSource 
... 
def MessageSource messageSource 
... 
String subject = messageSource.getMessage("somemessagekey", [name], null) 
... 

link tham khảo và khả năng thêm ở đây: http://static.springsource.org/spring/docs/2.0.8/api/org/springframework/context/MessageSource.html

+3

không nên xóa MessageSource messageSource là MessageSource messageSource hoặc def messageSource? tuyên bố def và lớp là thừa. –

13

Tôi biết có một câu trả lời, nhưng đây là quan điểm của tôi vào nó. Tôi đã thực hiện một dịch vụ (lấy cảm hứng từ những người khác)

import org.springframework.web.servlet.i18n.SessionLocaleResolver 
import org.springframework.context.MessageSource 

class I18nService { 

    boolean transactional = false 

    SessionLocaleResolver localeResolver 
    MessageSource messageSource 

    /** 
    * 
    * @param msgKey 
    * @param defaultMessage default message to use if none is defined in the message source 
    * @param objs objects for use in the message 
    * @return 
    */ 
    def msg(String msgKey, String defaultMessage = null, List objs = null) { 

     def msg = messageSource.getMessage(msgKey,objs?.toArray(),defaultMessage,localeResolver.defaultLocale) 

     if (msg == null || msg == defaultMessage) { 
      log.warn("No i18n messages specified for msgKey: ${msgKey}") 
      msg = defaultMessage 
     } 

     return msg 
    } 

    /** 
    * Method to look like g.message 
    * @param args 
    * @return 
    */ 
    def message(Map args) { 
     return msg(args.code, args.default, args.attrs) 
    } 
} 

Bây giờ, trong một dịch vụ chỉ cần tiêm i18nService và bạn tốt để đi! Điều này cũng làm cho việc kiểm tra đơn vị dịch vụ khác dễ dàng hơn khi bạn có thể giả lập i18nService

Như một phần thưởng, dịch vụ sẽ tìm cách tìm kiếm miền địa phương hiện tại cho yêu cầu web hiện tại, thực hiện dịch vụ đó trong ngữ cảnh yêu cầu web.

4

Trả lời ở trên không giúp tôi. Tôi đang sử dụng Grails 3.0.1 và giải pháp dưới đây hữu ích cho tôi

import org.springframework.context.i18n.LocaleContextHolder as LCH 
import grails.util.Holders; 

class MyService{ 

def messageSource = Holders.getGrailsApplication().getParentContext(); 

public String MyMethod() 
{ 
    String message = messageSource.getMessage("code",args,LCH.getLocale()); 
} 

} 
+0

Nếu bạn cần gọi phương thức của bộ điều khiển từ một thông báo bộ điều khiển khác, nguồn sẽ bị vô hiệu. (Ít nhất là cho tôi). Vì vậy, nó có thể là thú vị thiết lập nó một mình. –

1

Cách chính thức thực sự khá dễ dàng. The official documentation tiểu bang sau đây:

Nó đơn giản để đọc tin nhắn trong một bộ điều khiển vì bạn có thể gọi thẻ như các phương pháp:

def show() { 
    def msg = message(code: "my.localized.content", args: ['Juan', 'lunes']) 
} 

Kỹ thuật tương tự có thể được sử dụng trong tag libraries, nhưng nếu thẻ thư viện của bạn sử dụng tùy chỉnh namespace thì bạn phải đặt trước cuộc gọi với g.:

def myTag = { attrs, body -> 
    def msg = g.message(code: "my.localized.content", args: ['Juan', 'lunes']) 
} 

Ngoài ra, xin lưu ý để không cung cấp args khi dịch của bạn không sử dụng đối số:

def msg = message(code: "my.localized.content") 
+0

Câu trả lời này chỉ hợp lệ cho bộ điều khiển. Nó không hoạt động theo cách đó trong các dịch vụ. – deflomu

1

Tôi đang sử dụng grails 3.x.Tiêm messageSource

org.springframework.context.MessageSource

và sử dụng

String getMessage(String code, Object[] args, String defaultMessage, Locale locale); 

method.Modify mã của bạn này để

class MailController { 

    MessageSource messageSource 

    static transactional = false 

    public void sendEmail() { 
     String name = "some name..." 
     String subject = messageSource.getMessage('somemessagekey', [name], '', null) 
     // do some fancy stuff here... 
    } 
} 
Các vấn đề liên quan