Use one Message as argument in other Spring Messages (properties file) - spring

I have a need to do something like this:
bob.common=goat
bob.have=I have a {bob.common}!
bob.want=I want a {bob.common}!
bob.need=I need a {bob.common}!
Is this sort of thing possible? I know this seems silly, but being able to re-use a common piece is a need here, and we really can't (don't want to) do it programmatically.
We're already using numbered arguments in our properties, but we would like to be able to pass in a reference to another property.

I suggest to do this :
bob.common=goat
bob.have=I have a {0}!
bob.want=I want a {0}!
bob.need=I need a {0}!
Then in your page :
<spring:message code="bob.common" var="animal"/>
<spring:message code="bob.have" arguments="${animal}"/>
<spring:message code="bob.want" arguments="${animal}"/>
<spring:message code="bob.need" arguments="${animal}"/>
The way you want to do would be too strict, if you want to change your animal for example.

According to the Spring changelog, this has been supported since 2.5.3:
PropertyPlaceholderConfigurer supports nested keys in placeholder keys as well (e.g. "${db.${environment}}")
So for your example case, you should be able to use:
bob.have=I have a ${bob.common}!
and the PropertyPlaceholderConfigurer should recognise the "nested key" and resolve that correctly.

Related

In Spring boot, I'm trying to create another .property file that functions like messages.property, Is that possible?

So I'm trying to create another .property file (called labels.properties) that i can use in Thymeleaf like this:
<div th:text=#{property.from.labels}></div>
Right now I just add labels.properties in the root of resource folder, for now its not working. The purpose of this is I want to separate the property file that handles the error messages from texts for labels & buttons.
Is that possible?
if yes, how to do it?
if yes again, can I do internationalization like adding labels_ja.properties (Japanese)?
You can customize the naming (and location) of the message bundles by configuring the spring.messages.basename property. For example:
spring.messages.basename=labels
By doing so, Spring will look for messages within classpath:labels.properties and classpath:labels_{locale}.properties, such as classpath:labels_ja.properties.
If you want to use this in addition to the regular messages.properties, you can use a comma separated value:
spring.messages.basename=messages,labels
The first one within that comma separated list will take priority over the other ones. If you have a property.from.labels in both messages.properties and labels.properties, the one within messages.properties would be chosen in this example.
This can also be found within the documentation about internationalization.

ftl #spring.message - handle NoSuchMessageException

I have the .ftl page where i put values from locale property files like so :
<div id="hiddenDiv">
<#spring.message "${MyKey}.Popup"/>
</div>
The problem is that in some property files, i have the key MyKeyValue.Popup, but in others i don't. (namely the en.properties file)
And when spring tries to generate the model in english, it doesn't find that key in en.properties file.
Is there a way to handle that exception ? I have to handle it. I can't just put all of the possible keys into that property file. There are too many of them.
Please help.
The solution is to use this macro instead of the #spring.message :
<#spring.messageText "code", "Default message"/>
This doesn't throw an exception because it has a default value.
Hope this helps someone.

JSTL getting value in EL from another EL value

In my JSP page, I am iterating over a list of objects using the c:forEach tag. Each object in this iteration has a name field, and I am trying to use that name field to reference other objects that I have added to my Spring model. However, when I do this, I am getting an exception saying the property of the second object cannot be found on a String. Let me illustrate with a simplified example.
<c:forEach items="${companyList}" var="company" varStatus="num">
<c:set var="monthStats" value="${company.name}_month" />
<tr>
<td>Properties This Month</td>
<td>${monthStats.properties}</td>
</tr>
....
</c:forEach>
All of the objects are located inside a Spring Model object and have been set like this
model.addAttribute(company.getName() +"_month", currentMonthStats);
I have also tried throwing out the <c:set tag and trying
${(company.name + "_month").properties}
as well as
${${company.name + "_month"}.properties}.
Those havent worked either. Also, I wasn't quite sure how to word my title, so if it could worded better let me know so that other people can find this if they have the same issue.
You're basically asking for double-evaluation, and it doesn't work like that.
I'd modify the data delivered to the view layer to be something a little less odd, so you can access it in a non-pathological manner, like by putting the month stats into a map accessed by the company name (or id), or directly associated them in a DTO, etc.

Is it possible to pass argument from visualforce apex tag?

I have a function searchWorkByName that takes "key" as an argument and use SQOL to retrieve the data.
In visualforce side, I have a link that calls searchWorkByName but would like to be able to pass argument such as character 'a'
example, (this throws an error)
<apex:commandLink value="search!" action="{!searchWorkByName('aaa')}" />
Is it possible to do so if not what is the alternatives?
apex class
public class SearchWorkTest {
public PageReference searchWorkByName(String key) {
//find record of work names starting from provided key character
workNames = [select name from work__c where work__c.name like 'key%'];
return Page.searchResult;
}
}
visualforce
<apex:page standardController="work__c" extenstions="SearchWorkTest">
<!-- Is it possible to pass argument like 'foo' ? -->
<apex:commandLink value="search!" action="{!searchWorkByName}" />
</apex:page>
You can pass in parameters from a page into a function like this:
<apex:commandLink value="search!" action="{!searchWorkByName}">
<apex:param name="key" value="val"/>
</apex:commandLink>
Obviously, the value of the parameter in this case is fixed. If you want something dynamic (i.e. user types something and that is passed to the function), I'm not 100% sure how you'd do that, but I think it might be possible. However, the solution already posted skins the cat for you, but I thought I'd follow up with an alternative in case it's any use.
No, you cannot pass arguments to actions like that.
1 option is to make this variable a normal form field that user can type text/select from dropdown/whatever - if you'll use same name for a variable in Apex (and make it publicly visible by setters/getters), this will work without problems. Check out my answer at How do I integrate Salesforce with Google Maps? to get started.
Second option - if this search must be somehow done programatically without user having to click anything, if the data for example comes from page itself (i.e. is read in <apex:repeat> tag)... you could make a small helper page & controller and call them as components. There is no problem with passing data to components. Check documentation for <apex:component> and <apex:componentBody>. But I think first answer os most useful for you.
Good luck!

Duplicated Zend_Form Element ID in a page with various forms

How do I tell the Zend_Form that I want an element (and it's ID-label, etc) to use another ID value instead of the element's name?
I have several forms in a page. Some of them have repeated names. So as Zend_Form creates elements' IDs using names I end up with multiple elements with the same ID, which makes my (X)HTML document invalid.
What is the best solution to fix this, given that I really have to stick with using the same element names (they are a hash common to all forms and using the Zend_Form Hash Element is really out of question)?
Zend_Form_Element has a method called setAttribs that takes an array. You may be able to do something like $element->setAttribs(array('id' => "some_id"));
or you can do $element->setAttrib('id', 'some_id');
Thanks, Chris Gutierrez.
However, as I said, I needed to get ride of the default decorator generated IDs like -label. Wiht the $element->setAttribs() it is not possible, however.
So based on http://framework.zend.com/issues/browse/ZF-7125 I just did the following:
$element->clearDecorators();
$element->setAttrib('id', 'some_id');
$element->addDecorator("ViewHelper");
Whoever sees this: please note this was enough for what I needed. But may not be for you (the default settings has more than the viewHelper decorator).

Resources