Code Happy: Links and URLs

← Back to Index

Please note that this chapter was written for VERSION 3 of the Laravel PHP Framework.

Our application might get a little boring if we only have one page, and I'm sure the user would get peeved quite quickly if they had to type out the full URI each time to switch pages. Fortunately, hyper-links are here to save the day.

If you haven't been living under a rock for the past couple of decades you will already know what hyper-links are and I won't bore you with the technical explanation. Before we have a look at links let's take a look at how Laravel handles its URLs.

Retrieving URLs

First let's take a look at a problem. You see frameworks have very unique URL structures. Some may have an index.php in them, some installations won't. Others will have complex routes. In most cases using a relative URL like you would on another website would lead to trouble in the long run. If you chose to provide full URL's to everything and later decided to move the application to a different domain, you might find yourself abusing the find and replace function of your favourite editor.

Why not let Laravel do all the hard work? Laravel knows the full URL to your application. It knows whether or not you are using URL rewriting. It knows about your routes. It even knows what you keep in that box under your bed.. Let's take advantage of this information by using the URL class to generate some site URLs.

Let's start by finding the URL to the root of our website. We can use the base() method for this.

<?php

echo URL::base();
// http://myproject

Great! Now we have the full URL to our site, with or without the index.php on the end. It all depends on your current set-up. What about the current URL, the one that is being routed at the moment, can we get that? You betcha! Simply use the current() method.

<?php

echo URL::current();
// http://myproject/this/page

By default Laravel will strip off the query string if one is appended to the URL. If we want to retrieve the current URL along with the query string, we can use the full() method instead.

<?php

echo URL::full();
// http://myproject/this/page?thing=stuff

Knowing our base URL and current URL can be handy, but it would be more useful if we could get the URL to other routes or pages, then we could create links.

To generate a URL to a route, we use the to() method, and hand it the route that we are trying to retrieve. This is much easier than specifying the full path, for example..

<?php

echo URL::to('my/route');
// http://myproject/my/route

If we want to link to this page securely via the HTTPS protocol we can use the method to_secure() instead.

<?php

echo URL::to_secure('my/route');
// https://myproject/my/route

Do you remember being taught about named routes in the routing chapter? Of course you do! Here's an example of one again..

<?php

Route::get('login', array('as' => 'login', 'do' => function() {
    // some code
}));

Here we have a route that we have named 'login' using the 'as' array key. Well I told you that it would be useful later, and now is the time for named routes to shine. Let's make a link to our named 'login' route..

<?php

echo URL::to_route('login');
// http://myproject/login

Woah! Very clean and expressive I think you will agree. What if we need to supply parameters to our route? Simple, just pass an array of parameters as a second parameter to the to_route() method. Let's imagine for a second that our login route looks more like this...

<?php

Route::get('my/(:any)/login/(:any)/page')..

It's a terrible route, please don't use ugly URL's like this one, but it will help to illustrate a point. You see, if you pass parameters to the to_route() method, Laravel will automatically work out which order they should appear in the URL and return the full URL with the parameters in the right place. Neat!

<?php

echo URL::to_route('login', array(5, 7));

The above method would give us..

http://myproject/my/5/login/7/page

Great! Now our routes will look squeaky clean.. as long as we don't create routes as complicated as that one. Also if we decide to change the URI for our route at a later date, we won't need to update all of our links!

So that's routes cleared up, but we shouldn't forget controllers. No one likes to be left out. Fortunately there's a nice and clean way to create a link to a controller action. Simply use the to_action() method, for example..

<?php

echo URL::to_action('dashboard@home');
// http://myproject/dashboard/home

Just pass the controller name and action, separated by an @ (at) symbol. Once again you can pass an array of extra parameters as a second parameter to the to_action() method if you need to.

If we are dealing with assets, a CSS style-sheet for example, rather than routes pages we will need a very different URL. We can't use URL::to() because that might put an index.php in the URL or resolve it to one of our routes.

Instead we can use the to_asset() method to generate a correct link. Simply pass the application relative path to our style-sheet and Laravel will take care of the rest.

<?php

echo URL::to_asset('css/style.css');

This line will give us..

http://myproject/css/style.css

These methods are already very handy, but Laravel takes this a step further by providing shorter helper methods which look great when used in our views. Here is a list of these helpers, and their longer alternatives.

| Helper          | Method                |
|-----------------|-----------------------|
| url()           | URL::to()             |
| asset()         | URL::to_asset()       |
| route()         | URL::to_route()       |
| action()        | URL::to_action()      |

Now that we can retrieve our site URLs, the next logical step would be to use them to create hyper-links. Now I know what you're thinking, we can do it like this..

<a href="<?php echo URL::to('my/page'); ?>">My Page</a>

Sure that would work, but it's a little ugly. In Laravel if something is a little ugly, there is always a better way of handling it. Links are no exception.

Why don't we use the HTML class to generate a link? After all, that's what the HTML class is for. It is used to generate all kinds of HTML tags.

<?php echo HTML::link('my/page', 'My Page'); ?>

That looks a lot better! Let's see the result.

<a href="http://myproject/my/page">My Page</a>

If you are an SEO ninja, and cannot stand to see a link without a title attribute, simply pass an extra array.

<?php echo HTML::link('my/page', 'My Page', array('title' => 'My page!')); ?>

Which gives..

<a href="http://myproject/my/page" title="My page!">My Page</a>

One of the great features of Laravel is how consistent its method naming is. Many of the HTML::link methods follow a similar naming pattern as the URL::to methods, which makes them easy to remember. Let's take a look at how we can link to a secure page (via HTTPS).

<?php

HTML::link_to_secure('my/page', 'My Page');
// <a href="https://myproject/my/page">My Page</a>

We can also use link_to_route to create a link to a named route just like we did with the URL library.

<?php

HTML::link_to_route('login', 'Login!');
// <a href="http://myproject/login/page">Login!</a>

Once again we can use the link_to_action() method to link to a controller-action pair, for example..

<?php

HTML::link_to_action('account@login', 'Login!');
// <a href="http://myproject/account/login">Login!</a>

Laravel even gives us a method of easily creating 'mailto' links from an email address. Let's take a look.

<?php

HTML::mailto('me@daylerees.com', 'Mail me!');
// <a href="mailto:me@daylerees.com">Mail me!</a>

Nice and clean!

Now that you know how to create URL's and links, your applications will start to grow in size, covering many routes until they consume our planet and take over the unive...

Your applications will be a lot more interesting!

My books are available online for free to encourage learning. However, if you'd like for me to keep writing, then please consider buying a digital copy over at Leanpub.com.

It's available in PDF, ePub, and Kindle format, and contains a bunch of extras that you won't find on the site. I have a full-time job, and I write my books in my spare time. Please consider buying a copy so that I can continue to write new books from the comfort of my sofa!