Package: url-generator
Url generatorUrlGenerator is a simple library that allows you to generate URLs from a single JSON configuration for different programming languages.Other programming languages+There is alsoUrlGenerator 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 functionurl_generator.get_urlwhich accepts the following parameters:pathStringPath stringdefines path through route configuration using dot notation (see the #configuration section bellow).example:heureka.category.indexparameter kwargsParamsis dictionary of route parameters. Params dict should contain mixedGETparameters and template parameters as defined in configuration.example:lang="sk", productId=12345Example call:fromurl_generatorimportUrlGeneratorug=UrlGenerator('path/to/your/config.json',env="dev",lang="sk")ug.get_url("heureka.category.index",productId=12345)ConfigurationPath to configuration file must be passed trough the constructor to the UrlGenerator instance (as a first parameter).
Checktests/test.jsonfor 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"
        }  
    }
}KeywordsKeys in configuration that are prefixed by@symbol are considered askeyword.
Each route is defined by keyword. Note that@schemeand@hostkeywordsare mandatory.Keywordsare prefixed by@symbol to distinguish them frompath nodes.@schemeThis represents URL scheme byRFC1738, usuallyhttporhttpsexample:"@scheme": "https"@subdomainThis represents subdomain.example:"@subdomain": "www"@hostThis represents host (and can contain port if necessary)example:"@host": "www.heureka.cz"@host_postfixThis represents postfix for host. For example for dev environment.example:"@host_postfix": "test.dev"@pathThis represents URL path byRFC1738like/for index or/iphone-7/recenzefor product detailexample:"@path": "/obchody/czc-cz/recenze"@queryThis represents list of allowed query parameters with their internal and external representation.For example if configuration contains"@query": {"index": "i"}thenindexparameter in
callug.get_url('example_site', index=10)will be compiled according to configuration intoi=10and returned url should looks likehttps://www.example.com/?i=10.Note thatquery parameters are not mandatory, and cannot be set as mandatory.@fragmentThis represents fragment (anchor identifier) byRFC1738like#sectionexample:"@fragment": "section"Path nodesEvery key in configuration, which isnot prefixed by@or{symbol, is considered aspath node.Path nodesshould useunderscore_casenaming convention.Path stringis dot joinedPath nodeslikeheureka.category.index.For example, in following configurationsome_siteorindexare path nodes.
On the other hand@hostand@pathare keywords.{
    "@scheme": "https",
    "some_site": {
        "index": {
            "@host": "example.com",
            "@path": "/index.php"
        }
    }
}With the precending configuration we can callget_url('some_site.index')and generated url will behttps://example.com/index.php.InheritanceUsingpath stringwe define which URL we want to receive.
TheURL Generatorparses the config file and getskeywordsfrom givenpath nodeand all its parents.At the example bellow, we can callget_url('example.russian')and the response will behttps://www.example.ru/information.Note thatURL Generatoruses the@hostkeywordinexample.russianpath node, but@pathkeywordis fromexample. At least@schemekeywordis 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 seekeywordsoverloading, as thehostkeywordis defined inexamplepath nodeand it is overloaded inexample.russianpath node.This way we can build complex structures likeheureka.product.detail.reviews.only_certifiedwithout too many repating definitions in the configuration.Template parametersIn the configuration we can definetemplate parametersusing{parameter}syntax.
Those parameters will be expected inget_url(path, params)function call (in params array).Template parameters can be also defined globally as first parameter ofURL Generatorconstructor and those will be shared for allget_urlfunction calls.It isnot recommendedto use template parameters in values for@schemeand@querykeywords.At the example bellow we define top level domain usinglanguageparameter.
So we can callget_url(path, language='cz', page=1])and the result will behttps://www.example.cz?p=1.{
    "@scheme": "https",
    "example": {
        "@host": "www.example.{language}",
        "@params": { "page": "p" }
    }
}Note thatquery parametesandtemplate parametersare mixed inget_url(.., **kwargs)second parameter together.Template conditionsWe can definetemplate conditionsin configuration to separate configuration for given parameter value.This way we can define configuration only for given language/environment/etc..Template conditionsuses{parameter}=expected_valuesyntax and can contain same rules aspath nodes.Rules defined inside template condition are processed only if given parameter equals expected value.At the example bellow we define{lang}=spanishcondition, so if we callget_url("example", lang="spanish")it returnshttps://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 sotemplate conditionmust be
placed after overloaded values to have effect.Contributing rulesThe 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 inOther programming languagessection.Project owners should never merge code which breaks compatibility with other language versions.AuthorThe author of the first idea isPavel Škoda.So ...Happy URLing ;)