This plugin adds a new fieldtype to Craft for entering and validating international phone numbers, and getting information about those numbers. A Twig extension is also provided for extracting numbers from text.
It's built upon on the excellent libphonenumber-for-php port of Google's libphonenumber library.
- Field type for entering and validating international phone numbers.
- GraphQL support for both query and mutating phone number fields.
- Support for field and element condition rules.
- Twig filter for extracting number from text.
This plugin requires Craft CMS 5.0.0 or later.
You can install this plugin from the Plugin Store or with Composer.
Go to the Plugin Store in your project’s Control Panel and search for "Phone Number". Then click on the "Install" button in its modal window.
Open your terminal and run the following commands:
# Go to the project directory
cd /path/to/project
# Tell Composer to load the plugin
composer require rynpsc/craft-phone-number
# Tell Craft to install the plugin
./craft install/plugin phone-number
The Phone Number field provides an easy way of parsing, formatting, storing and validating international phone numbers.
The Phone Number field returns a PhoneNumberModel.
When calling any of the below make sure to first check that the field value isn't null. This check is omitted for brevity in the examples.
{% if entry.fieldHandle %}
{{ entry.fieldHandle.region }}
{% endif %}
The raw region code as entered within the field.
{{ entry.fieldHandle.region }}
The raw number as entered within the field.
{{ entry.fieldHandle.number }}
The numerical country code.
{{ entry.fieldHandle.getCountryCode() }}
The alphabetical region code.
{{ entry.fieldHandle.getRegionCode() }}
Returns a phone number link, see links.
{{ entry.fieldHandle.getLink() }}
Returns the number type.
{{ entry.fieldHandle.getType() }}
Number types are returned as integers.
Value | Type |
---|---|
0 | Fixed line |
1 | Mobile |
2 | Fixed line or mobile |
3 | Toll free |
4 | Premium rate |
5 | Shared cost |
6 | VOIP |
7 | Personal number |
8 | Pager |
9 | UAN |
10 | Unknown |
27 | Emergency |
28 | Voicemail |
29 | Short code |
30 | Standard rate |
Returns a description for the number in the supplied locale.
The description returned might consist of the name of the country, or the name of the geographical area the phone number is from.
If region
is supplied, it will also be taken into consideration. If the phone number is from the same region, only a lower-level description will be returned.
{# Manchester #}
{{ entry.fieldHandle.getDescription('en-GB') }}
{# Manchester #}
{{ entry.fieldHandle.getDescription('en-GB', 'GB') }}
{# United Kingdom #}
{{ entry.fieldHandle.getDescription('en-GB', 'US') }}
Returns an array of time zones to which a phone number belongs.
{{ entry.fieldHandle.getTimeZones() }}
Formats a phone number.
{{ entry.fieldHandle.format('international') }}
Numbers can be formatted in the following formats:
Format | Example Output |
---|---|
e164 | +441174960123 |
rfc3966 | tel:+44-117-496-0123 |
national | 0117 496 0123 |
international | +44 117 496 0123 |
The rfc3966 format is also available via the tel
alias.
Formats the phone number based on the region
.
{{ entry.fieldHandle.formatForCountry('GB') }}
Formats the phone number in a way that it can be dialled from the provided region
. The withFormatting
parameter determines whether there is any formatting applied to the number.
{{ entry.fieldHandle.formatForMobileDialing() }}
When querying for elements that have a Phone Number field, you can filter the results based on the Phone Number field data using a query param named after your field’s handle.
Possible values include:
Value | Description |
---|---|
':empty:' |
Field doesn't have a number |
':notempty:' |
Field does have a number |
{ region: ['GB'] } |
Number has the region "GB" |
{ region: ['not', 'GB'] } |
Number doesn't have the region "GB" |
{ number: ['01234567890'] } |
Number is equal to "01234567890" |
{ number: ['not', '01234567890'] } |
Number is not equal to "01234567890" |
{ number: '*0' } |
Number ends with "0" |
{ number: ['not', '*0'] } |
Number doesn't end with "0" |
{ region: "GB", number: '*0' } |
Number has the region "GB" and ends with "0" |
{% set entries = craft.entries()
.phone({ region: ['GB'] })
.all() %}
If you have an element form, such as an entry form, that needs to contain a Phone Number field, you will need to submit your field with inputs for both the region and number.
<select name="fields[fieldHandle][region]">
{% for region in craft.phoneNumber.getAllSupportedRegions() %}
<option value="{{ region.countryCode }}">{{ region.countryName }}</option>
{% endfor %}
</select>
<input name="fields[fieldHandle][number]">
The tel
filter extracts phone numbers from a string and turns them into links, using the number as the link text.
{{ entry.text|tel }}
By default, only numbers with a region code such as +44 will be converted. To convert numbers without a region code you can pass in a default country code to use when parsing.
{{ entry.text|tel('GB') }}
Both the getLink()
method and tel
filter support setting the generated links content and HTML attributes.
Attributes are set as per yii\helpers\BaseHtml::renderTagAttributes()
.
{{ entry.phoneFieldHandle.getLink({
class: 'my-class'
}) }}
{{ entry.textFieldHandle|tel(null, {
class: 'my-class'
}) }}
If text
is included in the attributes argument, its value will be HTML-encoded and set as the text contents of the link.
{{ entry.phoneFieldHandle.getLink({
text: 'Content'
}) }}
{{ entry.textField|tel(null, {
text: 'Content'
}) }}
If html
is included in the attributes argument, its value will be set as the inner HTML of the link (without getting HTML-encoded).
{{ entry.phoneFieldHandle.getLink({
html: '<div>Content</div>'
}) }}
{{ entry.textField|tel(null, {
html: '<div>Content</div>'
}) }}