Create internationalized address forms, like:
Sweden:
[Name]
[Street address]
[Postal code] [City]
US address:
[Name]
[Street address]
[City] [State] [Zip code]
with code like (React example):
tokenRows.map((row, index) => (
<div key={index}>
{tokens.map((token) => (
<input key={token} name={token} />
))}
</div>
));
Using OpenCage Data templates with address formats used in territories around the world.
OpenCage Data templates are meant to display data from a fragmented set of address parts. It's not suitable to map directly to form input. We want:
- Normalized field names. For example, the field name should be the same for ’Postal code’ and ’Zip code’ – the correct display form should instead be handled by translation.
- Omit unnecessary fields. In this example structure, house number doens't have it's own field and is expected to be written as part of the ’Street address’.
- No typography. For example no comma between City and State in US form fields.
- Write a Node script to extract the tokens to fulfill your form field needs.
- Import the tokens in your web project and map them to form fields (see example above).
- Optionally, print the address in a summary by importing the template.
npm i -D address-tokens
const { tokens, template } = require("address-tokens");
// Input can be any OpenCage Data template key, see below
// The value is the token name of your choice.
// Here ’road’ is split in two different fields, whereas
// ’conty’ and ’state’ use the same field name.
const input = {
attention: "{firstName} {lastName}",
road: "{addressLine1}\n{addressLine2}",
city: "{city}",
postcode: "{postalCode}",
county: "{region}",
state: "{region}",
country: "{country}",
};
tokens(input, "SE");
/* -->
[
["firstName", "lastName"],
["addressLine1"],
["addressLine2"],
["postalCode", "city"],
["country"],
];
*/
tokens(input, "US");
/* -->
[
["firstName", "lastName"],
["addressLine1"],
["addressLine2"],
["city", "region", "postalCode"],
["country"],
];
*/
template(input, "SE");
/* -->
`{firstName} {lastName}
{addressLine1}
{addressLine2}
{postalCode} {city}
{country}`
*/
template(input, "US");
/* outputs
`{firstName} {lastName}
{addressLine1}
{addressLine2}
{city}, {region} {postalCode}
{country}`
*/
const path = require("path");
const fs = require("fs");
const { tokens, template } = require("address-tokens");
const input = {
attention: "{name}",
road: "{streetAddress}",
city: "{city}",
postcode: "{postalCode}",
county: "{region}",
state: "{region}",
country: "{country}",
};
const content = Object.fromEntries(
["SE", "US", "AX"].map((code) => [
code,
{ output: template(fields, code), input: tokens(fields, code) },
])
);
fs.writeFileSync(path.resolve(__dirname, "my-address-tokens.js"), content);
The template output can be used to format the address token data into a string. Create a function like:
import layouts from './my-address-tokens';
const input = {
firstName: 'Erik',
lastName: 'Andersson',
addressLine1: '4 Main street',
postalCode: '999 00',
city: 'Somewhere'
}
const layout = layout['SE'].output;
const tokens = layout.match(/\{\w+\}/g);
let output = layout;
tokens?.forEach((token) => {
const variable = token.substring(1, token.length - 1);
output = output.replace(token, input[variable] ?? "");
});
output = output.replace(/\n\n+/, "\n").trim();
/* --->
Erik Andersson
4 Main street
999 00 Somewhere
*/
Extracted from https://github.com/OpenCageData/address-formatting/blob/master/conf/countries/worldwide.yaml
attention
house
road
house_number
postcode
postal_city
town
city
village
municipality
hamlet
county
state
archipelago
country
quarter
state_district
suburb
state_code
county_code
city_district
region
neighbourhood
island
continent
province
residential
$ git clone https://github.com/flip-it/address-tokens.git
$ cd address-tokens
$ npm run pull-submodules
$ npm install
$ npm test
Based on the work of JS Address formatter.