Is there a difference between Lang::get('locale') and __('locale') in Laravel? - multilingual

In Laravel 5.7 the docs say to use the following syntax to retrieve locales
{{ __ ('my.locale')}}
but I noticed
{{Lang::get('my.locale')}}
works too, and it's in fact what was also used in previous versions.
Is there a fundamental difference between this two, or just the syntax changed?

The main difference is that __() and #lang will check for json translation files in addition to your php language files. Other than that, the syntax hasn't changed; they all defer to the same \Illuminate\Translation\Translator::get() method eventually.
These will all work from a Blade view:
#lang('...')
{{ __('...') }}
{{ trans('...') }}
{{ Lang::trans('...') }}
{{ Lang::get('...') }}
{{ app('translator')->get('...') }}
If you use the #lang Blade directive, keep in mind that it doesn't escape htmlentities, which means your translation strings would need to be stored in their escaped form (e.g. <> instead of <>). None of the other functions escape htmlentities either, but using #lang is the only option in that list that doesn't pass the string through the handlebars {{ }}, which is where the escape function is called. It may not be common to have html special characters in a translation string, and translation strings don't usually come from user input (so cross-site scripting isn't an issue), but it's worth knowing.
If you want to dive deeper, this is the difference with __() (as of Laravel 5.8):
/**
* Translate the given message.
*
* #param string $key
* #param array $replace
* #param string $locale
* #return string|array|null
*/
function __($key, $replace = [], $locale = null)
{
return app('translator')->getFromJson($key, $replace, $locale);
}
You can see it's using getFromJson() instead of get(). However, getFromJson() falls back to get() if it didn't find anything in your json files:
// If we can't find a translation for the JSON key, we will attempt to translate it
// using the typical translation file. This way developers can always just use a
// helper such as __ instead of having to pick between trans or __ with views.
if (! isset($line)) {
$fallback = $this->get($key, $replace, $locale);
if ($fallback !== $key) {
return $fallback;
}
}
Then there's trans(), which is nothing more than an alias for get():
public function trans($key, array $replace = [], $locale = null)
{
return $this->get($key, $replace, $locale);
}

Related

Issue using Graphql in my react app. I just can't get the variable section to work [duplicate]

So i have a method that searches for anime by name, API is graphQL.
Here's the important part of the query
const searchQuery = this.state.searchString;
var query = `query Search{
# the rest of the query omitted for brevity
media(type:ANIME, search: ${searchQuery} ){
# ...
}
`
I'm getting two types of errors in response, first is when search string consists of multiple words separated by spaces - "Syntax Error: Expected :, found )"
Second when i search for single word - "Field "media" argument "search" requires type String, found naruto."
What is the problem here?
You can see full code here - https://github.com/red4211/react-anime-search , app deployed to github pages, search API response goes to console - https://red4211.github.io/react-anime-search/
The issue is that given some query like "naruto", your current code results in the following text:
media(type:ANIME, search: naruto ) {
This is not valid syntax since String literals should be surrounded by double quotes (").
Don't use string interpolation to provide dynamic values to the query. These should always be expressed as variables and included as a separate object inside your request alongside query.
You need to define the variable as part of your operation, providing the appropriate type
var query = `query Search ($searchQuery: String!) {
then you can use the variable anywhere inside the operation:
media(type:ANIME, search: $searchQuery) {
Now just pass the variable value along with your request.
body: JSON.stringify({
query,
variables: {
searchQuery,
}
})
Note that the variable name is prefixed with a $ inside the GraphQL document, but outside of it, we don't do that.
media() looks like a function, so in that case the correct syntax would be:
media(type="ANIME", search=searchQuery)
or if the argument of media() is an object
media({type: "ANIME", search: searchQuery})
Also, you don't need to use ${} around searchQuery since searchQuery is already a string. The usage for that would be something like
`${searchString}` or `foo${searchString}bar`
using the `` around the ${} utility to represent a string and its variable inside the string literal.
Hope it helps!

Gatling .sign issue

I am trying to build a Get request as follows and I would like CaseReference value to be populated via feeder .feed(CaseProviderSeq) but for some reason it's not picking CaseReference value and printing following for my println statement in .sign statement bellow
PATH KJ: /caseworkers/554355/jurisdictions/EMPLOYMENT/case-types/Manchester_Multiples/cases/$%7BCaseReference%7D/event-triggers/updateBulkAction_v2/token
My feeder CSV got following rows currently
1574761472170530
1574622770056940
so I am expecting this amended URL would be like
/caseworkers/554355/jurisdictions/EMPLOYMENT/case-types/Manchester_Multiples/cases/1574761472170530/event-triggers/updateBulkAction_v2/token
any idea what wrong I am doing here ??
.get(session => SaveEventUrl.replace(":case_reference","${CaseReference}").replaceAll("events", "") + s"event-triggers/${EventId}/token")
.header("ServiceAuthorization", s2sToken)
.header("Authorization", userToken)
.header("Content-Type","application/json")
.sign(new SignatureCalculator {
override def sign(request: Request): Unit = {
val path = request.getUri.getPath
println("PATH KJ: " + path)
request.getHeaders.add("uri", path)
}
})
This is not related to .sign, but your session attribute CaseReference not being interpreted. If you look closely you can see the braces %-encoded in $%7BCaseReference%7D.
Interpretation of the Gatling Expression Language strings happens only when a String is present when an Expression[Something] is needed1.
This bug you wrote is shown exactly in the warning in the documentation above.
I believe you can simply remove session => in your .get, so you are passing in a String rather than a Session => String2. That string will be implicitly converted to Expression[String]. That way Gatling will put the session attribute into the URL.
This happens because of the Scala implicit conversion.
In fact it is Session => Validation[String], because, again, of implicit conversions.

Template literal - getting error from API

So i have a method that searches for anime by name, API is graphQL.
Here's the important part of the query
const searchQuery = this.state.searchString;
var query = `query Search{
# the rest of the query omitted for brevity
media(type:ANIME, search: ${searchQuery} ){
# ...
}
`
I'm getting two types of errors in response, first is when search string consists of multiple words separated by spaces - "Syntax Error: Expected :, found )"
Second when i search for single word - "Field "media" argument "search" requires type String, found naruto."
What is the problem here?
You can see full code here - https://github.com/red4211/react-anime-search , app deployed to github pages, search API response goes to console - https://red4211.github.io/react-anime-search/
The issue is that given some query like "naruto", your current code results in the following text:
media(type:ANIME, search: naruto ) {
This is not valid syntax since String literals should be surrounded by double quotes (").
Don't use string interpolation to provide dynamic values to the query. These should always be expressed as variables and included as a separate object inside your request alongside query.
You need to define the variable as part of your operation, providing the appropriate type
var query = `query Search ($searchQuery: String!) {
then you can use the variable anywhere inside the operation:
media(type:ANIME, search: $searchQuery) {
Now just pass the variable value along with your request.
body: JSON.stringify({
query,
variables: {
searchQuery,
}
})
Note that the variable name is prefixed with a $ inside the GraphQL document, but outside of it, we don't do that.
media() looks like a function, so in that case the correct syntax would be:
media(type="ANIME", search=searchQuery)
or if the argument of media() is an object
media({type: "ANIME", search: searchQuery})
Also, you don't need to use ${} around searchQuery since searchQuery is already a string. The usage for that would be something like
`${searchString}` or `foo${searchString}bar`
using the `` around the ${} utility to represent a string and its variable inside the string literal.
Hope it helps!

How to set a context variable with dot in name?

I am trying to add a context data variable (CDV), which has a dot in its name. According to Adobe site this is correct:
s.contextData['myco.rsid'] = 'value'
Unfortunately, after calling s.t() the variable is split into two or more:
Context Variables
myco.:
rsid: value
.myco:
How can I set the variable and prevent splitting it into pieces?
You are setting it properly already. If you are referring to what you see in the request URL, that's how the Adobe library sends it. In your example, "myco" is a namespace, and "rsid" is a variable in that namespace. And you can have other variables in that namespace. For example if you have
s.contextData['myco.rsid1'] = 'value';
s.contextData['myco.rsid2'] = 'value';
You would see in the AA request URL (just showing the relevant part):
c.&myco.&rsid1=value&rsid2=value&.myco&.c
I assume you are asking because you want to more easily parse/qa AA collection request URLs from the browser network tab, extension, or some unit tester? There is no way to force AA to not behave like this when using dot syntax (namespaces) in your variables.
But, there isn't anything particularly special about using namespaces for your contextData variables; it's just there for your own organization if you choose. So if you want all variables to be "top level" and show full names in the request URL, then do not use dot syntax.
If you want to still have some measure of organization/hierarchy, I suggest you instead use an underscore _ :
s.contextData['myco_rsid1'] = 'value';
s.contextData['myco_rsid2'] = 'value';
Which will give you:
c.&myco_rsid1=value&myco_rsid2=value&.c
Side Note: You cannot do full object/dot notation syntax with s.contextData, e.g.
s.contextData = {
foo:'bar', // <--- this will properly parse
myco:{ // this will not properly parse
rsid:'value' //
} //
};
AA library does not parse this correctly; it just loops through top level properties of contextData when building the request URL. So if you do full object syntax like above, you will end up with:
c.&foo=bar&myco=%5Bobject%20Object%5D&&.c
foo would be okay, but you end up with just myco with "[object Object]" as the recorded value. Why Adobe didn't allow for full object syntax and just JSON.stringify(s.contextData) ? ¯\_(ツ)_/¯

File system path for images

I'm writing a custom helper that extends HtmlHelper and overriding the \HtmlHelper::image() method to calculate the image dimensions and add them as HTML attributes. What I have so far works fine for regular pictures:
public function image($path, $options = array()) {
if (!array_key_exists('width', $options) && !array_key_exists('height', $options)) {
$stamp = Configure::read('Asset.timestamp');
Configure::write('Asset.timestamp', false);
$path = $this->assetUrl($path, $options + array('pathPrefix' => Configure::read('App.imageBaseUrl')));
list($width, $height) = #getimagesize(rtrim(WWW_ROOT, '\\/') . $path);
if (!is_null($width)) {
$options['width'] = $width;
}
if (!is_null($height)) {
$options['height'] = $height;
}
Configure::write('Asset.timestamp', $stamp);
}
return parent::image($path, $options);
}
… but has these flaws:
Pictures from plug-ins can't be located on disk (and they should), e.g.:
echo $this->Html->image('/debug_kit/img/cake.icon.png', array('alt' => 'CakePHP'));
… produces this file system path:
…\src\webroot/debug_kit/img/cake.icon.png
… thus getimagesize() fails because actual location is:
…\src\Plugin\DebugKit\webroot\img\cake.icon.png"
External pictures (which should be ignored) go through the full process:
echo $this->Html->image('http://placekitten.com/200/300');
…\src\webroothttp://placekitten.com/200/300
I've been looking for a builtin method to convert a CakePHP picture URL (in any format accepted by \HtmlHelper::image() into a file system path (o something like null when doesn't apply) but I couldn't find any. Native features that need a disk path, such as \Helper::assetTimestamp() are wrapped in tons of non-reusable code.
Is there an elegant solution?
I'd say that there are pretty much only 3 options:
Submit a patch to add asset filesystem path retrieval functionality to the core.
Copy a lot of code from the helper (assetUrl(), webroot(), and assetTimestamp()).
Use web requests for local URLs (ideally combined with caching).
Try using DS rather than using \ or /, they sometime can cause problems with the OS.
DS is directory separator provided by cakephp Short for PHP’s DIRECTORY_SEPARATOR, which is / on Linux and \ on Windows.
Check the doc

Resources