I want to make a translation my_translation with an optional parameter. For example:
> I18n.t('my_translation')
=> "This is my translation"
> I18n.t('my_translation', parameter: 1)
=> "This is my translation with an optional parameter which value is 1"
Is this possible?
Yes, definitely. You just write the translations like this:
my_translation: This is my translation with an optional parameter which value is %{parameter}
Is the parameter really optional? In above translation, you have to provide all parameters.
UPDATE: Sorry, I answered too soon. I don't think it's easy to do. Maybe the easiest way is like this:
> I18n.t('my_translation1')
=> "This is my translation"
> I18n.t('my_translation2', parameter: 1)
=> "This is my translation with an optional parameter which value is 1"
I would say it is possible, though not recommended. You have two completely separate strings, based on your comments in #Yanhao's answer, and I would say they should be two separate entries in your yaml file:
report_name: My report
report_name_with_date: My report on %{date}
Since the existence of the date determines which string to display, you could perhaps test for its existence in in the params hash in a controller method, assign the title to a variable, and then use it in a view. Perhaps something like:
report_date = params[:report_date]
if report_date && report_date.is_a?(Date)
#report_name = I18n.t('report_name_with_date', date: report_date.to_s)
else
#report_name = I18n.t('report_name')
end
If you want behaviour exactly as you have described, you'd need two yaml entries anyway, and you'd have extra convolution, and you'd be doing a I18n no-no by creating a string by concatenating two strings together, which assumes a fixed grammatical sentence structure (not to mention this drives translators up the wall):
report_name_with_date: My report%{on_date}
on_date: on %{date}
with code something like this:
report_date = params[:report_date]
if report_date && report_date.is_a?(Date)
on_date = I18n.t('on_date', date: report_date.to_s)
#report_name = I18n.t('report_name_with_date', on_date: " #{on_date}")
else
#report_name = I18n.t('report_name_with_date', on_date: nil)
end
So, in summary, I'd say go with two separate whole strings, like in the first example.
This is the way i did it!
First set my translation
I18n.t('my_translation', parameter: optional_parameter)
Check if value is nil
optional_parameter = value.nil? "" : "with an optional parameter which value is #{value}"
I18n.t('my_translation', parameter: optional_parameter)
if value is nil =>"This is my translation"
if value is 1 => "This is my translation with an optional parameter which value is 1"
If you're using a number as an optional argument, Rails provides a better way to handle it.
e.g.
invoice:
zero: "Great! You have no pending invoices."
one: "You have only 1 pending invoice."
other: "You have %{count} pending invoices."
>> t("invoice", count: 0)
=> Great! You have no pending invoices.
>> t("invoice", count: 1)
=> You have only 1 pending invoice.
>> t("invoice", count: 5)
=> You have 5 pending invoices.
Related
There are some variables that I just use without knowing what it does. Could someone explain the logic behind all these parsing in Yocto?
What does the underscore do? What are the available arguments other than _append_pn?
PACKAGECONFIG_append_pn-packagename = " packagename"
PREFERRED_VERSION_linux-imx_mx6 = "3.10.17"
SRC_URI_append_toolchain-clang = " file://0004-Remove-clang-unsupported-compiler-flags.patch "
EXTRA_OECONF_append_arm = " --enable-fpm=arm"
How about this one? I know that adding in this way is to single out a package, but how does it work?
LICENSE_FLAGS_WHITELIST_append = " commerical_packagename"
Someone also mentioned something weird with this that worked for them: bitbake: how to add package depending on MACHINE?
IMAGE_INSTALL_append_machine1 += " package1"
The documentation covers this pretty well: https://www.yoctoproject.org/docs/latest/bitbake-user-manual/bitbake-user-manual.html#basic-syntax
The longer version is that _ introduces an override, which is a way of saying "do something special" instead of just assigning.
Some are operations such as append and prepend.
FOO = "1"
FOO_append = "2"
FOO is now "12" as 2 was appended to 1.
(_prepend does what you'd expect)
_remove can be used to remove items from a whitespace-separated list.
FOO = "1 2 3"
FOO_remove = "2"
FOO is now "1 3".
pn_[foo] is an override for a specific recipe name (historical naming, it means package name, but actually refers to the recipe). So your local.conf can do:
EXTRA_OEMAKE_pn-foo = "bar"
And you've just set EXTRA_OEMAKE for the foo recipe, and just the foo recipe.
There are other overrides. The architectures all have overrides, so _arm _x86 _mips etc specify that an assignment is specific to those architectures.
I got a few string like so:
TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_light_87689uiyhk
AND
TFjyg9780878_867978-DGB097908-78679iuhi698_sky_light_87689uiyhk
AND
TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_dark_87689uiyhk
AND
TFjyg9780878_867978-DGB097908-78679iuhi698_sky_dark_87689uiyhk
I need to check whether the strings above has one of the widesky_light, sky_light, widesky_dark and sky_dark with exactitude so I wrote this:
if my_string.match("widesky_light")
...
end
For each variant, but the problem I'm having is because sky_light and widesky_light are similar, my code is not working properly. I believe the solution to the above would be a regex, but I've spend the afternoon yesterday trying to get it to work without much success.
Any suggestions?
EDIT
A caveat: in this string (as example): TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_light_87689uiyhk, the part after widesky_light, which is _87689uiyhk is optional, meaning that sometimes I have it, sometimes I don't, so a solution would not be able to count on _string_.
Looks like you just need to reorder your if statements
if my_string.match(/widesky_light/)
return 'something'
end
if my_string.match(/sky_light/)
return 'something'
end
Regex
1st regex : extract word for further checking
Here's a regex which only matches the interesting part :
(?<=_)[a-z_]+(?=(?:_|\b))
It means lowercase word with possible underscore inside, between 2 underscores or after 1 underscore and before a word boundary.
If you need some logic depending on the case (widesky, sky, light or dark), you could use this solution.
Here in action.
2nd regex : direct check if one of 4 words is present
If you just want to know if any of the 4 cases is present :
(?<=_)(?:wide)?sky_(?:dark|light)(?=(?:_|\b))
Here in action, with either _something_after or nothing.
Case statement
list = %w(
TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_light_87689uiyhk
TFjyg9780878_867978-DGB097908-78679iuhi698_sky_light_87689uiyhk
TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_dark_87689uiyhk
TFjyg9780878_867978-DGB097908-78679iuhi698_sky_dark_87689uiyhk
TFjyg9780878_867978-DGB097908-78679iuhi698_trash_dark_87689uiyhk
)
list.each do |string|
case string
when /widesky_light/ then puts "widesky light found!"
when /sky_light/ then puts "sky light found!"
when /widesky_dark/ then puts "widesky dark found!"
when /sky_dark/ then puts "sky dark found!"
else puts "Nothing found!"
end
end
In this order, the case statement should be fine. widesky_dark won't match twice, for example.
Maybe something like this:
case my_string
when /_(sky_light)/
# just sky_light
when /sky_light/
# widesky_light
when /_(sky_dark)/
# just sky_dark
when /sky_dark/
# widesky_dark
else
puts "I don't like"
end
I have a Ruby hash that has attributes like this:
{:type=>"article", :id=>"207", :infographic=>nil, :guest_post=>nil, :interview=>nil}
Suppose I want to check if this hash has a key that is the same as a variable "keyVar"
keyVar = ":type"
If I do hash.has_key?(keyVar), it returns false, but it obviously does have the key.
What am I doing wrong?
Your keyVar variable is a string, not a symbol. Worse yet, it's a string with a prefixed colon, so it's not easily possible to convert it to a symbol.
What you want is
hash.has_key?(:type)
But what you're doing is:
hash.has_key?(":type")
Simpy using ":type".to_sym would get you :":type". You'll need something like this:
hash.has_key?(keyVar.gsub(":", "").to_sym)
You are checking for the wrong key. Do this:
key_var = :type
hash.key?(key_var)
If you happened to have the wrong key:
key_var = ":type"
then, the way to convert that to the correct key is:
key_var.delete(":").to_sym
so
hash.has_key?(key_var.delete(":").to_sym)
will work. Using gsub as another answer suggests is meaningless as there is only one : in the string. sub is better, but why use it when you can use delete?
there are many ways to check
> hash = {:type=>"article",
:id=>"207",
:infographic=>nil,
:guest_post=>nil,
:interview=>nil}
> hash.keys.include?(:type)
> true
> hash.has_key?(:type)
> true
> hash.key?(:type)
> true
and more.... Just read documentation
This code from my developer below... does it expect something like "1 - January" and try to parse it into something else?
I changed the code on my form so now the value being passed to this controller is just "1" instead of "1 - January"
How can I fix this so I don't get the "can't convert nil into string" error?
def get_expiry_month_number(monty_det, expiry_year)
if MONTH_NAMES.include? monty_det
month_number = MONTH_NAMES.index(monty_det)
month_number = MONTH_NUMBERS[month_number]
expiry_year = month_number.to_s + expiry_year[expiry_year.length-3..expiry_year.length-1]
return expiry_year
end
end
In your example you are running into the problem that one of your strings in your calculation for year is nil. Most likely this one,
expiry_year[expiry_year.length-3..expiry_year.length-1]
You can try and fix this by calling to_s on the culprit variable, thus converting the nil into '' and then concatenated.
Like so: expiry_year = month_number.to_s + expiry_year[expiry_year.length-3..expiry_year.length-1].to_s
However, this may have other seen consequences and isn't recommended. A better approach would be to find out why something you expect is a string is turning out to be empty, and perhaps displaying an appropriate error.
Could you explain a little bit more about what the function is supposed to do? And perhaps the value of expiry_year and monty_det when the error occurs? puts statements can be a big help here.
I guess that get_expiry_month_number('january', 2011) would return: 1011.
Indeed:
month_number should return 1 for january
expiry_year[expiry_year.length-3..expiry_year.length-1] returns the 3 last characters of 2011 => 011
I could really use some help with the best way to accomplish the following:
I have the below in my controller (and I know this should not be here and needs to move to the model)
This is an email messaging system so according to what position you hold you are able to email out to set groups of people. So if you are Battalion Commander etc you can choose to message out to one of the 5 groups defined below. If you are a Company Commander your groups change. In the view there is a drop down menu and you choose the group your message goes out to. The select menu is populated depending on the position of the signed in user.
The problem seems that the "elsif" portion does not populate the message correctly. It shows the right drop down list and acts as if the email is sent but the emails are not being populated. However the first value (Battalion Commander) works fine.
Do I have something written incorrectly in the if else statement? It seems like it should be pretty simple. The user position always reflects correctly so that is not it.
if (#position == "Battalion Commander" or "Command Sergeant Major" or "FRSA" or "Battalion FRG Leader")
#bnok = (#user.battalion.primaries).collect(&:email).select{|s| !s.blank?}.join(", ")
#bspouses = (#user.battalion.primaries(:conditions => ["relationship = 'spouse'"])).collect(&:email).select{|s| !s.blank?}.join(", ")
#bsoldiers= (#user.battalion.soldiers).collect(&:email).select{|s| !s.blank?}.join(", ")
#bsoldierspouse=((#user.battalion.soldiers)+(#user.battalion.primaries(:conditions => ["relationship = 'spouse'"]))).collect(&:email).select{|s| !s.blank?}.join(", ")
#ballcontacts=((#user.battalion.soldiers)+(#user.battalion.primaries)+(#user.battalion.additionals)).collect(&:email).select{|s| !s.blank?}.join(", ")
elsif
#position == ("Company Commander" or "First Sergeant" or "FRG Leader")
#nok = (#user.company.primaries).collect(&:email).select{|s| !s.blank?}.join(", ")
#spouses = (#user.company.primaries(:conditions => ["relationship = 'spouse'"])).collect(&:email).select{|s| !s.blank?}.join(", ")
#soldiers= (#user.company.soldiers).collect(&:email).select{|s| !s.blank?}.join(", ")
#soldierspouse=((#user.company.soldiers)+(#user.company.primaries(:conditions => ["relationship = 'spouse'"]))).collect(&:email).select{|s| !s.blank?}.join(", ")
#allcontacts=((#user.company.soldiers)+(#user.company.primaries)+(#user.company.additionals)).collect(&:email).select{|s| !s.blank?}.join(", ")
end
So this does not work, it work for either one set of positions or the other but not both. This correlates to a select menu in the view and depending on what position you hold the query on certain groups of people change.
So in the view I have this:
<% if #position == "Battalion Commander" %>
<%= f.select(:bcc_email, [["Please Select", ""], ["Battalion NOK", #bnok], ["Battalion Spouses", #bspouses], ["Battalion Soldiers Only", #bsoldiers], ["Battalion Soldiers & Spouses", #bsoldierspouse], ["All Battalion Contacts", #ballcontacts]]) %></h1><br />
I am still learning rails and I am not sure if a case statement would be better but then I am confused on where that goes and how that case statement fits into the view.
Any guidance would be great, I am trying to chip away at this and figure it out, but I would really appreciate some help.
Firstly it may help if you can format that a bit clearer - for us and yourself, often simple formatting will help identify issues.
Secondly, what is your goal here? I gather it's some sort of war simulator or something? And assume you realise that in an if statement, only one of them will be executed:
if (xxx)
aaaaaaaaaaaaaaaaaa
elseif (yyyy)
bbbbbbbbbbbbbb
end
in the case that xxx is true, the aaaaaaaa will be executed, and then it'll jump to end. The bbbbbbbbb part will not be executed - even if true, because the first statement was. If however xxx is not true, yyyy will be evaluated, and if true, bbbbbbbbbbbbb will happen.
I hope that helps a bit?
disclaimer: I don't know ruby. I have been told it is similar to python and LISP in some regards, so this answer makes that assumption.
What I would do is maintain these condition variables in a dictionary (or map, or hash table, whatever your language calls it). The "rank" of the person would be a key, and the value would correspond to the function you want to execute for that rank. for instance,
#the following example is python-esque. you'll have to port it to ruby.
def some_funct1(): #pass parameters if you need to. i don't, here.
sql_stuff_here
def some_funct2():
sql_stuff_here
map['important dude'] = some_funct1;
map['another important dude'] = some_funct1;
map['unimportant dude'] = some_funct2;
map['another_unimportant dude'] = some_funct2;
#after some time, you have a person whose rank is rank.
map[rank]() #this will execute the function
You wrote
if (... a big test ...)
..do some work..
elsif
..do something else..
end
but that is wrong! You should just write else instead of elsif unless you need to check another condition.
[I assume elsif followed by nothing=nil is always false]