You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Paul Stanton <pa...@mapshed.com.au> on 2021/08/26 02:30:31 UTC

Render a single Enum value

Using ${object.enumValue} renders the enum in raw form ie ENUM1

How do I leverage "TapestryInternalUtils.getLabelForEnum" without having 
to use a BeanDisplay or Grid etc?

Or is there super easy way to just render the Enum value formatted 
without rendering any wrapping html etc?

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Render a single Enum value

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Hello!

Have you tried <t:propertyDisplay value="object.enumValue"/>? This
component is used by BeanDisplay and Grid for outputting property values,
using the contributed display blocks to the BeanBlockSource, and uses
TapestryInternalUtils.getLabelForEnum(Messages, Enum).

On Wed, Aug 25, 2021 at 11:31 PM Paul Stanton <pa...@mapshed.com.au> wrote:

> Using ${object.enumValue} renders the enum in raw form ie ENUM1
>
> How do I leverage "TapestryInternalUtils.getLabelForEnum" without having
> to use a BeanDisplay or Grid etc?
>
> Or is there super easy way to just render the Enum value formatted
> without rendering any wrapping html etc?
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

-- 
Thiago

Re: Render a single Enum value

Posted by Dmitry Gusev <dm...@gmail.com>.
You could build a custom component, e.g.:

public class OutputEnum
{
    @Inject
    private Messages messages;

    @Parameter(required = true)
    private Enum<?> value;

    @BeginRender
    void begin(MarkupWriter writer)
    {
        if (value == null)
        {
            return;
        }

        Element element = writer.element("span");

        element.text(getLabelForEnum(messages, value));

        writer.end(); // span
    }
}


On Thu, Aug 26, 2021 at 3:31 AM Paul Stanton <pa...@mapshed.com.au> wrote:

> Using ${object.enumValue} renders the enum in raw form ie ENUM1
>
> How do I leverage "TapestryInternalUtils.getLabelForEnum" without having
> to use a BeanDisplay or Grid etc?
>
> Or is there super easy way to just render the Enum value formatted
> without rendering any wrapping html etc?
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

-- 
Dmitry Gusev

AnjLab Team
http://anjlab.com

Re: Render a single Enum value

Posted by Nathan Quirynen <na...@pensionarchitects.be>.
If you want a reusable solution, you could contribute your own custom 
binding prefix, so you can use the following in your .tml files:

${enum:object.enumValue}


And then in your .properties message files:

EnumName.ENUM=Enum message

----

1. Extend the AbstractBinding class: (maybe it can also be done by using 
the TapestryInternalUtils method you mentioned instead of our 
implementation here)


public class EnumBinding extends AbstractBinding {

     private final Messages messages;
     private final Binding valueBinding;
     private final TypeCoercer coercer;

     public EnumBinding(Messages messages, Binding valueBinding, 
TypeCoercer coercer) {
         this.messages = messages;
         this.valueBinding = valueBinding;
         this.coercer = coercer;
     }

     @Override
     public Object get() {
         Object rawValue = valueBinding.get();
         if (rawValue instanceof Enum<?>) {
             Enum<?> value = (Enum<?>)rawValue;
             String simpleName = value.getDeclaringClass().getSimpleName();
             return messages.get(simpleName + "." + 
coercer.coerce(value, String.class));
         } else {
             String simpleName = rawValue.getClass().getSimpleName();
             return messages.get(simpleName + "." + 
coercer.coerce(rawValue, String.class));
         }
     }

     @Override
     public boolean isInvariant() {
         return valueBinding.isInvariant();
     }

     @Override
     public Class<?> getBindingType() {
         return String.class;
     }
}
----

2. Create a BindingFactory implementation:


public class EnumBindingFactory implements BindingFactory {

     private final BindingSource bindingSource;
     private final TypeCoercer coercer;

     public EnumBindingFactory(BindingSource bindingSource, TypeCoercer 
typeCoercer) {
         this.bindingSource = bindingSource;
         this.coercer = typeCoercer;
     }

     @Override
     public Binding newBinding(
             String description,
             ComponentResources container,
             ComponentResources component,
             String expression,
             Location location) {

         Binding valueBinding = bindingSource.newBinding(
                 description, container, component, 
BindingConstants.PROP, expression, location);

         return new EnumBinding(container.getMessages(), valueBinding, 
coercer);
     }
}

----

3. Bind the factory service and contribute the new binding in your 
AppModule class like following:


public static void bind(ServiceBinder binder) {
         binder.bind(BindingFactory.class, 
EnumBindingFactory.class).withId("EnumBindingFactory");
}

public static void contributeBindingSource(
             MappedConfiguration<String, BindingFactory> configuration,
             @InjectService("EnumBindingFactory") BindingFactory 
enumBindingFactory) {

         configuration.add("enum", enumBindingFactory);
}

Op 26/08/2021 om 04:30 schreef Paul Stanton:
> Using ${object.enumValue} renders the enum in raw form ie ENUM1
>
> How do I leverage "TapestryInternalUtils.getLabelForEnum" without 
> having to use a BeanDisplay or Grid etc?
>
> Or is there super easy way to just render the Enum value formatted 
> without rendering any wrapping html etc?
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Render a single Enum value

Posted by Nathan Quirynen <na...@pensionarchitects.be>.
Or if you want a more global easy to use solution, you could contribute 
your own custom binding prefix, so you can use the following in your 
.tml files:

${enum:object.enumValue}


And then in your .properties message files:

EnumName.ENUM=Enum message

----

1. Extend the AbstractBinding class: (maybe it can also be done by using 
the TapestryInternalUtils method you mentioned instead of our 
implementation here)


public class EnumBinding extends AbstractBinding {

     private final Messages messages;
     private final Binding valueBinding;
     private final TypeCoercer coercer;

     public EnumBinding(Messages messages, Binding valueBinding, 
TypeCoercer coercer) {
         this.messages = messages;
         this.valueBinding = valueBinding;
         this.coercer = coercer;
     }

     @Override
     public Object get() {
         Object rawValue = valueBinding.get();
         if (rawValue instanceof Enum<?>) {
             Enum<?> value = (Enum<?>)rawValue;
             String simpleName = value.getDeclaringClass().getSimpleName();
             return messages.get(simpleName + "." + 
coercer.coerce(value, String.class));
         } else {
             String simpleName = rawValue.getClass().getSimpleName();
             return messages.get(simpleName + "." + 
coercer.coerce(rawValue, String.class));
         }
     }

     @Override
     public boolean isInvariant() {
         return valueBinding.isInvariant();
     }

     @Override
     public Class<?> getBindingType() {
         return String.class;
     }
}
----

2. Create a BindingFactory implementation:


public class EnumBindingFactory implements BindingFactory {

     private final BindingSource bindingSource;
     private final TypeCoercer coercer;

     public EnumBindingFactory(BindingSource bindingSource, TypeCoercer 
typeCoercer) {
         this.bindingSource = bindingSource;
         this.coercer = typeCoercer;
     }

     @Override
     public Binding newBinding(
             String description,
             ComponentResources container,
             ComponentResources component,
             String expression,
             Location location) {

         Binding valueBinding = bindingSource.newBinding(
                 description, container, component, 
BindingConstants.PROP, expression, location);

         return new EnumBinding(container.getMessages(), valueBinding, 
coercer);
     }
}

----

3. Bind the factory service and contribute the new binding in your 
AppModule class like following:


public static void bind(ServiceBinder binder) {
         binder.bind(BindingFactory.class, 
EnumBindingFactory.class).withId("EnumBindingFactory");
}

public static void contributeBindingSource(
             MappedConfiguration<String, BindingFactory> configuration,
             @InjectService("EnumBindingFactory") BindingFactory 
enumBindingFactory) {

         configuration.add("enum", enumBindingFactory);
}


Op 26/08/2021 om 07:32 schreef Volker Lamp:
>> Using ${object.enumValue} renders the enum in raw form ie ENUM1
>>
>> How do I leverage "TapestryInternalUtils.getLabelForEnum" without having to use a BeanDisplay or Grid etc?
>>
>> Or is there super easy way to just render the Enum value formatted without rendering any wrapping html etc?
> You could inject the Locale as well as the Messages services into the page and use the latter in a property method to return a localized string.
>
> Also, check out the Adding new property editors section in the BeanEditForm guide (https://tapestry.apache.org/beaneditform-guide.html) It may look clumsy initially but it‘s quite beautiful when a bean needs to appear on different pages across your app (which is likely to be the case).
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Render a single Enum value

Posted by Volker Lamp <vo...@gmail.com>.
> Using ${object.enumValue} renders the enum in raw form ie ENUM1
> 
> How do I leverage "TapestryInternalUtils.getLabelForEnum" without having to use a BeanDisplay or Grid etc?
> 
> Or is there super easy way to just render the Enum value formatted without rendering any wrapping html etc?

You could inject the Locale as well as the Messages services into the page and use the latter in a property method to return a localized string.

Also, check out the Adding new property editors section in the BeanEditForm guide (https://tapestry.apache.org/beaneditform-guide.html) It may look clumsy initially but it‘s quite beautiful when a bean needs to appear on different pages across your app (which is likely to be the case).