Overview
ex_url is a library modelled on the Elixir URI module. It parses and formats URL's with the additional function that is parses the scheme-specific payload of known URI schemes. At present it can parse:
The basic API is URL.new/1. The function URL.to_string/1 is delegated to the URI module.
Of course these are really URI's, not URL's but its a reasonable choice of name given that WHATWG prefers URL over URI:
Standardize on the term URL. URI and IRI [Internationalized Resource Identifier] are just confusing. In practice a single algorithm is used for both so keeping them distinct is not helping anyone. URL also easily wins the search result popularity contest
Examples
Parse a geo URL:
iex> URL.new("geo:48.198634,-16.371648,3.4;crs=wgs84;u=40.0")
{:ok,
%URL{
authority: nil,
fragment: nil,
host: nil,
parsed_path: %URL.Geo{
alt: 3.4,
lat: 48.198634,
lng: -16.371648,
params: %{"crs" => "wgs84", "u" => 40.0}
},
path: "48.198634,-16.371648,3.4;crs=wgs84;u=40.0",
port: nil,
query: nil,
scheme: "geo",
userinfo: nil
}
}Parse a tel URL:
iex> URL.new("tel:+61-0407-555-987")
{:ok,
%URL{
authority: nil,
fragment: nil,
host: nil,
parsed_path: %URL.Tel{params: %{}, tel: "+61 407 555 987"},
path: "+61-0407-555-987",
port: nil,
query: nil,
scheme: "tel",
userinfo: nil
}
}
# When the parameter "phone-context" is also a valid number then it is prepended before formatting
iex> tel = URL.new "tel:0407-555-987;phone-context=+61"
{:ok,
%URL{
authority: nil,
fragment: nil,
host: nil,
parsed_path: %URL.Tel{
params: %{"phone-context" => "+61"},
tel: "+61 407 555 987"
},
path: "0407-555-987;phone-context=+61",
port: nil,
query: nil,
scheme: "tel",
userinfo: nil
}
}Parse a data URL:
This first example shows the treatment of data that is base64 encoded. It is decoded by URL.Data.parse/1.
iex> URL.new("data:;base64,SGVsbG8gV29ybGQh")
{:ok,
%URL{
authority: nil,
fragment: nil,
host: nil,
parsed_path: %URL.Data{
data: "Hello World!",
mediatype: "text/plain",
params: %{"encoding" => "base64"}
},
path: ";base64,SGVsbG8gV29ybGQh",
port: nil,
query: nil,
scheme: "data",
userinfo: nil
}
}This second example shows the treatment of data that is not marked as base64 encoded. In this case it is considered to be percent-encoded. It is also decoded during parsing.
iex> URL.new("data:,Hello%20World%21")
{:ok,
%URL{
authority: nil,
fragment: nil,
host: nil,
parsed_path: %URL.Data{
data: "Hello World!",
mediatype: "text/plain",
params: %{}
},
path: ",Hello%20World%21",
port: nil,
query: nil,
scheme: "data",
userinfo: nil
}
}Parse a mailto URL
A mailto URL will be parsed and percent encoding will be decoded. Note that RFC2047 encoded-words is not currently supported.
iex> URL.new("mailto:infobot@example.com?subject=current-issue")
{:ok,
%URL{
authority: nil,
fragment: nil,
host: nil,
parsed_path: %URL.Mailto{
params: %{"subject" => "current-issue"},
to: ["infobot@example.com"]
},
path: "infobot@example.com",
port: nil,
query: "subject=current-issue",
scheme: "mailto",
userinfo: nil
}
}Parse a uuid URL
iex> URL.new("uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6;a=b")
{:ok,
%URL{
authority: nil,
fragment: nil,
host: nil,
parsed_path: %URL.UUID{
params: %{"a" => "b"},
uuid: "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
},
path: "f81d4fae-7dec-11d0-a765-00a0c91e6bf6;a=b",
port: nil,
query: nil,
scheme: "uuid",
userinfo: nil
}
}Configuration
Configure :ex_url in mix.exs:
defp deps do
[
{:ex_url, "~> 2.0"},
...
]
endIf configured in mix.exs, URL will use the following libraries:
ex_phone_number will be used to parse and format telephone numbers defined in the
telURI scheme. Numbers it cannot parse are kept as written.localize and gettext will be used to determine the current locale and therefore the current territory (country) for parsing and formatting telephone numbers that don't have a country code supplied. The
localizelocale is consulted first, then thegettextlocale, then"US".
localize requires the :json module that ships with OTP 27 and later. On OTP 26, also add {:json_polyfill, "~> 0.2 or ~> 1.0"} to your dependencies.
Optional configuration in mix.exs:
defp deps do
[
# Required
{:ex_url, "~> 2.0"},
# Optional
{:ex_phone_number, "~> 0.1"},
{:localize, "~> 1.2"},
{:gettext, "~> 0.13"}
...
]
endCopyright and License
Copyright 2018-2026 Kip Cole
See LICENCE.md for the licence terms.