l() is a function that is available anywhere within a Drupal installation. It accepts three arguments:
- $text: The text that will be visible to users for your link
- $path: The URL that the link will go to when clicked.
- $options: An associative array which allows you to set additional parameters to further customize the link with CSS classes etc… It is here that you would need to establish that the link will be an image if you so desire (I’ll go into this later). The $options array is optional.
l($text, $path, $options = array())
Specifying Anchor Tag Attributes
Two common anchor tag attributes are class and target. Here's how we add them to the previous example:<?php
$attributes = array( 'class' => 'foo', 'target' => '_blank' );
$link = l('Permalink', 'node/1', $attributes);
?>Linking to Images
The function's default action assumes that $text is pure text, not HTML. If < and > are present they're automatically converted into < and >. If you're linking an image you need the HTML so set the $html parameter TRUE. As you'll see in the l function's full description the $html parameter is the last of seven parameters, so you need to specify all of the preceding parameters. This call would therefore look something like:<?php
$image = '<img src="…" alt="Alternative Text" />';
$link = l($image, $url, array(), NULL, NULL, FALSE, TRUE);
?>How to create an image based link using the l() function for Drupal
The $text section of the l() function accepts any text so this text could be html and therefore could be an image. However by default it filters out html unless you tell it otherwise. To tell the l() function to accept html for its text you need to build the $options array and pass it as an argument. $options = array(
'attributes' => array(),
'html' => TRUE,
);
l('<img src="/images/path-to-image.png" />', 'node/1', $options);
'attributes' => array(),
'html' => TRUE,
);
l('<img src="/images/path-to-image.png" />', 'node/1', $options);
<?php
l('Very thin abstraction layer', 'node/11554', array('fragment' => 'comment-37717', 'class' => 'active'); // really you don't need the class set to active, because l() adds class="active" by default.?><?php
l('Very thin abstraction layer', 'node/11554', array('fragment' => 'comment-37717', 'target' => _blank); ?><?php
l('Very thin abstraction layer', 'node/11554', array('fragment' => 'comment-37717', 'attributes' => array('class' => 'active', 'target' => '_blank'));> // really you don't need the class set to active, because l() adds class="active" by default.?>Example with custom class, attributes
Posted by chriscohen on September 17, 2009 at 9:24am
This will produce a link with the class="widelink" and rel="lightbox" attributes on the a tag.<?php
l(
t('My link'),
'node/56',
array(
'attributes' => array(
'class' => 'widelink',
'rel' => 'lightbox',
)
)
);?>how to prevent l() from screwing up an ubercart purchase link
Posted by bsenftner on January 6, 2010 at 12:45am
In porting a D5 site to D6, I found within their Ubercart logic they are generating a purchase item image-link like this:
The problem is the l() function is supposed to generate this:
but is generating this incorrect link with character encoding rather than '?' and '=' characters:
Apparently, the D5 l() function does not do that same character encoding, and was not an issue... So here's the fix for D6:
The solution being to place the query string portion of the link into a 'query' attribute.
$buy_img = theme_image('sites/all/themes/customTheme/images/buy.png', 'BUY', 'Buy The' . check_plain($node->title), array('class' => 'coins'));
$buy_link = 'cart/add/e-p' . $node->nid . '_q1_m0?destination=cart/checkout';
print l( $buy_img, $buy_link, array('html' => true) );http://localhost/cart/add/e-p176_q1_m0?destination=cart/checkouthttp://localhost/cart/add/e-p176_q1_m0%3Fdestination%3Dcart/checkout $buy_link = 'cart/add/e-p' . $node->nid . '_q1_m0';
print l( $buy_img, $buy_link, array('html' => true, 'query' => 'destination=cart/checkout') );Add permissions to view links
Posted by cbearhoney on March 16, 2010 at 3:15pm
I thought this was helpful...
Used in blog module function blog_page_last
if (user_access('create blog entries')) {
$items[] = l(t('Create new blog entry.'), "node/add/blog");
}Internal Module Links
Posted by whoisrich on March 25, 2010 at 9:25pm
To clarify for those who want their module to support the 'Clean URLs' option.
returns a link complete with
If you need a link without the
<?php
$var = l("Click Text", "ModuleName");?>returns a link complete with
<a href= tags. For a link that goes with your hook_menu() and 'page arguments' you just add the arguments to the path.<?php
$var = l("Click Text", "ModuleName/value/value");?><a href= tags use 'url' instead.<?php
$var = url("ModuleName/value/value")?>Examples
Posted by dotpex on May 17, 2010 at 1:21pm
Various implementation of l() function
simple:
with class:
link to user:
Always use user/user id!!! simple link with image:
complex link with image:
simple:
<?php
l(t('Link text'), 'about-us');?><?php
l(t('Link text'), 'about-us', array('attributes' => array('class' => 'about-link')));?><?php
l(t($user->name), 'user/'.$user->uid, array('attributes' => array('class' => 'link', 'id' => 'xxx', 'title' => 'Title')));?>Always use user/user id!!! simple link with image:
<?php
$img = '<img src="'.$base_path . $directory . '/images/rssIcon.png" />';
l($img, 'user/3', array('html' => array('html' => 'true')));
// also valid
l($img, 'user/3', array('html' => 'true'));?><?php
l($img, 'user/3', array('attributes' => array('class' => 'link', 'id' => 'xxx', 'title' => 'Title'), 'html' => 'true'));?>Some of those examples
Posted by zeropaper on July 1, 2010 at 4:04pm
*might* lead to security issues.. (I mean... sure I did some of those mistakes... back in the days... :) )
the l() function sanitize the first argument (the text) when the option "html" isn't TRUE...
it means that you need to really take care about what the first argument will be if using the "html" option
For example:
Just a note..
if you need to have a variable in a translation.. like it might have been the case in the example
or...
anyway, it was nice from you to help!
the l() function sanitize the first argument (the text) when the option "html" isn't TRUE...
it means that you need to really take care about what the first argument will be if using the "html" option
For example:
<?php// making an img tag like might not be the safest solution
//$img = '<img src="'.$base_path . $directory . '/images/rssIcon.png" />';
// this would be much better, but still, you need to know that the $directory variable is also safe$img = theme('image', $directory .'/images/rssIcon.png');// this is, I think, not possible...
//l($img, 'user/3', array('html' => array('html' => 'true')));
// is okl($img, 'user/3', array('html' => 'true'));?><?php// well, stop me if I am wrong, but I guess might be useful to wrap $user->name within t()..
//l(t($user->name), 'user/'.$user->uid, array('attributes' => array('class' => 'link', 'id' => 'xxx', 'title' => 'Title')));
// Something who might be handy if you need to "define" an HTML id is the form_clean_id()
// it will prevent to have twice the same id in the HTML (which is bad :) )l($user->name, 'user/'.$user->uid, array('attributes' => array('class' => 'link', 'id' => form_clean_id('xxx'), 'title' => 'Title')));?>if you need to have a variable in a translation.. like it might have been the case in the example
<?php
l(t('Some string related to @user_name', array('@user_name' => $user->name)), 'user/'. $user->uid);// I might explain why it might be better to use @user_name over a simple @user... but it's not the topic ;)?>or...
<?php
theme('username', $user);// whatever.. ?>in $options you forget to
Posted by sobi3ch on May 31, 2010 at 1:13pm
'boxes' table in database
Posted by nirmal_george on June 16, 2010 at 2:41pm
link -localized_options-query
Posted by seansies on July 3, 2010 at 7:53pm
I'm using ThemeKey to change the theme on a series of pages on my website that have a completely different theme from the rest of the site -- based on a parameter appended to the url. Some of these pages are nodes that must be able to be updated from the subtheme side, as well as the main theme. So I’m trying to hook into the menu_item_link in template.php, but it doesn’t like my code. I copied the applicable snippet from the zen theme template php, and modified it as below for my zen_dis sub theme -- It still seems to be looking at the main Zen theme for this option, though – how do I phrase the Hook_ language to force it to use this?:
function zen_dis_menu_item_link($link) {
if (empty($link['localized_options'])) {
$link['localized_options'] = array();
}
// If an item is a LOCAL TASK, render it as a tab
if ($link['type'] & MENU_IS_LOCAL_TASK) {
$link['title'] = '' . check_plain($link['title']) . '';
$link['localized_options']['query'] = '?dis-site-search-organization';
$link['localized_options']['html'] = TRUE;
}
return l($link['title'], $link['href'], $link['localized_options']);
}
function zen_dis_menu_item_link($link) {
if (empty($link['localized_options'])) {
$link['localized_options'] = array();
}
// If an item is a LOCAL TASK, render it as a tab
if ($link['type'] & MENU_IS_LOCAL_TASK) {
$link['title'] = '' . check_plain($link['title']) . '';
$link['localized_options']['query'] = '?dis-site-search-organization';
$link['localized_options']['html'] = TRUE;
}
return l($link['title'], $link['href'], $link['localized_options']);
}
For Drupal6
Posted by bloom on August 19, 2010 at 8:52am
If you look at the description of the function in Drupal 6 parameters you will find under $options:
So I made the following changes as the user described above and it worked:
Additional $options elements used by the url() function.But I was not able to put additional parameters into URL in this case:
print l("Click here", $internal_path, array(
'listing_url' => 'data'
));print l("Click here", $internal_path, array(
'query' => array(
'listing_url' => 'data'
),
));Class Active
Posted by modesia on August 25, 2010 at 6:33pm
Hi,
I've tried experimenting with this function in order to append the class="active". It works great with the internal path (node/#), but if I supply the url alias it doesn't seem to work.
I've tried this way :
Maybe I'm doing this wrong. Any thoughts?
Regards
I've tried experimenting with this function in order to append the class="active". It works great with the internal path (node/#), but if I supply the url alias it doesn't seem to work.
I've tried this way :
<?php
print l(t('Link Text'),'my-url-alias',array('alias' => 'TRUE')); ?>Regards
Link to #
Posted by 8837 on October 8, 2010 at 3:08pm
Title and Alt attributes are sanitized
Posted by NancyDru on September 20, 2010 at 6:44pm
Actually all the "attributes" values are sanitized in
drupal_attributes, so if you do anything to sanitize it yourself, you can end up double encoding. For example, l($title, $path, array('attributes' => array('title' => t('All about @names', array('@names' => 'Adam & Eve'))))) will result in the ampersand being double encoded. In this example, it is okay to use '!names' because drupal_attributes will do a check_plain for you.Can't figure out how to
Posted by yngens on December 26, 2010 at 9:37pm
Can't figure out how to combine attributes and fragment, since I need both - the first one to apply a class, second one to generate proper URI to the comment. What is wrong in my code below?
<?php
$block_content .= l(t('Conversate'), "node/$links->nid", array('attributes'=>array('class'=>'comment')), array('fragment' => "comment-$links->cid")).'</div>';?>
Links to an anchor, or hash-only links
l('linktext', '', array('fragment' => 'namedanchor', 'external' => TRUE));to create a hash-only link (to #) you'll need to adapt it to:
l('linktext', '', array('fragment' => ' ', 'external' => TRUE));(note that fragment does contains a space.)