4.6.x common.inc l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE)
4.7.x common.inc l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE)
5.x common.inc l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE)
6.x common.inc l($text, $path, $options = array())
7.x common.inc l($text, $path, array $options = array())

Formats an internal or external URL link as an HTML anchor tag.

This function correctly handles aliased paths and adds an 'active' class attribute to links that point to the current page (for theming), so all internal links output by modules should be generated by this function if possible.

However, for links enclosed in translatable text you should use t() and embed the HTML anchor tag directly in the translated string. For example:

t('Visit the <a href="@url">settings</a> page', array('@url' => url('admin')));

This keeps the context of the link title ('settings' in the example) for translators.


string $text: The translated link text for the anchor tag.

string $path: The internal path or external URL being linked to, such as "node/34" or "http://example.com/foo". After the url() function is called to construct the URL from $path and $options, the resulting URL is passed through check_plain() before it is inserted into the HTML anchor tag, to ensure well-formed HTML. See url() for more information and notes.

array $options: An associative array of additional options. Defaults to an empty array. It may contain the following elements.

  • 'attributes': An associative array of HTML attributes to apply to the anchor tag. If element 'class' is included, it must be an array; 'title' must be a string; other elements are more flexible, as they just need to work in a call to drupal_attributes($options['attributes']).
  • 'html' (default FALSE): Whether $text is HTML or just plain-text. For example, to make an image tag into a link, this must be set to TRUE, or you will see the escaped HTML image tag. $text is not sanitized if 'html' is TRUE. The calling function must ensure that $text is already safe.
  • 'language': An optional language object. If the path being linked to is internal to the site, $options['language'] is used to determine whether the link is "active", or pointing to the current page (the language as well as the path must match). This element is also used by url().
  • Additional $options elements used by the url() function.

Return value

string An HTML string containing a link to the given path.

See also


141 calls to l()
actions_synchronize in includes/actions.inc
Synchronizes actions that are provided by modules in hook_action_info().
aggregator_form_category_submit in modules/aggregator/aggregator.admin.inc
Form submission handler for aggregator_form_category().
aggregator_form_feed_submit in modules/aggregator/aggregator.admin.inc
Form submission handler for aggregator_form_feed().
aggregator_view in modules/aggregator/aggregator.admin.inc
Displays the aggregator administration page.
authorize.php in ./authorize.php
Administrative script for running authorized file operations.

... See full list

2 string references to 'l'
FieldTranslationsTestCase::setUp in modules/field/tests/field.test
Set the default field storage backend for fields created during tests.
LocaleTranslationFunctionalTest::testJavaScriptTranslation in modules/locale/locale.test


includes/common.inc, line 2490
Common functions that many Drupal modules will need to reference.


function l($text, $path, array $options = array()) {
  global $language_url;
  static $use_theme = NULL;

  // Merge in defaults.
  $options += array(
    'attributes' => array(),
    'html' => FALSE,

  // Append active class.
  if (($path == $_GET['q'] || ($path == '<front>' && drupal_is_front_page())) && 
    (empty($options['language']) || $options['language']->language == $language_url->language)) {
    $options['attributes']['class'][] = 'active';

  // Remove all HTML and PHP tags from a tooltip. For best performance, we act only
  // if a quick strpos() pre-check gave a suspicion (because strip_tags() is expensive).
  if (isset($options['attributes']['title']) && strpos($options['attributes']['title'], '<') !== FALSE) {
    $options['attributes']['title'] = strip_tags($options['attributes']['title']);

  // Determine if rendering of the link is to be done with a theme function
  // or the inline default. Inline is faster, but if the theme system has been
  // loaded and a module or theme implements a preprocess or process function
  // or overrides the theme_link() function, then invoke theme(). Preliminary
  // benchmarks indicate that invoking theme() can slow down the l() function
  // by 20% or more, and that some of the link-heavy Drupal pages spend more
  // than 10% of the total page request time in the l() function.
  if (!isset($use_theme) && function_exists('theme')) {
    // Allow edge cases to prevent theme initialization and force inline link
    // rendering.
    if (variable_get('theme_link', TRUE)) {
      $registry = theme_get_registry(FALSE);
      // We don't want to duplicate functionality that's in theme(), so any
      // hint of a module or theme doing anything at all special with the 'link'
      // theme hook should simply result in theme() being called. This includes
      // the overriding of theme_link() with an alternate function or template,
      // the presence of preprocess or process functions, or the presence of
      // include files.
      $use_theme = !isset($registry['link']['function']) || ($registry['link']['function'] != 'theme_link');
      $use_theme = $use_theme || !empty($registry['link']['preprocess functions']) || !empty($registry['link']['process functions']) || !empty($registry['link']['includes']);
    else {
      $use_theme = FALSE;
  if ($use_theme) {
    return theme('link', array('text' => $text, 'path' => $path, 'options' => $options));
  // The result of url() is a plain-text URL. Because we are using it here
  // in an HTML argument context, we need to encode it properly.
  return '<a href="' . check_plain(url($path, $options)) . '"' . drupal_attributes($options['attributes']) . '>' . ($options['html'] ? $text : check_plain($text)) . '</a>';


tanoshimi’s picture

Note that to attach a class to a link via the $attributes array, then the class element itself must also be an array (even if it contains a single element)

In other words, Drupal 6.x:

  l(t('Link text'), 'about-us', array('attributes' => array('class' => 'about-link')));

Drupal 7.x:

  l(t('Link text'), 'about-us', array('attributes' => array('class' => array('about-link'))));
johnvsc’s picture

that multiple classes would be this:

  l(t('Link text'), 'about-us', array('attributes' => array('class' => array('about-link','another-class'))));
rjbrown99’s picture

Nope, multiple classes seems to be this - one array key, multiple values separated by a space.

  l(t('Link text'), 'about-us', array('attributes' => array('class' => 'about-link another-class')));
paul2’s picture

So that is correct for D6, @rjbrown99, but in D7 the 'class' attribute value must be an array (see the $options parameter explained above). Just see how l() manipulates the 'class' attribute in the function body above; that code will break if you pass a string as you suggested.


  l(t('Link text'), 'about-us', array('attributes' => array('class' => 'about-link another-class')));


  l(t('Link text'), 'about-us', array('attributes' => array('class' => array('about-link', 'another-class'))));
peter.hellerhoff’s picture

What's so perfidious about this is that something like

                    $options = array(
                        'attributes' => array (
                            'class' => 'my_class',
                    print l($mytitle,$myhref,$options);

seems to work in the first moment. But then if you click the link you will get:

Fatal error: [] operator not supported for strings in \includes\common.inc on line 2426

The function l tries to add the class "active" to the array(!) $options['attributes']['class'].

I suggest to make the function l more robust by adding the following lines:

  if (is_string($options['attributes']['class']))
    $options['attributes']['class'] = explode(" ",$options['attributes']['class']);

And therby convert the string to an array. This would allow to submit even multiple classes as a space separated string, as one would write the class attribute directly into the html tag:

                        'attributes' => array (
                            'class' => 'my_class1 my_class2',

Going the correct way via the array would still be possible.

peter.hellerhoff’s picture

Sorry, to avoid warnings, the suggested lines should read:

  if (isset($options['attributes']['class']) && is_string($options['attributes']['class']))
    $options['attributes']['class'] = explode(" ",$options['attributes']['class']);
thedavidmeister’s picture

There is no use commenting here about proposed changes, if you want to change the way that l() works you need to open a ticket in the core issue queue and submit a patch that can be run through our standard QA processes.

sirkitree’s picture

Most of the time an ajax link is just a fragment:

In order to accomplish this, use the 'fragment' in $options. ex:

l(t('Refresh'), '', array('attributes' => array('id' => 'refresh-link-id', 'class' => 'refresh-link'), 'fragment' => 'refresh'));

This will output the following:

<a href="/#refresh" id="refresh-link-id" class="refresh-link">Refresh</a>
Rob230’s picture

Your example will make the link point to the homepage with a fragment. If you want to point to the current page you can pass in external, which will cause url() to do nothing with the path.


l(t('Refresh'), '', array(
  'attributes' => array(
    'id' => 'refresh-link-id',
    'class' => 'refresh-link'
  'fragment' => 'refresh'),
  'external' => TRUE,

This will output:

<a href="#refresh" id="refresh-link-id" class="refresh-link">Refresh</a>

farse’s picture

typo in the code, should be:

l(t('Refresh'), '',
'attributes' => array(
'id' => 'refresh-link-id',
'class' => 'refresh-link'
'fragment' => 'refresh',
'external' => TRUE,)

jayhawkfan75’s picture

This works great. Thank you farse!

MichaelCole’s picture

l(t('View Map & Directions'), $map_address_url, array('attributes' => array('target'=>'_blank')))

Karol Haltenberger’s picture

e.g. if url points to a page with a form, you'll be redirected to destination url

l('Title', 'url', array('query' => array('destination' => 'destination_url')))

This creates:

<a href="url?destination=destination_url">Title</a>
MD3’s picture

This was a total life saver! Thanks for the tip!

yurtboy’s picture

would this be here but then above it tells you to use the url function for this? Uhg. Glad I scrolled down to find the "wrong" way to do it.

borgo’s picture

Combination of the above.

        global $base_url;

        print l(
          $base_url . $node_url, 
              'attributes' => array(
                'id' => 'my-id', 
                'class' => 'my-class'
              'query' => array(
                'foo' => 'bar'
              'fragment' => 'refresh',
              'html' => TRUE


<a href="http://www.example.com/node/1?foo=bar#refresh" id="my-id" class="my-class"><img src="http://www.example.com/files/image.jpg"/></a>
crossfish’s picture

Now that's what I call a great comment. Shows the what/how and the final output. Thanks borgo!

batigolix’s picture

borgo's code example contains an error, though

  'attributes' => array(
    'id' => 'my-id',
    'class' => 'my-class'

should read:

  'attributes' => array(
    'id' => 'my-id',
    'class' => array('my-class')

Classes must be placed in an array. See http://api.drupal.org/api/drupal/includes--common.inc/function/l/7#comme...

geerlingguy’s picture

If you want a simple anchor/fragment link (similar to what sirkitree said in the ajax links comment above), but with just the anchor (href="#namedanchor"), do something like the following:

l(t('My Anchor Link'), '', array(
  'fragment' => 'namedanchor',
  'external' => TRUE,
  'attributes' => array(
    'title' => 'Title here.'

This outputs:

<a href="#namedanchor" title="Title here.">My Anchor Link</a>

You cannot use the l() function to create a simple 'name' anchor, though (like <a name="namehere"></a>). For this, you'll need to create the link manually.

dcontard’s picture

You can still use the l() function to create a simple 'name' anchor with an empty href value. For this, just do the following:

l('', '', array(
//'fragment' => 'nameanchor',
'external' => TRUE,
'attributes' => array(
//'title' => 'Title here.',
'name' => 'nameanchor',

This generates:

&lt;a href=&quot;&quot; name=&quot;nameanchor&quot;&gt;&lt;/a&gt;

dcontard’s picture

Mmmm... yesterday in the preview, that last line showed in a different manner. It should look like this:

<a href="" name="nameanchor"></a>

Or this:

<a href="" name="nameanchor"></a>

googlg’s picture

geerlingguy if i want to output such HTML:


what the l() function should like ? Thanks.

grip media’s picture

After hours of searching on this, it was the "external" attribute that needed to be added!

chenxing678’s picture

How about ''

FOOLVER’s picture

here is a hint to link to javascript:void(0)

l($text,'javascript:void(0)',array('fragment' => '','external'=>true));

ishmael-sanchez’s picture

Change field and style name to suit your needs.

 l(theme_image_style(array('path' => $variables['node']->field_logo['und']['0']['uri'], 'style_name' => '100x100')), 'node/' . $variables['node']->nid, array('html' => TRUE));
ronrons’s picture

You can use this as well.

$image = array(
  'style_name' => '100x100',
  'path' => $variables['node']->field_logo['und']['0']['uri'], 
  'alt' => '',
  'title' => '',
  'attributes' => array('class' => 'logo-class')
print l(theme('image_style', $image), 'node/' . $variables['node']->nid, array('html' => TRUE));
vertikal.dk’s picture

If you want to link to a local anchor (# on the same page), it requires a bit of tweaking. Using an empty path will lead to the root of the site, so you need to pump in the current path using $_GET['q'].

This example will create a local link to the comments section of a node:
$link = l(t('Comments'), $_GET['q'], array('fragment' => 'comments'));

In a node located on the address http://mysite.tld/my_node this will output http://mysite.tld/my_node#comments


Anly Dcouth’s picture

U Can provide the desired link and can redirect it to your desired page in a form by providing,

$form['name']['link'] = array (
'#type' => 'item',
'#markup' => l('ur desired text', 'ur destination url'),
dis works well in my website..!

jeremymcminn’s picture

How would I change Edit into img src?

l(t('Edit'), 'node/' . $node->nid . '/webform/components/' . $cid, array('query' => drupal_get_destination())),

peter.hellerhoff’s picture

You would have to set the option html to TRUE

print l(   
    'node/' . $node->nid . '/webform/components/' . $cid, 
        'query' => drupal_get_destination(),
        'html' => true,
jasom’s picture

My solution for user avatar in sitebar block. This is code from my block template:

print l(  
    'user/' . $user->uid,
        'html' => true,
        'attributes' => array(
          'title' => $user->name . '\'s account',
          'class' => 'user-picture'

This is in my template.php

function themename_preprocess_block (&$variables) {
        if ($variables['logged_in']) {
        $user = user_load($variables['user']->uid);
        if ($user->picture){
        $variables['user_avatar'] = theme_image_style(
                                'style_name' => 'thumbnail',
                                'path' =>$user->picture->uri,
                                'attributes' => array('class' => 'user-picture'),
                                'width' => '100',
                                'height' => '100',
                                'alt' => $user->name . '\'s avatar',
                                'title' => $user->name . '\'s avatar',
            $variables['user_avatar'] =  '<a title="Profile" href=/user><img src="/sites/all/themes/uni7/avatar.png" /></a>';
        else {
            $variables['user_avatar'] = '<img src="/sites/all/themes/uni7/avatar.png" />';
mzwyssig’s picture

How could I pass parameters to a link ?

If i'm on the page /node/123, I'd like to create a link with an output such as /node/123?param=456. Having in mind that it should work on any node (by keeping the current page url).

Is there a "drupal way" or do I have to use pure PHP ?


sharathbabus’s picture

hello everyone,

Need your help in fixing this issue.
Below mentioned code is used in template.

  // echo $vars['node']->type; 

require_once 'librarypath/geoip.inc';
$gi = geoip_open("librarypath/GeoIP.dat",GEOIP_STANDARD);
$location = geoip_country_code_by_addr($gi, $_SERVER['REMOTE_ADDR']);

and my link is like this:
if($location == 'US') { echo 'pricing-others'; } else { echo 'pricing'; }">

I want to call the above hyperlink in my content page. how to call this. Kindly reply ASAP. This is bit urgent.

Thanks in advance....

sharathbabus’s picture

hello everyone,

Need your help in fixing this issue.
Below mentioned code is used in template.

  // echo $vars['node']->type; 

require_once 'librarypath/geoip.inc';
$gi = geoip_open("librarypath/GeoIP.dat",GEOIP_STANDARD);
$location = geoip_country_code_by_addr($gi, $_SERVER['REMOTE_ADDR']);

and my link is like this:

if($location == 'US') { echo 'pricing-others'; } else { echo 'pricing'; }">

I want to call the above hyperlink in my content page. how to call this. Kindly reply ASAP. This is bit urgent.

Thanks in advance....

zhilevan’s picture

I used l(t('mytext'),'path'); in block content with php format, i sured that the php code run correctly but dont get any result .

zhilevan’s picture

print  l(t('mytext'),'path'); 


quinns’s picture

Try this.

l('click here', 'node/123', array('query' => array('param' => 456)));
holtzermann17’s picture

This worked, where
l('click here', 'node/123?param=456');

timofey’s picture

I noticed a few have difficulties with destination.

Here's a proper way to do this:

$destination = drupal_get_destination();
l('Login', 'user/login', array('query' => array($destination)));

You'll notice that 'query' is not set to array('destination' => $destination); that's because drupal_get_destination() already returns an array. I.e. drupal_get_destination() = array('destination' => '/destination-path').

drupalshrek’s picture

  // The following produces a link such as ""  
  print l('', 'flipcard/start_set/' . $term->tid, array('html' => TRUE));
Ahmed_Samir’s picture

l( t('Refresh Page'), $path . '/getdata', array(
              'attributes' => array(
                'id' => '', 
                'class' => 'btn-small btn-primary '
              ),'query' => drupal_get_destination() , 'html' => TRUE)),
peter.hellerhoff’s picture

the line with class should rather be:

'class' => array('btn-small', 'btn-primary '),

See my posting above: http://api.drupal.org/comment/47838#comment-47838

patacra’s picture

I was wondering why the l() function removes all HTML and PHP tags in the title attribute.

The drupal_attributes() function called below will run all of the attributes across check_plain() which should do the job. This filtering seems unnecessary (CPU consuming) and may break the rendering of the desired tooltip.

What about if I would like to create a link with a tooltip such as this?

Pass over me

peter.hellerhoff’s picture

I would prefer doing this the old fashioned way:
title="&lt;&lt; This is not the best example &gt;&gt;"

Liam Morland’s picture

To create a link like this:
<a href="#id">Link</a>
Do this:

l('Link', NULL,  array('fragment' => 'id', 'external' => TRUE));
Fabianx’s picture

Even simpler:

l('Link', '#id',  array('external' => TRUE));

The advantage is that this allows also:

l('Link', '#',  array('external' => TRUE));

which does not work with the fragment solution :)

charles1988’s picture

<li class="email dividerpagetools" title="Email">
$link = "printmail/".$myQ;
$img = '<img title="Email" alt="Email" src="'. $themePath . '/images/mail.png" />';
$attributes = array('attributes' => array('class' => 'Prt'),'html' => true);
print l( $img, $link, $attributes);

hectorelgomez’s picture

You can create a back link with Drupal l function using javascript:

			$link_text = "previous page";
			$link_path = "javascript:history.back()";
			$d_link_previous_page_link =  l( t($link_text), $link_path,
				   array('attributes' =>
							'title' => t('previous page'),
joelbox-Mondial-IT’s picture


l('filename', file_create_url('public://dir_in_files_directory/filename'));