Why is passing of second variable on href much flexible in Laravel? - php

I am using Laravel Framework 4.1.30.
My Original Problem was...
I got a working route that when I type "localhost/user/alvin" it works but when I click a drop-down bar, it does not work.
drop-down bar from template was: (li tag removed)
{{ Auth::user()->username }}
route is:
Route::get('/user/{username}', array(
'as' => 'profile-user',
'uses' => 'ProfileController#user'));
View of URL when I click the dropdown bar is:
"localhost/user/%7Busername%7D"
I got 3 working answers for this from other communities.
First was a simple:
{{ Auth::user()->username }}
Second was:
{{ Auth::user()->username }}
Last was:
<a href="{{ URL::route('profile-user',['username'=>Auth::user()->username]) }}">
{{ Auth::user()->username}}</a>
Originally I thought the simplest (First Solution) form would be the wisest choice but as per most developer they choose the Third answer because it allows some flexibility to some extent.
I want to implement a good Quality Assured code as much as possible.
My question... Why would the 3rd solution be much more flexible compared to a much simpler code?

You can even use a more flexible, shorter modification of the third one:
<a href="{{ route('profile-user', Auth::user()->username) }}">
When you are using named routes, you do not put actual URLs, nor controller method names into your Views. You only provide a route name to your Views, and all other things are defined in your routes, and can be changed, if needed, without making breaking anything else. It would be a waste not to use this feature.
It is also more flexible, by not specifying the parameter name, so it can be changed in the routes too, without breaking the Views. This way they will be just taken in the order they were inputted. They are also read by a controller method in the order, i.e. public function index($parameter1, $parameter2) not by an associative array.
The route() is an alias to URL::route().

Related

Laravel - Conditional Route Name mapping / dynamic routes

I thought to write static routes like contact, imprint or "About Us" in the web.php as a one-liner. I saw this at Laravel Daily.
web.php
Route::get('/{page}', App\Http\Controllers\StaticPageController::class)
->name('page')
->where('page', 'about-us|imprint|contact');
It's nice but I'm getting problems with my navbar.
My Blade navbar has a dynamic part. The current menu item is highlighted. Very simple.
nav.blade.php
<x-nav-link :href="route('about-us')" :active="request()->routeIs('about-us')">
{{ __('About us') }}
</x-nav-link>
With the new one-liner, I then get the following error message:
Symfony\Component\Routing\Exception\RouteNotFoundException.
Route [about-us] not defined. (View: /project01/resources/views/includes/nav.blade.php)
Which is logical, because I no longer have the about-us route.
Actually, the route should be given a corresponding array mapping. But I don't know how. How can I solve the problem?
The solution for this problem will be:
<x-nav-link :href="route('page', ['page' => 'about-us'])" :active="request()->routeIs('about-us')">
{{ __('About us') }}
</x-nav-link>
Special Thanks for all good answears!
You have two options.
1- Change the routeIs() to is() and use the path, not the route name
<x-nav-link :href="route('page', ['page' => 'about-us'])" :active="request()->is('about-us/*')">
{{ __('About us') }}
</x-nav-link>
2- Switch back to 3 routes instead of the one liner. There is no gain in using the one liner. It is slower and harder to read (maintain)
You have assigned a name page to a given route with the required parameter named page. So, you must use the following code:
route('page', ['page' => 'about-us']);
https://laravel.com/docs/6.x/routing#named-routes
I think there is a misunderstanding.'about-us|imprint|contact' is the parameter restrictions.'page' is the route name.So this should work;
<x-nav-link :href="route('page','about-us')" :active="Request::url() == route('page','about-us')">
{{ __('About us') }}
</x-nav-link>

Make method of Twig-safe function also Twig-safe

I have defined a Twig function like this:
new Twig_SimpleFunction('link', 'html_link', ['is_safe' => ['html']]);
so every {{ link(...) }} isn't auto-escaped by Twig. That works.
But html_link() returns a Link object that can be tweaked in the template, to add a URL #fragment or link [attribute]:
{{ link('url', 'label').withFragment('foo') }}
{{ link('url', 'label').withClass('special') }}
But Twig detects that it's not a pure link() anymore, so it's not html-safe anymore, and I have to add |raw to make it work:
{{ link('url', 'label').withFragment('foo')|raw }}
{{ link('url', 'label').withClass('special')|raw }}
Which works. But. Not very pretty.
Can I tell Twig that link().withFragment() and link().withClass() are still html-safe?
Custom filters have an option preserves_safety that kinda works kinda like that:
{{ someFunction(someVar)|someFilter }}
If someFunfction is html-safe, and someFilter was defined with preserves_safety, the output is still safe. I don't want to make filters for ever Link method, so that's not quite good enough.
I can't use Twig_Markup, because:
It has to remain an object as long as possible (withFragment, withClass etc return $this), so you can do multiple things to it, e.g. add a class AND a fragment.
It must be usable outside of Twig. E-mails and flash messages can include links. Only Twig knows (and should know) what a Twig_Markup is. Since it's not an interface, I can't add it to the Link class.

Pass two parameters as one to TWIG url

I'm using a framework (specifically EC-Cube3, if interested) that uses a Silex application with TWIG templates.
It has a navigation sidebar that is configured with PHP object arrays. I can inject an item array that looks something like this:
$item = array(
"id" => "item_id"
"url" => "named_url"
);
The url is created in typical Silex fashion:
$app->match('/item', 'Controller::method')->bind('named_url');
The framework eventually uses the url field and evaluates it in TWIG like so:
{{ url(item.url) }}
And this is usually fine! But the problem comes when I have a URL that includes a parameter, like this:
$app->match('/item/{id}', 'Controller::method')->bind('named_url'); // Needs 'id' to be evaluated.
In this scenario, setting the URL by the same array won't work because TWIG's url function needs the id for the second argument.
Since I can't change the application's TWIG files (because then I can't safely update the application), I need to be able to set the item's url to include the id as well.
After investigating, I don't think this is possible. Is it true that this is impossible? Or is there some method that I'm unaware of?
You can use mutiple vars like this
{{ path('path_in_route', {'id': article.id,'slug': article.slug}) }}
And
path_in_route
must be in your router file.
Hope that helps you.
Can you try the following in your Twig file:
{{ url(item.url,{'id': id}) }}
I believe that should work, but not certain.
EDIT #2
What if you use something like this:
$app->match('/item', 'Controller::method($id)')->bind('named_url');
Where $id is the id you need to pass in. I'm not really familiar with Silex, but maybe it's something like that?

Hypertext to route not working

Hi I have a hyperlink from a page:
<h3>hitest</h3>
the route:
Route::get('hitest', function(){ return 'hitest message';});
There is an error:
No query results for model [App\User2].
hyper link is from a page with this url
/userpage/1
the 1 is a model object.
Shouldn't the hyperlink route to /hitest ?
Please see my other post: Strange behavior with routing and hypertext.
I'm new at web development. Is there configurations for routing? The app is hosted (not local).
As bytesarelife already mentioned, you can use the url()-function, like so:
{{ url('your/url/') }}
A better way in terms of maintainability would be to give your routes names, so you would not have to replace every url in every template once you want to change it. You can do so, by adding the name in your routes:
Route::get('hitest', function(){ return 'hitest message';})->name('getHittest');
And then you can use the route function in your view:
{{ route('getHittest') }}

Diffrence between Laravel Routing Method

what is the difference between both routing ? can anyone explain ?
Route::get('login', 'webcontroller#login');
Route::get('login', array('as' => 'login','uses'=>'webcontroller#login'));
Well. There is the flexibility of Route object (i think it belongs to Symfony)
In the first statement, you explicitly say that you what controller's action a certain address should trigger (in your case it is 'login' which triggers login() of WebController).
In the second statement, you can add an "array" of settings for the controller's method, which, in your case you have specified a name. "login", which is the name of your Route::get() rule for the address "/login", could be used any where in the system without you explicitly specifying any controller or url which gives you the ability to change whatever you like in the future, as long as you are consistent with your names.
You set a route:
Route::get("login", array('as'=>'login', 'uses'=>'LoginController#Login');
Then you can use it like:
$url = URL::route('profile');
Whil you are still able to change the url of your route:
Route::get("user/login", ...);
Without the need to change its uses of "name" within your project.
You can read about it on Laravel's official documentation:
http://laravel.com/docs/4.2/routing#named-routes
In the number 2, you usea an alias , is easy for call de route in the code:
example:
<a href=" {{ route('user.list') }} ">
< span class="glyphicons glyphicons-link"></span>
<span class="sidebar-title">Link</span>
</a>

Categories