In laravel, why provide the trailing . character in the prefix - laravel

In laravel, I had a question about the route name prefix.
The name method may be used to prefix each route name in the group with a given string. For example, you may want to prefix all of the grouped route's names with admin. The given string is prefixed to the route name exactly as it is specified, so we will be sure to provide the trailing . character in the prefix:
Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Route assigned name "admin.users"...
})->name('users');
});
I don’t understand the meaning of this sentence:
The given string is prefixed to the route name exactly as it is specified, so we will be sure to provide the trailing . character in the prefix
In addition to increasing readability, I don’t know the essential difference between adding . and not adding .

Related

Create title slug + random string Laravel 7

I would like to create a slug that combines the title + a random string in Laravel.
I tried this, but nothing, in the second case it does nothing but combine the character string with the title.
Str::slug(request('title'), '-', Str::random());
or
Str::slug(request('title'), Str::random());
I would like something like this:
this-is-an-example-title-Jfij4jio4523q234
Double-check the method signature from https://laravel.com/docs/7.x/helpers#method-str-slug (and deeper at https://github.com/laravel/framework/blob/7.x/src/Illuminate/Support/Str.php#L552)
To be explicit, the second parameter of the method is the character used to replace whitespace, and the third parameter refers to the locale to use when generating the slug. That means you need your string to be fully composed before passing it to the method.
Assuming you want your slug joined by a - then something like this is what you want:
$value = request('title') . ' ' . Str::random();
$slug = Str::slug($value); // optionally Str::slug($value, '-'); to explicitly define the join
Str::Slug() has been defined as:
slug(string $title, string $separator = '-', string $language = 'en')
The third param can be seen as language with default value: en.
Str::slug($request->input('title').Str::random(40), '-');
I hope this helps.

Unable to fetch get parameter with encoded '/' in Laravel using route

I am new to Laravel and working on existing code.
I want to pass some values in url in format of URL/val1/val2/val3.
Every thing is working perfect if all values with normal string or number
but if any value has special character like slash / or \ it shows errors.
eg.
working :- URL/abc/pqr/xys
but if val3 = 22/06 ;url is URL/val1/val2/22/06 error shows 404 not found
If I encoded val3 using javaScript's function encodeURIComponent()
val3=22%2F06 and url become URL/val1/val2/22%2F06 shows Object not found!
// My current route web.php is:-
Route::get('/export/{name}/{status}/{search}', 'ReportController#export')->name('export');
//routes.php
Route::get('view/{slashData?}', 'ExampleController#getData')
->where('slashData', '(.*)');
Your route accept only 3 params. But you pass four params.
Route::get('/export/{name}/{status}/{search}', 'ReportController#export')->name('export');
You must change your val3=22-06. Don't use / as value of your param.
Eg.
URL/val1/val2/22-06
You need to use regex expression for that situation:
Route::get('/export/{name}/{status}/{search}', 'ReportController#export')->name('export')->where(['search' => "[\w\/]+"]);

How to redirect to parent directory (don't delete rest of URL) when integer in url

I've got an URL like:
https://website.com/XXX/123/AA/BB/CC/DD
and if 123 is integer I would like it to redirect to:
https://website.com/XXX/AA/BB/CC/DD
How can I do that in nginx or Laravel?
On the Laravel side, one way is to create a route to match the url pattern and then redirect. You can use regular expression constraints to ensure the first part is an integer.
Route::get('xxx/{integer}/{a}/{b}/{c}/{d}', function ($integer, $a, $b, $c, $d) {
return redirect("/xxx/$a/$b/$c/$d");
})->where(['integer' => '[0-9]+']);

Wildcard Prefix Laravel 5

is there a way in Laravel 5 to have a recognized list of prefixes, such as ['gbr','en','eu'], so that
/gbr/bar/baz/shoelace // or
/eu/bar/baz/shoelace
is handled by the same controller#method as
/bar/baz/shoelace
Except that the additional parameter foo=gbr is passed in the first condition?
Note the Route::group prefix won't work because there may or may not be a prefix in this case. Also, this strategy should take precedence over all else, i.e. the Route would check for the (optional) prefix first.
Yes there is a way.
When declaring your routes, you can declare them as
Route::get('{prefix}/bar/baz/shoelace', 'controller#method')->where('prefix', 'gbr|en|eu');
gbr|en|eu is a simple regular expression that will match either the string gbr, en or eu. Check out Regular expression constraints for more details
And in your controller you can have
public function method($prefix) {
//code here
}

How do I combine CatchAll and EndsWith in an MVC route?

The following route will match any folder structure below BasePath:
http://BasePath/{*SomeFolders}/
How do I create another route which will match any zip file below the same BasePath structure?
I tried this...
http://BasePath/{*SomeFolders}/{ZipFile}
... but it errors with
A path segment that contains more than one section, such as a literal section or a parameter, cannot contain a catch-all parameter.
Parameter name: routeUrl
How should I approach this?
*Update*
The original requirements are in fact flawed.
{ZipFile} will match the final section regardless of what it contains. (File or Folder)
In reality I believe the route pattern I'm looking to match should be:
http://BasePath/{*SomeFolders}/{ZipFile}.zip
It seems that constraints are the answer here.
routes.MapRoute( _
"ViewFile", "BasePath/{*RestOfPath}", _
New With {.controller = "File", .action = "DownloadFile"}, _
New With {.RestOfPath = ".*\.zip"}
)
routes.MapRoute( _
"ViewFolder", "BasePath/{*RestOfPath}", _
New With {.controller = "Folder", .action = "ViewFolder"} _
)
or for those of you who prefer C#...
routes.MapRoute(
"ViewFile", "BasePath/{*RestOfPath}",
new {controller = "File", action = "DownloadFile"},
new {RestOfPath = #".*\.zip"}
);
routes.MapRoute(
"ViewFolder", "BasePath/{*RestOfPath}",
new {controller = "Folder", action = "ViewFolder"}
);
(Erm I think that's right)
The same route is registered twice, with the first variation being given the additional constraint that the RestOfPath parameter should end with ".zip"
I am given to understand that Custom Constraints are also possible using derivatives of IRouteConstraint.
Catch all anywhere in the URL - exactly what you need
I've written such Route class that allows you to do exactly what you describe. It allows you to put catch-all segment as the first one in the route definition (or anywhere else actually). It will allow you to define your route as:
"BasePath/{*SomeFolders}/{ZipFile}"
The whole thing is described into great detail on my blog post where you will find the code to this Route class.
Additional info
Based on added info I would still rather use the first route definition that doesn't exclude file extension out of the route segment parameter but rather add constraint for the last segment to be
"[a-zA-Z0-9_]+\.zip"
So routing should still be defined as stated above in my answer, but contraint for the ZipFile should be defined as previously written. This would make my special route work out of the box as it is now.
To also make it work for other route delimiters (like dot in your example) code should be changed considerably, but if you know routing very well how it works, you can change it to work that way.
But I'd rather suggest you keep it simple and add a constraint.
As the error says, your catchall has to be the last param in your route.
To get the ZipFile part out, you will have to parse it from the SomeFolders catchall:
public ActionResult MyAction(string SomeFolders)
{
// parse the ZipFile out from the SomeFolders argument
}
So if you have /folder1/folder2/folder3/file.zip, you can do this:
var zipFile = SomeFolders.SubString(SomeFolders.LastIndexOf("/") + 1);

Resources