Get last part of current URL in Laravel 5 using Blade - laravel

How to get the last part of the current URL without the / sign, dynamically?
For example:
In www.news.com/foo/bar get bar.
In www.news.com/foo/bar/fun get fun.
Where to put the function or how to implement this in the current view?

Of course there is always the Laravel way:
request()->segment(count(request()->segments()))

You can use Laravel's helper function last. Like so:
last(request()->segments())

This is how I did it:
{{ collect(request()->segments())->last() }}

Use basename() along with Request::path().
basename(request()->path())
You should be able to call that from anywhere in your code since request() is a global helper function in Laravel and basename() is a standard PHP function which is also available globally.

The Route object is the source of the information you want. There are a few ways that you can get the information and most of them involve passing something to your view. I strongly suggest not doing the work within the blade as this is what controller actions are for.
Passing a value to the blade
The easiest way is to make the last part of the route a parameter and pass that value to the view.
// app/Http/routes.php
Route::get('/test/{uri_tail}', function ($uri_tail) {
return view('example')->with('uri_tail', $uri_tail);
});
// resources/views/example.blade.php
The last part of the route URI is <b>{{ $uri_tail }}</b>.
Avoiding route parameters requires a little more work.
// app/Http/routes.php
Route::get('/test/uri-tail', function (Illuminate\Http\Request $request) {
$route = $request->route();
$uri_path = $route->getPath();
$uri_parts = explode('/', $uri_path);
$uri_tail = end($uri_parts);
return view('example2')->with('uri_tail', $uri_tail);
});
// resources/views/example2.blade.php
The last part of the route URI is <b>{{ $uri_tail }}</b>.
Doing it all in the blade using the request helper.
// app/Http/routes.php
Route::get('/test/uri-tail', function () {
return view('example3');
});
// resources/views/example3.blade.php
The last part of the route URI is <b>{{ array_slice(explode('/', request()->route()->getPath()), -1, 1) }}</b>.

Try request()->segment($number) it should give you a segment of the URL.
In your example, it should probably be request()->segment(2) or request()->segment(3) based on the number of segments the URL has.

YourControllor:
use Illuminate\Support\Facades\URL;
file.blade.php:
echo basename(URL::current());

It was useful for me:
request()->path()
from www.test.site/news
get -> news

I just had the same question. In the meantime Laravel 8. I have summarised all the possibilities I know.
You can test it in your web route:
http(s)://127.0.0.1:8000/bar/foo || baz
http(s)://127.0.0.1:8000/bar/bar1/foo || baz
Route::get('/foo/{lastPart}', function(\Illuminate\Http\Request $request, $lastPart) {
dd(
[
'q' => request()->segment(count(request()->segments())),
'b' => collect(request()->segments())->last(),
'c' => basename(request()->path()),
'd' => substr( strrchr(request()->path(), '/'), 1),
'e' => $lastPart,
]
)->where('lastPart', 'foo,baz'); // the condition is only to limit
I prefer the variant e).
As #Qevo had already written in his answer. You simply make the last part part of the request. To narrow it down you can put the WHERE condition at the route.

Try with:
{{ array_pop(explode('/',$_SERVER['REQUEST_URI'])) }}
It should work well.

Related

How to include a variable in a laravel redirect

I have a variable in a Laravel 5 controller which I am trying to include in the url of a redirect link, however nothing I've tried seems to work, my code is currently as follows.
$newChallenge = ((int) request('challenge_id') + 2);
return redirect('/texttext/{{$newChallenge}}');
However, this doesn't use the variable represented by $newChallenge, but rather
"{{newChallenge}}" as a string, how should this be done?
{{ }} is meant for use in blade files.
I think you can do return redirect('/texttext/{ $newChallenge }'); if you really want those { } brackets.
Or just return redirect(sprintf('/texttext/%s'), $newChallenge));
or return redirect('/texttext/'.$newChallenge);
Edit: Also, your redirect could probably benefit from being a named route. https://laravel.com/docs/5.8/routing#named-routes
May be you can change it to a query parameter
like
return redirect('/texttext/?=newChallenge={{$newChallenge}}');
if you want to use
return redirect('/texttext/{{$newChallenge}}');
It should be something like below
Route::get('texttext/{{newChallenge}}', 'YourController#newChallenge');
and newChallenge signature will function newChallenge(Request $request, $newChallenge)
if you want to use something like return redirect(route('new-challenge', $newChallenge));
just add name to route like
Route::get('texttext/{{newChallenge}}', 'YourController#newChallenge')->name('new-challenge');
I have not tested, but I think it should work.

Get part of url from Laravel named route

Is there a possibility to get the part of url, that is defined in route?
For example with this route:
Route::get('/editor/{id}', 'EditorController#editor')->name('editorNew');
after using mentioned functionality, let's say route_link(); i would like to get:
$route_link = route_link('editorNew', array('id' => 1));
//$route_link containts "/editor/1"
I tried to use route(), but i got http://localhost/app/public/editor-new/1 instead of /editor-new/1 and that's not what i wanted.
For clarity need this functionality to generate links depending on machine, that the app is fired on (integration with Shopify).
You can use route method to get the relative path by passing false in the third parameter as:
route('editorNew', [1], false); // returns '/editor-new/1'
You could use the following:
$route_link = route('editorNew', [1]);
1 is the first value that will be on the route, at this moment {id}.
If you want to use the paramater (id) in your method, it will be the following:
public function editor($id) {
//your code
}
And in the view you could use:
Route::input('id');
Hope this works!

How to automatically append query string to laravel pagination links?

I am working on search filter on checkbox click, with Laravel and Ajax call. So I get results when I click on a checkbox. my query is as follows:
$editors = User::with(['editor.credentials','editor.specialties','editor.ratings']);
$temp=$editors->whereHas('editor', function($q) use ($a_data){
$q->whereHas('specialties',function($sq) use($a_data){
$sq->whereIn('specialty',$a_data);
});
})->paginate(2);
This gives me all the data I need. however how should I get the links for pagination?
$temp->setBaseUrl('editors');
$links = $temp->links()->render();
I am currently doing this and with $links which I am sending over as response to ajax call, I set the pagination with $links data. Now, I need to append the query to next page like page=2?query="something". I don't know how should I go about appending the remaining query result links to next page links. i.e. I don;t know what should come in the query="something" part. Can someone guide me. thanks
{{ $users->appends($_GET)->links() }}
It will append all query string parameters into pagination link
As of Laravel 7, you can call the withQueryString() method on your Paginator instance.
Quote from the documentation:
If you wish to append all current query string values to the pagination links you may use the withQueryString method:
{{ $users->withQueryString()->links() }}
See "Appending To Pagination Links": https://laravel.com/docs/7.x/pagination#displaying-pagination-results
Check the answer from #Arda, as it's global solution. Below you can find how to do it manually.
Use appends on Paginator:
$querystringArray = Input::only(['search','filter','order']); // sensible examples
// or:
$querystringArray = ['queryVar' => 'something', 'anotherVar' => 'something_else'];
$temp->appends($querystringArray);
Append all input except the actual page, form token and what you don't want to pass:
$paginatedCollection->appends($request->except(['page','_token']));
For the latest version of Laravel at the moment (5.2), you can just use the Request facade to retrieve the query string and pass that to your paginator's appends() method
$input = Request::input();
$myModelsPaginator = App\Models\MyModel::paginate();
$myModelsPaginator->appends($input);
Add this anywhere in your app (e.g routes.php, filters.php or anything that's autoloaded), no need to edit any pagination codes that is written already. This works flawlessly using view composers, and you don't need to know any query string parameters:
////////PAGINATION QUERY STRING APPEND
View::composer(Paginator::getViewName(), function($view) {
$queryString = array_except(Input::query(), Paginator::getPageName());
$view->paginator->appends($queryString);
});
//////////////////
Inspired from previous answers I ended up using the service container for both frontend + api support.
In your AppServiceProvider#boot() method:
$this->app->resolving(LengthAwarePaginator::class, function ($paginator) {
return $paginator->appends(array_except(Input::query(), $paginator->getPageName()));
});
you can used request helper in view as same
{{ $users->appends(request()->query())->links() }}
in your view where you display pagination...
{{ $results->appends(Request::except('page'))->links() }}
appends keeps the query string value except "page". not sure if it will work with POST request
{{ $users->appends(Request::only(['filter','search']))->links()}}
Updating #rasmus answer for Laravel 8.
In your AppServiceProvider boot method, add the following lines and your existing query string will be be used for all pagination links
$this->app->resolving(Paginator::class, function ($paginator) {
return $paginator->appends(Arr::except(Request::query(), $paginator->getPageName()));
});
$this->app->resolving(LengthAwarePaginator::class, function ($paginator) {
return $paginator->appends(Arr::except(Request::query(), $paginator->getPageName()));
});
And for completeness, use these classes:
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Request;

Is there a way to set a default url parameter for the Route class in Laravel 4?

I'm trying to set up sub-domain based routing in Laravel 4 and I've hit a bit of an annoyance...
My route group looks like this:
Route::group(array('domain' => '{company}.domain.com'), function() {
// ...
});
Which seems to work fine, however, I need to specify the company parameter for every route/url I generate. I.e:
{{ HTML::linkRoute('logout', 'Logout', ['company' => Input::get('company')]) }}
Is there any way to specify the company parameter as static/global, so it is automatically added to any links I specify, unless otherwise overwritten/removed?
Unfortunately, no (I haven't seen any evidence in the router or HTMLBuilder that you can). You could, however, make an HTML macro... Example:
HTML::macro('lr', function($link, $title) {
$company = !empty(Input::get('company')) ? Input::get('company') : "";
return HTML::linkRoute($link, $title, ['company' => $company]);
});
Then call it - instead of HTML::linkRoute, use HTML::lr('logout', 'Logout')
Just an idea.

Call a controller in Laravel 4

In Laravel 3, you could call a controller using the Controller::call method, like so:
Controller::call('api.items#index', $params);
I looked through the Controller class in L4 and found this method which seems to replace the older method: callAction(). Though it isn't a static method and I couldn't get it to work. Probably not the right way to do it?
How can I do this in Laravel 4?
You may use IoC.
Try this:
App::make($controller)->{$action}();
Eg:
App::make('HomeController')->getIndex();
and you may also give params:
App::make('HomeController')->getIndex($params);
If I understand right, you are trying to build an API-centric application and want to access the API internally in your web application to avoid making an additional HTTP request (e.g. with cURL). Is that correct?
You could do the following:
$request = Request::create('api/items', 'GET', $params);
return Route::dispatch($request)->getContent();
Notice that, instead of specifying the controller#method destination, you'll need to use the uri route that you'd normally use to access the API externally.
Even better, you can now specify the HTTP verb the request should respond to.
Like Neto said you can user:
App::make('HomeController')->getIndex($params);
But to send for instance a POST with extra data you could use "merge" method before:
$input = array('extra_field1' => 'value1', 'extra_field2' => 'value2');
Input::merge($input);
return App:make('HomeController')->someMethodInController();
It works for me!
bye
This is not the best way, but you can create a function to do that:
function call($controller, $action, $parameters = array())
{
$app = app();
$controller = $app->make($controller);
return $controller->callAction($app, $app['router'], $action, $parameters);
}
Route::get('/test', function($var = null) use ($params)
{
return call('TestController', 'index', array($params));
});
Laurent's solution works (though you need a leading / and the $params you pass to Request::create are GET params, and not those handled by Laravel (gotta put them after api/items/ in the example).
I can't believe there isn't an easier way to do this though (not that it's hard, but it looks kinda hackish to me). Basically, Laravel 4 doesn't provide an easy way to map a route to a controller using a callback function? Seriously? This is the most common thing in the world...
I had to do this on one of my projects:
Route::controller('players', 'PlayerController');
Route::get('player/{id}{rest?}', function($id)
{
$request = Request::create('/players/view/' . $id, 'GET');
return Route::dispatch($request)->getContent();
})
->where('id', '\d+');
Hope I'm missing something obvious.
$request = Request::create('common_slider', 'GET', $parameters);
return Controller::getRouter()->dispatch($request)->getContent();
For laravel 5.1
It's an Old question. But maybe is usefull. Is there another way.
In your controller: You can declare the function as public static
public static function functioNAME(params)
{
....
}
And then in the Routes file or in the View:
ControllerClassName::functionNAME(params);

Resources