How to internationalize a message in grails with a hashmap (key:value) - grails

I need to translate a message key using a Hashmap using the Grails standard internationalization method.
I receive an Enum and a map with the binding, which are going to be replaced in the text.
The Enum indicates, which key is going to be recovered. The bindings have the values to replace on the translation.
messageSource.getMessage("mail.layout.subject.${templateName}",ARGS,"",locale)
The problem is that I need to pass the map to the args like an array, not like a map, but I don't know the order of the args.
My question is, if there are any ways to create a tranlation key like:
mail.layout.subject.ENUM1=Blablabl {name} bablablabl {age}
Instead of
mail.layout.subject.ENUM1=Blablabl {0} bablablabl {1}

Finally I did it with brute force. May be is not the best answer but I coudln't find any one better.
Basically I get the translation with te message resources and then I work with it finding my custom expresions.
def messageSource = grailsApplication.getMainContext().getBean('messageSource')
def subject = messageSource.getMessage("mail.layout.subject.NOTIFICATION",null,"",locale)
An example of subject resource
mail.layout.subject.NOTIFICATION=The user {friend.name} is friend of {user}
An example bindings:
def bindings = [friend:[name:"Jhon",surname:"Smith"],user:"David"]
With this senteces I replace my expresions with the value of the bindings
Pattern pattern = Pattern.compile("\\{[^}]+\\}")
def res = subject.replaceAll(pattern,{
def expresion = it[1..it.size()-2] // removes brackets
def fields = expresion.split("\\.");
def res = bindings
fields.each{
println(it)
res = res."${it}"
}
return res
})
After the proces the subject becomes like: "The user Jhon is friend of David"
The example use a HashMap of HashMaps, but it also works with object because grails/groovy handles the object like HashMaps and viceversa

This is much cleaner. :)
import groovy.text.SimpleTemplateEngine
def text = 'Dear "$firstname $lastname",So nice to meet you in ${city.name}.See you in ${month},${signed}'
def binding = ["firstname":"Sam", "lastname":"Pullara", "city":["name":"San Francisco", "id":"28"], "month":"December", "signed":"Groovy-Dev"]
def engine = new SimpleTemplateEngine()
template = engine.createTemplate(text).make(binding)

Related

Is there a way to replace mapping values with another variables value in jenkins pipeline

I have following mapping defined
def e_environments = [["demo1#mystuff.com":"file1"], ["demo2#mystuff.com":"file1"], ["insurance1#mystuff.com":"file2"], ["insurance2#mystuff.com":"file2"]]
Is there a way to replace URL's with same file name from a variable value. For example
def demo_env = ["demo1#mystuff.com","demo2#mystuff.com"]
def insurance_env= ["insurance1#mystuff.com","insurance2#mystuff.com"]
def def e_environments = [[${demo_env}:"file1"], [${insurance_env}:"file2"]]
I hope you must have made some efforts from your side before asking here.
Here is something for you to work upon,
def e_environments = [ "demo1#mystuff.com":"file1", "demo2#mystuff.com":"file1" , "insurance1#mystuff.com":"file2" ,"insurance2#mystuff.com":"file2" ]
def temp = []
e_environments.keySet().each{
temp.add(e_environments[it])
}
temp.unique().each{ val ->
println e_environments.findAll{it.value==val}
}
Got all keys from Map
Created a unique list of it
And a little bit of groovy magic for you to fix and figure it out.

Django admin custom search on custom column

Question:
How can I add the ability to search for items in my custom column Help Text?
FooAdmin View
Code:
Here is a simplified version of the code that I am working with:
models.py (yes this is how the models need to be set up)
class HelpText(models.Model):
help_text = models.CharField(max_length=1000)
def __str__(self):
return self.help_text
class Foo(models.Model):
job_name = models.CharField(max_length=200, blank=False, null=False)
env = models.CharField(max_length=200, blank=False, null=False)
def __str__(self):
return self.job_name
class FooHelpText(models.Model):
foo = models.OneToOneField(Foo, on_delete=models.DO_NOTHING)
help_text = models.ForeignKey(HelpText, on_delete=models.DO_NOTHING)
def __str__(self):
return str(self.help_text)
admin.py
class FooHelpTextInline(admin.TabularInline):
model = models.FooHelpText
#admin.register(models.Foo)
class FooAdmin(admin.ModelAdmin):
search_fields = ['env', 'job_name',]
list_display = ['pk', 'job_name', 'env', '_get_help_text', ]
inlines = [FooHelpTextInline]
def _get_help_text(self, obj):
return obj.foohelptext.help_text
Current behavior:
The current code above allows me to see the associated help_text in a column on FooAdmin. However, I am not able to search by anything in that column.
Not the answer I am looking for:
I know if it was the other way around where the help_text was a ForeignKey on Foo I could do something like foo__help_text, but that is not how my models are set up (and can not change).
Desired behavior:
Use the search box to search for help text (not just env and job_name).
Possible Solution (that I need help with):
I suspect that get_search_results might be what I need, but I don't understand how to implement it for my use case.
UPDATE:
The closest I can get is searching for a number(aka a specific PK that I know exists) and getting that search result. But the query doesn't really make sense. And obviously that is not the desired functionality of a search.
def get_search_results(self, request, queryset, search_term):
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
try:
search_term_as_int = int(search_term)
except ValueError:
pass
else:
queryset |= models.Foo.objects.select_related(
'foohelptext').filter(fooshelptext=search_term_as_int)
return queryset, use_distinct
I just don't understand the Python |= (bitwise OR operator) and why it has to be an integer.
Much easier than I thought. No need for get_search_results.
Simply needed to add it as foohelptext__help_text__help_text as an other item in the search fields.

How Can I Use Config Entries with Dots When Parsing with XmlSlurper

I'm trying to use a groovy Config entry to parse an xml file with XmlSlurper.
Here's the Config file:
sample {
xml {
frompath = "Email.From"
}
}
Here's the XML
<xml>
<Email>
<From>
<Address>foo#bar.com</Address>
<Alias>Foo Bar</Alias>
</From>
<Email>
</xml>
This is what I tried initially:
XmlSlurper slurper = new XmlSlurper()
def record = slurper.parseText((new File("myfile.xml")).text)
def emailFrom = record?."${grailsApplication.config.sample.xml.frompath}".Address.text()
This doesn't work because XmlSlurper allows one to use special characters in path names as long as they're surrounded by quotes, so the app is translating this as:
def emailFrom = record?."Email.From".Address.text()
and not
def emailFrom = record?.Email.From.Address.text()
I tried setting the frompath property to be "Email"."From" and then '"Email"."From"'. I tried tokenizing the property in the middle of the parse statement (don't ask.)
Can someone please point me towards some resources to find out if/how I can do this?
I feel like this issue getting dynamic Config parameter in Grails taglib and this https://softnoise.wordpress.com/2013/07/29/grails-injecting-config-parameters/ may have whispers of a solution, but I need fresh eyes to see it.
The solution in issue getting dynamic Config parameter in Grails taglib is a proper way to deref down such a path. E.g.
def emailFrom = 'Email.From'.tokenize('.').inject(record){ r,it -> r."$it" }
def emailFromAddress = emailFrom.Address.text()
If your path there can get complex and you rather go with the potentially more dangerous way, you could also use Eval. E.g.
def path = "a[0].b.c"
def map = [a:[[b:[c:666]]]] // dummy map, same as xmlslurper
assert Eval.x(map, "x.$path") == 666

how to change "xxx object" in django admin result list

Please take a look at this picture:
I am trying to change "business object" text to it's instance name. I wonder if there is an easy way to do that without dealing with django's core code.
This is the model I'm using:
class Business(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
description = models.TextField(blank=True)
industry = models.ManyToManyField(Industry)
class Meta:
verbose_name = 'Business'
verbose_name_plural = 'Businesses'
def __unicode__(self):
return "%s: %s" % (self.id, self.name)
Call the method __str__ instead of __unicode__. See https://docs.djangoproject.com/en/dev/intro/tutorial02/#playing-with-the-api and look for the info box called "__str__ or __unicode__?".
I had the same problem here. As Brenda J. Butler indicated (the link), it looks like if you are using Python 3.x you should define str() instead of unicode.

Default django-admin list filter

My question is just an extension of this thread [Question]http://stackoverflow.com/questions/851636/default-filter-in-django-admin .
from myproject.myapp.mymodels import fieldC
class Poll(models.Model):
fieldA = models.CharField(max_length=80, choices=CHOICES.MyCHOICES)
fieldB = models.ForeignKey(fieldC)
admin.py
list_display = ('fieldB__fieldc1')
Now my list filter shows four criteria All, A ,B ,C .
What I want is if the superuser is logged in ,the filter should show all four criteria All,A,B,C and if the user is other than superuser filter should only show All, A, B.
How can i acheive this ?
Here is my actual piece of admin.py
def changelist_view(self, request, extra_context=None):
referer = request.META.get('HTTP_REFERER', '')
test = referer.split(request.META['PATH_INFO'])
if test[-1] and not test[-1].startswith('?'):
if not request.GET.has_key('patient__patient_type__exact'):
q = request.GET.copy()
q['patient__patient_type__exact'] = 'Real'
request.GET = q
request.META['QUERY_STRING'] = request.GET.urlencode()
if not request.user.is_superuser:
q['patient__patient_type__exact'] = 'Real'
return super(VisitAdmin, self).changelist_view(request, extra_context)
Thanks in advance
I think the new FilterSpec API in Django 1.4 gives you exactly what you need here. Check out the docs on list_filter. In 1.4 you can now make custom list filters that subclass django.contrib.admin.SimpleListFilter and give you the power to write custom lookup and queryset code, and since the request is passed in you can do a simple conditional with is_superuser.
if request.user.is_superuser:
# pass one set of lookups
else:
# pass a different set
read the example code in the docs carefully and I think it will all be clear.

Resources