The first components in the ASP.NET pipeline are Middleware
. Middleware can either handle a request completely, or process the incoming request and pass it on to the next component in the pipeline.
As Piranha CMS is built around standard ASP.NET
components most of its middleware is used for routing and passes the request on to eventually be handled by the web application.
The middleware components are added when calling UseCms
in ConfigureServices
. The following code sets up middleware for all available content.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApi api)
{
...
// Configure Piranha
app.UsePiranha(options =>
{
options.UseCms();
...
});
...
}
This call is equivalent to setting up the entire web application and adding the following middleware components (in the specified order). Please note that the routing middleware handles all of the existing content types.
The routing middleware will perform the following operations on the request in the specified order.
The middleware first tries to resolve the current site by looking at the hostname and the first url-segment, for example:
mysite.com/en
If a match can't be found it continues by resolving the site using only the hostname. If the current hostname can't be found it will use the default site of the application.
You can bypass this entire step by disabling UseSiteRouting
in your startup in which case the default site will always be used.
app.UsePiranha(options =>
{
options.UseCms(o =>
{
o.UseSiteRouting = false;
});
});
GET mysite.com/alias
After the site has been resolved the middleware tries to find an alias that matches the requested url. If such an alias is found the middleware will return a temporary or permanent redirect depending on the alias.
You can bypass this entire step by disabling UseAliasRouting
in your startup.
app.UsePiranha(options =>
{
options.UseCms(o =>
{
o.UseAliasRouting = false;
});
});
GET mysite.com/pageSlug
After this the middleware will try to resolve the page deepest in the hierarchical sitemap that matches the requested url. If a page is found it is stored for later processing.
As this step is needed for several other actions you can't bypass it entirely, but you can disable the request for being rewritten for pages by disabling UsePageRouting
and/or UseStartpageRouting
in your startup.
app.UsePiranha(options =>
{
options.UseCms(o =>
{
o.UsePageRouting = false;
o.UseStartpageRouting = false;
});
});
GET mysite.com/pageSlug/postSlug
If a page was found in the previous step and that page is an archive the middleware will, using the next segment in the requested url, try to resolve a post from that archive.
You can bypass this entire step by disabling UsePostRouting
in your startup.
app.UsePiranha(options =>
{
options.UseCms(o =>
{
o.UsePostRouting = false;
});
});
For more detailed information about how routing for content types works, please refer to Routing and Advanced Routing.
After the previous operations have been performed the middleware rewrites the request to the ASP.NET application using the following rules.
If a post was found the request is rewritten to the route of the post. Possible query string and remaining url segments are passed along to that route.
If a page was found that wasn't an archive the request is rewritten to the route of the page. Possible query string and remaining url segments are passed along to that route.
If a page was found that was an archive the middleware inspects the remaining segments in the requested url to resolve parameters for the archive.
GET /<pageSlug>/<year?>/<month?>(/page/<pageNum>)?
GET /<pageSlug>/category/<categorySlug>/<year?>/<month?>(/page/<pageNum>)?
GET /<pageSlug>/tag/<tagSlug>/<year?>/<month?>(/page/<pageNum>)?
All parameters are optional except pageSlug
, but the optional paging must be placed last. Everything after the page number is ignored. This means that the following URL's would be valid:
/myblog
/myblog/category/fishing
/myblog/tag/salmon
/myblog/page/2
/myblog/category/fishing/page/2
/myblog/tag/salmon/page/2
/myblog/2018
/myblog/category/fishing/2018
/myblog/tag/salmon/2018
/myblog/2018/page/2
/myblog/category/fishing/2018/page/2
/myblog/tag/salmon/2018/page/2
/myblog/2018/1
/myblog/category/fishing/2018/1
/myblog/tag/salmon/2018/1
/myblog/2018/1/page/2
/myblog/category/fishing/2018/1/page/2
/myblog/tag/salmon/2018/1/page/2