function url

You are here

7 common.inc url($path = NULL, array $options = 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, $query = NULL, $fragment = NULL, $absolute = FALSE)
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.

... See full list

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.

... See full list

File

includes/common.inc, line 1468
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

Do 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.css
That'll happen if you have modules like i18n or Spaces enabled and configured to use path prefixes.

See: http://drupal.org/node/872340

anything 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 outputs:
'user/register?gids[]=6/' which actually is wrong I say.

D6 6.22

When 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.