oqtane / oqtane.framework

CMS & Application Framework for Blazor & .NET MAUI
http://www.oqtane.org
MIT License
1.87k stars 537 forks source link

[ENH] Pattern matching for Url Mappings #4694

Open mdmontesinos opened 1 day ago

mdmontesinos commented 1 day ago

Oqtane Info

Version - 5.2.3 Render Mode - Static Interactivity - Server Database - SQL Server

Describe the enhancement

Migrating content from another CMS or active website to Oqtane requires creating hundreds or even thousands of Url Mappings, as Oqtane uses a delimiter character (!) in the path for parameters.

Therefore, even if a page is called the same, i.e. blogs, the page path in Oqtane would become blogs/!/{id}/{slug}, so the original blogs/{id}/{slug} will all result in broken links. Because of this, you can expect to receive thousands of broken links, one for each publicly available blog.

A possible work-around for this issue would be a sql (or C#) script that iterates over all the blogs and, for each, adds a url mapping to accomodate the new url template. However, this can become problematic when you have to perform this for tens of entities, ending up with, possibly, tens of thousands of entries in the UrlMapping table.

Oqtane should definitely support pattern matching to ease the migration process from other CMS or even regular Blazor applications, therefore attracting more users.

For example, a simple pattern matching could map blogs/* to blogs/!/*. This could later on perhaps be enhanced with additional features like mapping blogs/{id}/{slug} to blogs/!/{slug}/{id}, capturing and reordering path parameters.

Nonetheless, I consider that a basic pattern matching like the first one is vital for this framework.

sbwalker commented 1 day ago

@mdmontesinos this was considered when Url Mapping was introduced but the conclusion was that it would be better to delegate this responsibility to infrastructure components which are specialized for this purpose. For example, IIS already supports pattern-based rewriting in your web.config which is highly optimized based on decades of production usage. It is not very user friendly as there is no UI however one of the philosophies in Oqtane is to not re-invent the wheel.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <location path="." inheritInChildApplications="false">
        <system.webServer>
            <handlers>
                <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
            </handlers>
            <aspNetCore processPath=".\AssemblyName.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
            <rewrite>
                <rules>
                    <rule name="redirect" enabled="true">
                        <match url="(.*)" />
                        <conditions>
                            <add input="{HTTP_HOST}" negate="true" pattern="^NewDomain\.com$" />
                        </conditions>
                        <action type="Redirect" url="https://NewDomain.com/{R:1}" appendQueryString="true" redirectType="Permanent" />
                    </rule>
                </rules>
            </rewrite>
        </system.webServer>
    </location>
</configuration>
mdmontesinos commented 1 day ago

@sbwalker Perhaps complex url mappings do indeed need to be handled by the infrastructure, but I still believe Oqtane should provide, at least, a basic mechanism of wildcard url mapping.

There are cases where you don't have access to infrastructure configuration or when the provider does not allow doing this.

sbwalker commented 10 hours ago

It is important to note that Url Mappings in Oqtane was NOT intended to be a general Url rewriter. It is currently only utilized in the scenario where the route path cannot be determined (ie. a 404). In this exception case it uses the Url Mappings to determine if the user should be redirected to a different route path. As a result of this behavior, this feature has very limited impact on performance as it is not being invoked for every request - it is only invoked for 404s. What you are suggesting is that Url Mappings should be a full featured Url rewriter which would be executed on every request (a much larger performance impact). This is the reason why I think the IIS Url rewriter is a better approach, as it has already been extensively optimized for performance.

mdmontesinos commented 48 minutes ago

I didn't actually mean to change the current behaviour. It should still only be applied when the request results in a 404, for obvious performance reasons. However, when trying to find a url mapping that applies to the missing route, it could do it with a direct mapping or with a wildcard.