Download the PHP package baraja-core/smart-router without Composer
On this page you can find all versions of the php package baraja-core/smart-router. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package smart-router
Smart router
A router is a component for bidirectional translation between a URL and an application request. By bidirectional we mean the possibility to derive a presenter action from a URL, but also vice versa, to generate a corresponding URL to the action.
The package provides a default implementation of SmartRouter
, which improves the default routing method in Nette and adds the ability to store specific URLs in a database (or other repository), including their parameters, language, and advanced configuration.
Installation
The package is part of the default Baraja Sandbox.
Or you can install manually via Composer:
All routing rules are defined in the RouterFactory
class, where we can inject the SmartRouter
service like this:
We will ensure that all requests are first processed via SmartRouter and only in case of failure will other regular routes be used.
SmartRouter
SmartRouter
is my internal implementation of how routing should work. The entire request routing process works fully automatically, and can be influenced by a very detailed configuration, which is then cached.
We divide routing into 3 separate parts:
Match
: Rewrite URL to application request (request processing)Construct URL
: Create a URL based on an application requestRewriter
: Implementation of an interface for rewriting parameters on the URL part, where most of the magic happens
The default implementation of the Rewriter is DoctrineRewriter
(more information), which routes URLs based on a database table. Its internal implementation is extremely effective.
For smaller applications or in the case of testing, you can use StaticRewriter
, which performs rewriting based on a physically stored in array.
Match - Accept the request URL
The following text describes how the list of found parameters is compiled according to the loaded URL.
Routing is divided into 4 logical steps.
- Find the required URL in the cache. If the record exists (it can also be negative), we route it directly and we don't have to search further
- Preparation of the cache for configuration, if any, we will use from the cache,
- Finding the current URL (routing) according to the internal logic (will be described below),
- Save the routed parameters to the key-value cache, which will be used next in the first step.
The request cache contains 2 parameters:
- Expiration by constant
CACHE_EXPIRATION
(default 30 minutes) - Tag with value
route/<presenter>:<action>
Caution: Special behavior
All requests that we can handle are still being processed internally in the router, which always adds the
locale
key. If not specified during routing, we return the default language for the current site. If the default language does not exist, we return English.If the current language of the matched request does not exist, we throw an
E_NOTICE
level error.
Sending and processing the matched application request
Whether we find the application request in the cache or it is created by a direct match, it will always be sent by the returnRequest()
method.
The task of this method is to set the current environment (private property environment
) to the internal state of the router, which will be used for routing other requests and compiling URLs. The currently matched environment will only be used if it is better than the internally set one.
The environment priority rating table is stored in the environmentScoreTable
configuration key and in the basic implementation is:
localhost
: 1beta
: 2production
: 3
At the same time, the task of this method is to set the language to the Translator.
Attention: If no request has been routed, it is not possible to reliably determine the language and environment during further processing of the application and generation of links.
If we generate a link to an e-mail in CLI mode (cron or another background task), for example, it is always necessary to insert the language (
locale
) and environment (environment
) into all requests. If we do not enter these values, the router may behave differently than we expect.
Entity MatchRequest
- Internal logic of request processing
The MatchRequest
entity serves as a helper to process the current URL and return results. The instance is created by the Smart router itself.
Final processing is done only after calling a single public method match()
, which returns a parameter field in case of success, or null
in case of error or invalid request.
The internal logic of processing can change (and improve) over time, this text describes only general principles. A description of the specific implementation and an explanation is available directly in the implementation as a comment.
Processing procedure:
- Finding a route (
processRoute()
method)
Currently we only support Front
and Admin
modules, we are looking for matching presenter
and action
.
We gradually try the rules:
- Is the Homepage or an empty URL? (
$slug === ''
) - Is there an admin request? If so, we route regularly according to the mask
admin/[<locale=en cs|en>/]<presenter>/<action>
- Transcription based on
Rewriter
+ addition of parameters, environment and language. - A regular expression (corresponds to the
<presenter> / <action>
mask) for backward compatibility of old orlazy
URLs.
- We will process the language of the request
The resulting language of the request is very difficult to determine, because when designing the routing kernel, we came across dozens of special cases where it is not easy to decide. It is usually a combination of domain language vs. another language slugu, or locale parameter.
The solution consists in accumulating all available languages that we have available about the current URL, sorting them into fields according to keys and then selecting the best one according to priorities.
We distinguish 3 basic priority levels:
- (best)
URL parameter
: Contained in?locale=en
, Path / Slug
: Part of the URL is assigned to a specific language according to the rewrite,Domain
: The language is typical for the currently routed domain.
- Compilation of final parameters
In this step, the last check and purge of the parameters will be performed, which will be sent as an application request.
The minimum configuration always contains values:
presenter
(in the form<module>:<presenter>
)action
locale
(string)environment
(string, values:localhost
,beta
,production
)
Construct URL - Build a URL
The following text describes how the URL is generated according to the specified parameters.
Before generating the URL itself, it is necessary to verify the existence of basic keys, according to which we will determine the type of URL.
It's about:
locale
: The language in which the URL is available,environment
: The environment where the URL leads (for example, to avoid generating a link toproduction
or other combinations onbeta
).
- We find the URL in the cache according to the key composed of parameters,
- If the cache does not contain the resulting URL, we will prepare the configuration, or read it from the cache,
- Build the required URL based on the internal logic (described below),
- Write to the cache and return the final URL, or
null
if it is not possible to crash.
The process of compiling a URL is much more challenging to match and must take into account more rules. However, some parts work the same.
The basis of a correctly generated URL is its uniqueness, even in the future. It must not contain logical disputes (for example, the slug language does not fit the domain language), so extremely complex logic and a set of rules are used for assembly.
Before building the final URL, an instance of the ConstructUrlRequest
entity is created, which requires (array $params, Rewriter $rewriter, array $config = null)
and sets the internal state of the entity for further generation based on the configuration.
When compiling, we find out the following values:
environment
: The environment in which we will generate the URL (different for localhost or domain production, for example),locale
: URL languagelazy
: Abool
flag indicating a simply assembled regular URL without usingRewriter
, which can slow down - explained below,presenter
andaction
for page type context.
The assembly itself is performed only when the construct()
method is called, which returns string
with an absolute URL or null
in the event of an error.
The procedure again has many steps:
- Obtaining a domain
- Is the environment empty, unknown, or has no default domain defined for it in the configuration? Then the current domain is retained.
- If the environment exists, we will find the best domain for the desired language,
- If the domain for the required language does not exist, we return the default domain for the environment and remember the
needLocaleParameter
flag, which says that we must pass the language in a parameter in the URL.
Before returning the domain, we check the configuration to see if we should add www.
before the domain (useWww
flag).
- Processing
path
(slug
)
Now it depends on whether we are building the path according to real parameters (using the Rewriter
interface), or it is a lazy link
, ie a simplified version.
Lazy link generates a path in the form <presenter>/<action>
, generating only /
for Homepage:default
, only /product
for Product:default
and so on.
As for the real link, we generate the URL from Rewriter
using the rewriteByParameters()
method, while the router's internal logic performs further cleanup, such as comparing languages and removing overwritten parameters. More info in the section on the transcriber.
- We will compile the final URL according to the general format:
<scheme>://<domain>/<path>?<parameters>
Lazy URL - Simplified URL format
The Smart Router supports the so-called lazy URL
, which is a permanent URL generated using regular expressions, which does not require access to the Rewriter
or the database during compilation and parsing.
Its advantage is extremely fast reading and creation. It is especially suitable for large listings of items (such as products in a catalog), where building a nice URL would take an unnecessarily long time and completely delay loading the page.
Lazy URLs are generated during generation by passing the value ['lazy' => true]
.
Rewriter
In order to be able to dynamically rewrite the URL to the application request (parameters) and back (generate the URL), it was necessary to implement a Smart router
, which provides a general algorithm for this task.
In practice, however, it is necessary for different clients to rewrite URLs in different ways - but mostly from a database. The Rewriter
interface is used for this task, which is good to know especially in a situation where we need to change the method of compiling URLs, or rewrite from a static file (small websites or test progress).
rewriteByPath(string $path):?array;
Overwrites the current path (slug
) in the parameter field. If not, it returns null
.
Minimum configuration to return:
rewriteByParameters interface (array $parameters):?RewriterParametersMatch;
Overwrites the required parameters on Slug and other properties. Returns the result as a type entity.
The task of the RewriterParametersMatch
entity is to carry strict information about which path
(slug
) the URL was rewritten to, in which language and what parameters were used.
Example:
When routing the /wheels
URL, a rewrite was performed on Front:Category:detail
with the parameter id = 1
.
We have to pass this parameter separately in the field, because the router overwrites the parameter id = 1
into the slug /kola
, which clearly represents this ID. Removal is also necessary so that the parameter is not further preserved in the URL, because it is already passed as part of the slug (inside the DB) and can therefore always be re-routed.
📄 License
baraja-core/smart-router
is licensed under the MIT license. See the LICENSE file for more details.
All versions of smart-router with dependencies
nette/application Version ^3.0
nette/http Version ^3.0
nette/caching Version ^3.0
baraja-core/localization Version ^2.0
baraja-core/url Version ^1.0