# message

## Purpose

Resolves a message from the given code or error. Normally used in conjunction with eachError. O

## Examples

Loop through each error and output the message:

    <g:eachError bean="${book}">
        <li><g:message error="${it}" /></li>
    </g:eachError>

> Note that this is typically used for built-in Grails messages, rather than user application messages. For user application messages, use the code or message parameters, as illustrated below.

Output a message for a specific known code:

    <g:message code="my.message.code" />

Output a message for a compatible object.

    <g:message message="${myObj}" />

> Note that objects passed to the message parameter must implement the org.springframework.context.MessageSourceResolvable interface.

## Description

Attributes

- `error` (optional) - The error to resolve the message for. Used for built-in Grails messages.
- `code` (optional) - The code to resolve the message for. Used for custom application messages.
- `message` (optional) - The object to resolve the message for. Objects must implement org.springframework.context.MessageSourceResolvable.
- `default` (optional) - The default message to output if the error or code cannot be found in messages.properties.
- `args` (optional) - A list of argument values to apply to the message, when code is used.
- `encodeAs` (optional - 0.6+) - The name of a codec to apply, i.e. HTML, JavaScript, URL etc

One of either the `error` attribute, the `code` attribute or the `message` attribute is required. Messages are resolved from the `grails-app/i18n/messages.properties` bundle. See also Internationalization.

For a more complex example, to output your own message with parameters and a default message, you might use the following code from your controller:

    flash.message = "book.delete.message"
    flash.args = [ "The Stand" ]
    flash.default = "book deleted"

You would then specify the following in messages.properties:

    book.delete.message="Book {0} deleted."

and specify the following from your view:

    <g:message code="${flash.message}" args="${flash.args}" default="${flash.default}"/>

Which would result in the output "Book The Stand deleted." If you had misnamed the message or not specified it in `messages.properties`, your default message of "book deleted" would be output.

## Source

Show Source

    def message = { attrs ->
            messageImpl(attrs)
        }    def messageImpl(attrs) {
            def messageSource = grailsAttributes.applicationContext.messageSource
            def locale = attrs.locale ?: RCU.getLocale(request)        def text
            def error = attrs.error ?: attrs.message
            if (error) {
                try {
                    text = messageSource.getMessage(error , locale)
                }
                catch (NoSuchMessageException e) {
                    if (error instanceof MessageSourceResolvable) {
                        text = error?.code
                    }
                    else {
                        text = error?.toString()
                    }
                }
            }
            else if (attrs.code) {
                def code = attrs.code
                def args = attrs.args
                def defaultMessage
    			if(attrs.containsKey('default')) {
    				defaultMessage = attrs['default']
    			} else {
    				defaultMessage = code
    			}            def message = messageSource.getMessage(code, args == null ? null : args.toArray(),
                    defaultMessage, locale)
                if (message != null) {
                    text = message
                }
                else {
                    text = defaultMessage
                }
            }
            if (text) {
                return attrs.encodeAs ? text."encodeAs${attrs.encodeAs}"() : text
            }
            ''
        }    // Maps out how Grails contraints map to Apache commons validators
        static CONSTRAINT_TYPE_MAP = [email : 'email',
                                      creditCard : 'creditCard',
                                      matches : 'mask',
                                      blank: 'required',
                                      nullable: 'required',
                                      maxSize: 'maxLength',
                                      minSize: 'minLength',
                                      range: 'intRange',
                                      size: 'intRange',
                                      length: 'maxLength,minLength']