| 7 common.inc | url($path = NULL, array |
| 4.6 common.inc | url($path = NULL, $query = NULL, $fragment = NULL, $absolute = FALSE) |
| 4.7 common.inc | url($path = NULL, $query = NULL, $fragment = NULL, $absolute = FALSE) |
| 5 common.inc | url($path = NULL, |
| 6 common.inc | url($path = NULL, $options = array()) |
| 8 common.inc | url($path = NULL, array $options = array()) |
Generates an internal or external URL.
When creating links in modules, consider whether l() could be a better alternative than url().
Parameters
$path: (optional) The internal path or external URL being linked to, such as "node/34" or "http://example.com/foo". The default value is equivalent to passing in '<front>'. A few notes:
- If you provide a full URL, it will be considered an external URL.
- If you provide only the path (e.g. "node/34"), it will be considered an internal link. In this case, it should be a system URL, and it will be replaced with the alias, if one exists. Additional query arguments for internal paths must be supplied in $options['query'], not included in $path.
- If you provide an internal path and $options['alias'] is set to TRUE, the path is assumed already to be the correct path alias, and the alias is not looked up.
- The special string '<front>' generates a link to the site's base URL.
- If your external URL contains a query (e.g. http://example.com/foo?a=b), then you can either URL encode the query keys and values yourself and include them in $path, or use $options['query'] to let this function URL encode them.
$options: (optional) An associative array of additional options, with the following elements:
- 'query': A URL-encoded query string to append to the link, or an array of query key/value-pairs without any URL-encoding.
- 'fragment': A fragment identifier (named anchor) to append to the URL. Do not include the leading '#' character.
- 'absolute' (default FALSE): Whether to force the output to be an absolute link (beginning with http:). Useful for links that will be displayed outside the site, such as in an RSS feed.
- 'alias' (default FALSE): Whether the given path is a URL alias already.
- 'external': Whether the given path is an external URL.
- 'language': An optional language object. Used to build the URL to link to and look up the proper alias for the link.
- 'base_url': Only used internally, to modify the base URL when a language dependent URL requires so.
- 'prefix': Only used internally, to modify the path when a language dependent URL requires so.
Return value
A string containing a URL to the given path.
140 calls to url()
- aggregator_admin_settings in modules/
aggregator/ aggregator.admin.inc - Form builder; Configure the aggregator system.
- aggregator_block in modules/
aggregator/ aggregator.module - Implementation of hook_block().
- aggregator_form_feed in modules/
aggregator/ aggregator.admin.inc - Form builder; Generate a form to add/edit feed sources.
- aggregator_help in modules/
aggregator/ aggregator.module - Implementation of hook_help().
- aggregator_page_categories in modules/
aggregator/ aggregator.pages.inc - Menu callback; displays all the categories used by the aggregator.
27 string references to 'url'
- aggregator_form_feed in modules/
aggregator/ aggregator.admin.inc - Form builder; Generate a form to add/edit feed sources.
- aggregator_form_feed_validate in modules/
aggregator/ aggregator.admin.inc - Validate aggregator_form_feed form submissions.
- aggregator_parse_feed in modules/
aggregator/ aggregator.module - Parse a feed and store its items.
- aggregator_refresh in modules/
aggregator/ aggregator.module - Checks a news feed for new items.
- aggregator_save_feed in modules/
aggregator/ aggregator.module - Add/edit/delete an aggregator feed.
File
- includes/
common.inc, line 1467 - Common functions that many Drupal modules will need to reference.
Code
function url($path = NULL, $options = array()) {
// Merge in defaults.
$options += array(
'fragment' => '',
'query' => '',
'absolute' => FALSE,
'alias' => FALSE,
'prefix' => '',
);
if (!isset($options['external'])) {
// Return an external link if $path contains an allowed absolute URL.
// Only call the slow filter_xss_bad_protocol if $path contains a ':' before
// any / ? or #.
$colonpos = strpos($path, ':');
$options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && filter_xss_bad_protocol($path, FALSE) == check_plain($path));
}
// May need language dependent rewriting if language.inc is present.
if (function_exists('language_url_rewrite')) {
language_url_rewrite($path, $options);
}
if ($options['fragment']) {
$options['fragment'] = '#' . $options['fragment'];
}
if (is_array($options['query'])) {
$options['query'] = drupal_query_string_encode($options['query']);
}
if ($options['external']) {
// Split off the fragment.
if (strpos($path, '#') !== FALSE) {
list($path, $old_fragment) = explode('#', $path, 2);
if (isset($old_fragment) && !$options['fragment']) {
$options['fragment'] = '#' . $old_fragment;
}
}
// Append the query.
if ($options['query']) {
$path .= (strpos($path, '?') !== FALSE ? '&' : '?') . $options['query'];
}
// Reassemble.
return $path . $options['fragment'];
}
global $base_url;
static $script;
if (!isset($script)) {
// On some web servers, such as IIS, we can't omit "index.php". So, we
// generate "index.php?q=foo" instead of "?q=foo" on anything that is not
// Apache.
$script = (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') === FALSE) ? 'index.php' : '';
}
if (!isset($options['base_url'])) {
// The base_url might be rewritten from the language rewrite in domain mode.
$options['base_url'] = $base_url;
}
// Preserve the original path before aliasing.
$original_path = $path;
// The special path '<front>' links to the default front page.
if ($path == '<front>') {
$path = '';
}
elseif (!empty($path) && !$options['alias']) {
$path = drupal_get_path_alias($path, isset($options['language']) ? $options['language']->language : '');
}
if (function_exists('custom_url_rewrite_outbound')) {
// Modules may alter outbound links by reference.
custom_url_rewrite_outbound($path, $options, $original_path);
}
$base = $options['absolute'] ? $options['base_url'] . '/' : base_path();
$prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
$path = drupal_urlencode($prefix . $path);
if (variable_get('clean_url', '0')) {
// With Clean URLs.
if ($options['query']) {
return $base . $path . '?' . $options['query'] . $options['fragment'];
}
else {
return $base . $path . $options['fragment'];
}
}
else {
// Without Clean URLs.
$variables = array();
if (!empty($path)) {
$variables[] = 'q=' . $path;
}
if (!empty($options['query'])) {
$variables[] = $options['query'];
}
if ($query = join('&', $variables)) {
return $base . $script . '?' . $query . $options['fragment'];
}
else {
return $base . $options['fragment'];
}
}
}
Comments
Don't use url() to generate JS and CSS paths
PermalinkDo not use url() to generate JS and CSS paths. Because of this fragment:
if (function_exists('custom_url_rewrite_outbound')) {// Modules may alter outbound links by reference.
custom_url_rewrite_outbound($path, $options, $original_path);
}
if you call e.g.:
url('modules/node/node.css');you'll get e.g.:
/prefix/modules/node/node.cssThat'll happen if you have modules like i18n or Spaces enabled and configured to use path prefixes.
See: http://drupal.org/node/872340
use the query option to pass variables in your link
Permalinkanything after the ? is a variable to include in the query.
THIS IS WRONG:
url("user/register?gids[]=$node->nid", array('absolute' => TRUE))outputs incorrect:
user/register%3Fgids%5B%5D%3D6
THIS IS RIGHT:
url("user/register", array('query' => 'gids[]='. $node->nid,'absolute' => TRUE))which outputs the correct:
user/register?gids[]=6
Dave Shaw
Tribe Rising
To me it
PermalinkTo me it outputs:
'user/register?gids[]=6/' which actually is wrong I say.
D6 6.22
ampersands are double encoded
PermalinkWhen you use a link or file name that has an ampersand (&), url() or l() will double-encode the ampersand to %2526. It is because of drupal_urlencode() trying to compensate for Apache's mod_rewrite's behavior. I see good intention but it's not the ideal place to accomplish this. I believe it is not the case for D7 or 8. See drupal_urlencode() for the few other cases that are double-encoded.
It is especially problematic when you use url() or l() to create a link to a static file that has an ampersand in the file name.