Skip to content

heureka/py-url-generator

Repository files navigation

Url generator

UrlGenerator is a simple library that allows you to generate URLs from a single JSON configuration for different programming languages.

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

Basic usage:

Main entrypoint to this library is function url_generator.get_url which accepts the following parameters:

pathString

Path string defines path through route configuration using dot notation (see the #configuration section bellow).

example: heureka.category.index

parameter kwargs

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

Example call:

from url_generator import UrlGenerator

ug = UrlGenerator('path/to/your/config.json', env="dev", lang="sk")
ug.get_url("heureka.category.index", productId=12345)

Configuration

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"
        }  
    }
}

Keywords

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.

@scheme

This represents URL scheme by RFC1738, usually http or https

example: "@scheme": "https"

@subdomain

This represents subdomain.

example: "@subdomain": "www"

@host

This represents host (and can contain port if necessary)

example: "@host": "www.heureka.cz"

@host_postfix

This represents postfix for host. For example for dev environment.

example: "@host_postfix": "test.dev"

@path

This represents URL path by RFC1738 like / for index or /iphone-7/recenze for product detail

example: "@path": "/obchody/czc-cz/recenze"

@query

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.

@fragment

This represents fragment (anchor identifier) by RFC1738 like #section example: "@fragment": "section"

Path nodes

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.

Inheritance

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.

Template parameters

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.

Template conditions

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.

Contributing rules

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.

Author

The author of the first idea is Pavel Škoda.

So ...

Happy URLing ;)