%s variable not working in Magento - magento

I always use %s variable as a placeholder when there is error or success such as this code:
Mage::getSingleton('customer/session')->addError(Mage::helper('module')
->__('Hi %s, there is an error', $name));
The problem is: sometimes it works, sometimes it doesn't. Surely the $name does contain a valid string value (I've var_dump it many times). Do you know why?

As others have noted, you're not limited to one argument in your translated string. Some examples:
One argument, in one place:
Mage::helper('module')->__('Hi %s, there is an error', $name);
Two arguments, in two places:
Mage::helper('module')->__('Hi %s, there is an error with code %s', $name, $code);
One argument, in two places:
Mage::helper('module')->__('Hi %1$s, there is an error. Your name is %1$s', $name);
Two arguments, swapping places:
// Template or block file
Mage::helper('module')->__('Hi %1$s %2$s, there is an error', $firstname, $lastname);
// CSV translation
"Hi %1$s %2$s, there is an error", "%2$s, %1$s received an error"
Documentation on the PHP function being used to power this can be found here: vsprintf
(PS: The double-quoting that knase is talking about only applies to your CSV file, where a double-quote is an escaped single quote.)

%s varible work in translate magento. You can write in .csv translate file such as in example:
"Hi %s, there is an error","An error is %s"
Or if you use "%s" for translate you must write double slashe twiсe for shield. Look example:
"Hi ""%s"", there is an error.","An error is ""%s""."
You write for this translate:
Mage::helper('module')->__('Hi "%s", there is an error', $name);

What version of Magento are you using? In current version of Magento, the variable replacement happens here
#File: app/code/core/Mage/Core/Model/Translate.php
...
//array_unshift($args, $translated);
//$result = #call_user_func_array('sprintf', $args);
$result = #vsprintf($translated, $args);
...
I imagine dropping some debugging statement in there could help lead to a better understanding of the problem.

Make sure in the csv file you use double quotes " instead of single quotes '.
Incorrect:
'Welcome %s', 'Hello %s'
Correct:
"Welcome %s", "Hello %s"

Wow, it seems if there is more than one %s, the translation won't work. So it must be only one %s for the translation to work properly.

Related

Can you fix my PHP If Statement, using a Href?

I am using an if statement and trying to get one of two statements to show, depending on the session running.
please help. thank you.
if (session_name== "admin"){
echo ("[Admin Logout]");
}else {
echo "[Member Logout]";
}
?>
Also there is 2 syntax errors on the echo parts.
You if you use double quotes around the argument to echo, you should use single quotes inside it for the HTML attribute, or vice versa (an alternative is to escape the inner quotes with backslash, but I never understand why people prefer this). And you need $ before the variable name.
if ($session_name== "admin"){
echo ("<a href='admin/logout.php'>[Admin Logout]</a>");
}else {
echo "<a href='logout.php'>[Member Logout]</a>";
}

How to use codeigniter form validation library for two different languages at the same time?

I'm trying to use codeigniter form validation library for showing two different lines in two different languages at the same time but it throws an error:
$this -> form_validation -> set_message('required', 'Warning %s should not be empty! <br /> Dikkat %s alanı boş bırakılmamalıdır.');
Is there a way to using that function like this without facing that error:
A PHP Error was encountered
Severity: Warning
Message: sprintf(): Too few arguments
Filename: libraries/Form_validation.php
Line Number: 525
The sprintf() function on line 525 in core/libraries/form_validation.php only has two arguments.
$message = sprintf($line, $this->_translate_fieldname($row['label']));
The first argument must be a string with designated insertion points. The following arguments (in a sprintf function) will have to match the number of insertion points. And codeigniter only uses one.
From the Codeigniter Userguide: http://ellislab.com/codeigniter/user_guide/libraries/form_validation.html
If you include %s in your error string, it will be replaced with the "human" name you used for your field when you set your rules.
But, the solution for your problem is this:
$this->form_validation->set_message('required', 'Warning %1$s should not be empty! <br /> Dikkat %1$s alanı boş bırakılmamalıdır.');
%1$s represents the first argument after the string argument in sprintf(). It is explained very well in the examples here: http://dk1.php.net/sprintf

How to show in CodeIgniter only the second parameter in form validation message?

E.g. I have this line in my language form_validation file:
$lang['min_length'] = "%s must be at least %s characters in length.";
And I want the output to be like this:
$lang['min_length'] = "This field must be at least %s characters in length.";
However, the problem is that it looks like this when echoed:
This field must be at least Your name characters in length.
which is wrong because it takes the first %s instead of the second %s.
How can I force CI to take the second %s? Is it possible?
Since the min_length is a standard function in the Form Validation Library and treated through this library, you can only do so by changing the core library.
But there is an easier way - using a callback function with the Form Validation Library:
$this->form_validation->set_rules('your_field', 'The Field label', 'callback_my_min_length[10]');
Then within your controller, add this:
public function username_check($str, $min_length)
{
if ( mb_strlen($str) >= $min_length)
{
return TRUE;
}
else
{
$this->form_validation->set_message('my_min_length', 'This field must be at least '.$min_length.' characters in length.');
return FALSE;
}
}
This is how I would do it.

Rails String Interpolation in a string from a database

So here is my problem.
I want to retrieve a string stored in a model and at runtime change a part of it using a variable from the rails application. Here is an example:
I have a Message model, which I use to store several unique messages. So different users have the same message, but I want to be able to show their name in the middle of the message, e.g.,
"Hi #{user.name}, ...."
I tried to store exactly that in the database but it gets escaped before showing in the view or gets interpolated when storing in the database, via the rails console.
Thanks in advance.
I don't see a reason to define custom string helper functions. Ruby offers very nice formatting approaches, e.g.:
"Hello %s" % ['world']
or
"Hello %{subject}" % { subject: 'world' }
Both examples return "Hello world".
If you want
"Hi #{user.name}, ...."
in your database, use single quotes or escape the # with a backslash to keep Ruby from interpolating the #{} stuff right away:
s = 'Hi #{user.name}, ....'
s = "Hi \#{user.name}, ...."
Then, later when you want to do the interpolation you could, if you were daring or trusted yourself, use eval:
s = pull_the_string_from_the_database
msg = eval '"' + s + '"'
Note that you'll have to turn s into a double quoted string in order for the eval to work. This will work but it isn't the nicest approach and leaves you open to all sorts of strange and confusing errors; it should be okay as long as you (or other trusted people) are writing the strings.
I think you'd be better off with a simple micro-templating system, even something as simple as this:
def fill_in(template, data)
template.gsub(/\{\{(\w+)\}\}/) { data[$1.to_sym] }
end
#...
fill_in('Hi {{user_name}}, ....', :user_name => 'Pancakes')
You could use whatever delimiters you wanted of course, I went with {{...}} because I've been using Mustache.js and Handlebars.js lately. This naive implementation has issues (no in-template formatting options, no delimiter escaping, ...) but it might be enough. If your templates get more complicated then maybe String#% or ERB might work better.
one way I can think of doing this is to have templates stored for example:
"hi name"
then have a function in models that just replaces the template tags (name) with the passed arguments.
It can also be User who logged in.
Because this new function will be a part of model, you can use it like just another field of model from anywhere in rails, including the html.erb file.
Hope that helps, let me know if you need more description.
Adding another possible solution using Procs:
#String can be stored in the database
string = "->(user){ 'Hello ' + user.name}"
proc = eval(string)
proc.call(User.find(1)) #=> "Hello Bob"
gsub is very powerful in Ruby.
It takes a hash as a second argument so you can supply it with a whitelist of keys to replace like that:
template = <<~STR
Hello %{user_email}!
You have %{user_voices_count} votes!
Greetings from the system
STR
template.gsub(/%{.*?}/, {
"%{user_email}" => 'schmijos#example.com',
"%{user_voices_count}" => 5,
"%{release_distributable_total}" => 131,
"%{entitlement_value}" => 2,
})
Compared to ERB it's secure. And it doesn't complain about single % and unused or inexistent keys like string interpolation with %(sprintf) does.

CodeIgniter: set_message for max_length[x]

How do you set an error message for max_length and min_length rules. For instance, if I set a rule max_length[6], I'd like the error message to display
Max characters allowed: 5
I got the same problem and even though this post is old, there's no correct answer.. You just have to use the string placeholder %s in second place of your message. In the documentation (http://codeigniter.com/user_guide/libraries/form_validation.html#settingerrors) there is an example for a field not being empty:
$this->form_validation->set_message('username_check', 'The %s field can not be the word "test"');
There, it uses the %s placeholder for the name of the field, but if you modify the 'max_length' message putting the field name first and the length second like this:
$this->form_validation->set_message('max_length', 'The field %s max length is %s');
it will work. Is not the best solution, but that one works for me. Hope it helps
application/language/en/en_lang.php I have this:
$lang['name'] = "Name";
$lang['form_required'] = "is required.";
application/language/es/es_lang.php I have this:
$lang['name'] = "Nombre";
$lang['form_required'] = "es requiero.";
application/controllers/yourController.php I have this:
$this->form_validation->set_rules('name', $this->lang->line('name'), 'required|alpha|xss_clean');
$this->form_validation->set_message('required', '%s ' . $this->lang->line('form_required'));
I hope this help!
#Daniel is correct. Per CodeIgniter's documentation, you can override the default error message for any validation rule (such as "min_length", "max_length", etc.) like this:
$this->form_validation->set_message('validation_rule', 'Your message here');
So, in your example you could do:
$this->form_validation->set_message('max_length', 'Max characters allowed: 5');
Simply include that where your validation rules exist.
gAMBOOKa,
create a 'new' rule that also checks for max_length
$this->form_validation->set_rules('username', 'Username', 'required|_max_length[12]');
and for the method..
function _max_length($val)
{
if (strlen($this->input->post('username')) > $val)
{
$this->form_validation->set_message('_max_length', 'Max characters allowed: 5')
return FALSE;
}
return TRUE;
}
add this to your controller as a new rule and set the message like so ---^
CodeIgniter has one of the better documentations out of all the frameworks. Read the userguide on their site or the one in your CI directory.
http://codeigniter.com/user_guide/libraries/form_validation.html#settingerrors
Take a look in system/language/english/form_validation_lang.php and you'll find
$lang['max_length'] = "The %s field can not exceed %s characters in length.";
Which is easily overridden by copying it to
application/language/english/form_validation_lang.php
And changing it to the string you'd like. Do not edit the file in system/ directly, then it'll be overwritten if you upgrade CodeIgniter.
There is no need to add a new method. You may set a custom message to a form validation error by accessing the "max_length" rule as shown below.
$this->form_validation->set_rules('username', 'Username', 'required|min_length[5]', array('required' => 'Username is required.','max_length' => 'Max characters allowed: 5')
);
Note: This is also applicable for "min_length" rule.

Resources