I want to make standard request for laravel localization file: animals.php
which looks like:
<?php
return [
'dog' => 'dog trans',
'cat' => 'cat trans',
'super-mutant-spider' => 'super-mutant-spider trans',
];
Now when I'm accessing this, I'm simply writing:
trans('animals.dog') -> gives dog trans etc.
this is fine,
now I want to make it depend on the user variable animal:
so when $user->animal is 'dog' I want dog trans result.
so when I try: trans('animals.$user->animal') it will not work
How can I code it?
This is basic string concatenating.
What you need is basically this: trans('animals.' . $user->animal)
You have detailed explanation on PHP - concatenate or directly insert variables in string
Related
I wanted to pass a value of typed array to my route parameter, the array could be in any size and a different key-value pairs each time.
Route::get('/example/{array}', ...
So if I have an array like this:
$array = [
'a' => 'one',
'b' => 1,
...
]
I did this but knew already it ain't gonna work because it looks like I'm passing values to my route parameters named a, b, etc.
route('route.name', $array)
As expected the error says:
... [Missing parameter: array]
So I used the serialize().
route('route.name', serialize($array))
I'm still getting an error, something like:
[Missing parameter: s:1:"a";i:1;s:1:"b";i:2;]
What am I missing ? I also don't understand what the last error says.
PHP have for this the http_build_query function.
$array = [
'a' => 'one',
'b' => 1,
];
$query = http_build_query(array('myArray' => $array));
// output: myArray%5Ba%5D=one&myArray%5Bb%5D=1
When passing data to a route in Laravel you should make a practice of passing that data in an array like so:
Route:
Route::get('/example/{array}', ...
Calling the named route:
route('route.name', ['array' => serialize($array)])
I don't know if this formatting is required, but it 1. helps you to better format your routes when passing multiple values, and 2, makes your code more readable.
Laravel Routing Documentation
I found the same problem, and from the tests I did, it seems to be an incompatibility between php and Laravel.
What happens is that php serialize() (and also php json_encode()) use the character «{». This character seems to confuse Laravel router, so the error message.
I have tried to use php htmlspecialchars(serialize($array)) (and other combinations like htmlentities(json_encode($array))) but the problem is that «{» is a normal character so they do not transform it (so continues confusing the Laravel router).
I also tried the solution of Maik Lowrey, but then I do not see an out of the box method to recover the array from the serialized parameter on the other side of the route (urldecode() does nothing).
At last I have used the following ugly turnaround that only works for one-dimension arrays (but works):
In the blade route generation:
['arrayParameter' => trim(json_encode($array), '{}')]
In the Controller function:
$array = json_decode('{' . $arrayParameter . '}', true);
Best regards.
How to add line break in laravel language files?
I have tried to use ,, \n\r,
to break line and add new line but all these not work.
return [
'best_hospitality' => 'Simply <br /> the best hospitality',
];
You can use
'best_hospitality' => "<pre>Simply\r\nthe best hospitality</pre>",
or 'best_hospitality' => sprintf ('<pre>Simply%sthe best hospitality</pre>',PHP_EOL ),
please note the use of double quotes in the first example, it is not working with single quotes if you use the \r\n inside the string, this is why
if you try echo(Lang::get('message.best_hospitality')) you will see the new line:
I am not so sure if you need the pre tag, depends where you need to use the Lang for html or not, eg using (double quotes here):
'best_hospitality' => "Simply\r\nthe best hospitality",
and var_dump(Lang::get('message.best_hospitality')); exit;
has the output
C:\wamp64\www\test\app\Http\Controllers\TestController.php:24:string 'Simply
the best hospitality' (length=39)
Does this cover your case?
You need HTML Entity Names on your lang files.
Try this :
return [
'best_hospitality' => 'Simply <br> the best hospitality',
];
May I suggest creating a custom helper function for this specific case?
Add this into your helpers.php file:
if (! function_exists('trans_multiline')) {
/**
* Retrieve an escaped translated multiline string with <br> instead of newline characters.
*/
function trans_multiline($key, array $replace = [], string $locale = null): string
{
return nl2br(e(__($key, $replace, $locale)));
}
}
Now you will have a function trans_multiline() available for you in any view, which will behave pretty much like the built-in __() helper.
The function will fetch a localized string of text and replace any newline \r\n symbol with <br> tag.
Caveat: For a proper escaping it must be done before nl2br() function, like you see in the code above. So, to prevent any weird errors due to double-escaping, you must use this custom helper without any additional escaping, like so:
{!! trans_multiline('misc.warning', ['name' => 'Joe']) !!}
Escaping will be handled by the e() function (which is what Laravel uses under the hood of {{ }}) inside the helper itself.
And here's how you define a multiline translation string:
'warning' => "There's only 1 apple, :name!\r\nDon't eat it!"
Make sure to use double-quotes, so PHP actually replaces \r\n with a newline character.
Obviously, parameter replacing still works exactly like with the __() helper.
I'm having an array $customPre. I want to print the element of the array "Please specify which fund". I am doing like this:
{$customPre.Please specify which fund}
But it's not working.
In this case you need to use PHP-like syntax that is similar to PHP: {$variable['key']}.
If In PHP you have:
$smarty->assign('customPre', array ('Please specify which fund' => 'This is value'));
In Smarty you need to use:
{$customPre['Please specify which fund']}
And the output for this will be:
This is value
I believe you cannot use in this case dot syntax ( {$customPre.Please specify which fund}) because it's probably looks for whitespaces in keys. Even adding quotes won't help.
Apologies in advance for what I think might be a stupid question. I promise I have searched, but I'm not sure if I've searched for the correct things. I'm a very new programmer, Ruby is my first serious language, and I taught myself it over the past few months. I've also never asked a question on StackOverflow, so hopefully this is acceptably clear and meets the other requirements for question-asking. Here is the question:
I have a branching method that calls various different APIs and various different URLs within them, based upon the values passed to the method. As is, it looks like:
if api == x
url = "http://url.x.com/api/#{#variable}"
elsif api == y
url = "http://url.y.com/api/public/#{#var1}_#{#var2}/#{#variable}"
etc.
The url's being called are different for each operation, as are the necessary variables. The variables used in the requests are being created as instance variables at the beginning of the method. The possible values of the instance variables are stored in a large hash or are being passed into the method by the call itself. The hash is structured like:
$globalhash =
{
"api_1" =>
{
"call_type_1" => {"info_1" => "", "info_2" => ""},
"call_type_2" => {"info_1" => "", "info_2" => ""}
},
"api_2" =>
{
"call_type_1" => {"info_1" => "", "info_2" => ""},
"call_type_2" => {"info_1" => "", "info_2" => ""}
}
}
The problem I have is that this branching section goes on for a long time in the code--partially because I've done it suboptimally, I'm sure. I'm also sure that my code would be much more efficient if the branching section didn't exist. Ideally, instead of the branching section, I'd like to make this happen:
url = $globalhash[#api][#call_type]["url"]
The value that pulls would be a URL specific to the call type and the api--the address, formatting, and various other differences included. So some values would be:
http://api.x.com/#var1_#var2/#variable
http://api.y.com/public/#variable
and so on. So the structures vary, and I need to access the instance variables stored within the method call, but I need to do so dynamically. The issue I've had is that every way I've tried to implement this results in the values of the instance variables in the strings for "url" being set when $globalhash is read as the program begins to run, with them all being nil. I need it to check the variable when the request is being made, and not before, basically. I have a similar (same?) issue with setting the post_data for the request--if I could find a way to set it in the hash, I'd have cleaner code that runs faster. The post_data is as:
post_data = {'value' => #var1, 'value2' => #var2, 'value3' => #var3}
and so on. The post_data is different for each API and for each call_type; the values are different as are the requested variables for them. I'd like to implement a set of key-value pairs in the hash that look vaguely like:
$globalhash = {"api_1" => {"call_type_1" => {"url" => "http://api.x.com/#{#variable}", "post_data" => "{'value' => #var1, 'value2' => #var2, etc.}"}}}
Except, of course, it would need to work--the variables it needs to reference are nil when $globalhash is being read. I'm not sure how best to solve this.
The program works as-is, but I have a very derpy-looking ~80 lines of branching code that figures out the structure of the URL and the post_data, and then requests it.
The only solution I've considered is creating an instance hash within the method to replace the branching code, that only gets created after declaring the instance variables. However, I'm afraid that would create a similar problem to the current one, of it being inefficient to create a huge new hash every time.
Thanks for reading, and I appreciate your help. I hope the pseudo-code is acceptable, I found it the best way to explain my question.
EDIT: Found a solution. Code:
url = eval "\"#{$globalhash["api_1"]["call_type_1"]["url"]}\""
["url"] references 'http://api.x.com/#{#variable}', single quotes prevent interpolation within the hash, eval function puts it in double quotes and string interpolation collects the instance variable at the time it is called. It's an ugly methodology BUT it does let me greatly shorten my code. Source: https://www.ruby-forum.com/topic/3237101
Instead of creating the hash using the instance variables...
post_data = {'value' => #var1, 'value2' => #var2, 'value3' => #var3}
...you could initialize the hash using strings representing the instance variables.
post_data = {'value' => '#var1', 'value2' => '#var2', 'value3' => '#var3'}
Then when you reference the hash variable, you would wrap the call in an eval.
post_data = {'value' => '#var1', 'value2' => '#var2', 'value3' => '#var3'}
#var2 = 'this is test data'
eval(post_data['value2'])
=> "this is test data"
Similarly I would use placeholders in the url...
url = 'http://api.x.com/[#variable]'
#variable = "cotton_tree"
my_url = url.dup
my_url.sub!(/\[.*?\]/, eval(my_url.match(/\[(.*?)\]/)[1])) while my_url.match(/\[(.*?)\]/)
p my_url
=> "http://api.x.com/cotton_tree"
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.