Suppose the route is like this:
Route::get('messages/{messages}', ['as' => 'messages.show', 'uses' => 'MessagesController@show']);
So, when we will create an URL using URL helper of Laravel,
{{ route('messages.show', 12) }}
will display example.com/messages/12
.
This is correct. Let's have some hash in the URL.
{{ route('messages.show', [12, '#reply_23']) }}
This will display example.com/messages/12#reply_23
.
This looks good. Now let's add some query strings instead of the hash.
{{ route('messages.show', [12, 'ref=email']) }}
This will display example.com/messages/12?ref=email
. This looks cool.
Now add both query string and hash.
{{ route('messages.show', [12, 'ref=email', '#reply_23']) }}
Now this will display example.com/messages/12?ref=email&#reply_23
. This looks little ugly because of the &
in the URL. However it's not creating a lot of problem, I would like to get a clean URL like example.com/messages/12?ref=email#reply_23
. Is there a way to get rid of the unnecessary &
in the URL?
Edit: There is a workaround, but I am looking for a solid answer.
<a href="{{ route('messages.show', [12, 'ref=email']) }}#reply_23">Link to view on website</a>
The Laravel UrlGenerator
class does not support specifying the #fragment
part of the URL. The code responsible for building the URL is the following, and you can see it just appends the query string parameters and nothing else:
$uri = strtr(rawurlencode($this->trimUrl(
$root = $this->replaceRoot($route, $domain, $parameters),
$this->replaceRouteParameters($route->uri(), $parameters)
)), $this->dontEncode).$this->getRouteQueryString($parameters);
A quick test of your code reveals that the second example you posted:
{{ route('messages.show', [12, '#reply_23']) }}
Actually generates:
/messages/12?#reply_23 // notice the "?" before "#reply_23"
So it treats #reply_23
as a parameter rather than as a fragment.
An alternative to this shortcoming would be to write a custom helper function that allows to pass the fragment as a third parameter. You could create a file app/helpers.php
with your custom function:
function route_with_fragment($name, $parameters = array(), $fragment = '', $absolute = true, $route = null)
{
return route($name, $parameters, $absolute, $route) . $fragment;
}
Then add the following line at the end of your app/start/global.php
file:
require app_path().'/helpers.php';
You can then use it like this:
{{ route_with_fragment('messages.show', [12, 'ref=email'], '#reply_23') }}
Of course you can name the function whatever you want, if you feel the name I gave it is too long.