UrlGenerator is a simple library that allows you to generate URLs from a single JSON configuration for different programming languages.
+There is also UrlGenerator for PHP, which accepts the same configuration, +so you can combine multiple projects in Python and PHP using same configuration file.
Main entrypoint to this library is function url_generator.get_url
which accepts the following parameters:
Path string defines path through route configuration using dot notation (see the #configuration section bellow).
example: heureka.category.index
Params is dictionary of route parameters. Params dict should contain mixed GET
parameters and template parameters as defined in configuration.
example: lang="sk", productId=12345
from url_generator import UrlGenerator
ug = UrlGenerator('path/to/your/config.json', env="dev", lang="sk")
ug.get_url("heureka.category.index", productId=12345)
Path to configuration file must be passed trough the constructor to the UrlGenerator instance (as a first parameter).
Check tests/test.json
for better understanding.
Structure is plain Json (planning support for comments in future).
Simple configuration file can look like this:
{
"some_example_site": {
"@scheme": "https",
"@subdomain": "www",
"@host": "example.com",
"@host_postfix": "test.dev",
"@path": "/{category_id}/search",
"@params": {
"query": "q"
}
}
}
Keys in configuration that are prefixed by @
symbol are considered as keyword.
Each route is defined by keyword. Note that @scheme
and @host
keywords are mandatory.
Keywords are prefixed by @
symbol to distinguish them from path nodes.
This represents URL scheme by RFC1738, usually http
or https
example: "@scheme": "https"
This represents subdomain.
example: "@subdomain": "www"
This represents host (and can contain port if necessary)
example: "@host": "www.heureka.cz"
This represents postfix for host. For example for dev environment.
example: "@host_postfix": "test.dev"
This represents URL path by RFC1738 like /
for index or /iphone-7/recenze
for product detail
example: "@path": "/obchody/czc-cz/recenze"
This represents list of allowed query parameters with their internal and external representation.
For example if configuration contains "@query": {"index": "i"}
then index
parameter in
call ug.get_url('example_site', index=10)
will be compiled according to configuration into i=10
and returned url should looks like https://www.example.com/?i=10
.
Note that query parameters are not mandatory, and cannot be set as mandatory.
This represents fragment (anchor identifier) by RFC1738 like #section
example: "@fragment": "section"
Every key in configuration, which is not prefixed by @
or {
symbol, is considered as path node.
Path nodes should use underscore_case
naming convention.
Path string is dot joined Path nodes like heureka.category.index
.
For example, in following configuration some_site
or index
are path nodes.
On the other hand @host
and @path
are keywords.
{
"@scheme": "https",
"some_site": {
"index": {
"@host": "example.com",
"@path": "/index.php"
}
}
}
With the precending configuration we can call get_url('some_site.index')
and generated url will be https://example.com/index.php
.
Using path string we define which URL we want to receive. The URL Generator parses the config file and gets keywords from given path node and all its parents.
At the example bellow, we can call get_url('example.russian')
and the response will be https://www.example.ru/information
.
Note that URL Generator uses the @host
keyword in example.russian
path node, but @path
keyword is from example
. At least @scheme
keyword is defined in global space (root path).
{
"@scheme": "https",
"example": {
"@host": "www.example.com",
"@path": "/information"
"russian": {
"@host": "www.example.ru"
}
}
}
At this example you can also see keywords overloading, as the host
keyword is defined in example
path node and it is overloaded in example.russian
path node.
This way we can build complex structures like heureka.product.detail.reviews.only_certified
without too many repating definitions in the configuration.
In the configuration we can define template parameters using {parameter}
syntax.
Those parameters will be expected in get_url(path, params)
function call (in params array).
Template parameters can be also defined globally as first parameter of URL Generator constructor and those will be shared for all get_url
function calls.
It is not recommended to use template parameters in values for @scheme
and @query
keywords.
At the example bellow we define top level domain using language
parameter.
So we can call get_url(path, language='cz', page=1])
and the result will be https://www.example.cz?p=1
.
{
"@scheme": "https",
"example": {
"@host": "www.example.{language}",
"@params": { "page": "p" }
}
}
Note that query parametes and template parameters are mixed in get_url(.., **kwargs)
second parameter together.
We can define template conditions in configuration to separate configuration for given parameter value.
This way we can define configuration only for given language/environment/etc..
Template conditions uses {parameter}=expected_value
syntax and can contain same rules as path nodes.
Rules defined inside template condition are processed only if given parameter equals expected value.
At the example bellow we define {lang}=spanish
condition, so if we call get_url("example", lang="spanish")
it returns https://www.ejemplar.es
.
{
"@scheme": "https",
"example": {
"@host": "www.example.cz",
"{lang}=spanish": {
"@host": "www.ejemplar.es"
}
}
}
Note that rules are processed from top to bottom in file. Latter rule has priority so template condition must be placed after overloaded values to have effect.
The main advantage of the URLGenerator is that it can share the configuration through multiple programming languages. Therefore, it is necessary to keep the individual language versions compatible with each other.
So, when you create a pull-request into this repository, please concider contributing the same functionality to the other repositories listed in Other programming languages section.
Project owners should never merge code which breaks compatibility with other language versions.
The author of the first idea is Pavel Škoda.
Happy URLing ;)