Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Big Rock: URL generation for pages #5921

@rynowak

Description

@rynowak

Related Issues:


I have a proposal after spending some time with this. It feels very complimentary to what we have elsewhere in the system.

I know that this proposal can work because it's just a small twist on what we already have implemented. Doing something as simple as what's proposed here is beneficial because it doesn't require a lookup table or any custom logic for pages, it's just routing.

Proposal - Page Names

Conceptually, each page has a name that uniquely identifies it.

By default, the page name will be it's relative path based at the pages root directory, with unnecessary noise like the leading slash and file extension trimmed. This means that for a site with the root path of /Pages, then /Pages/Index.cshtml is Index, /Pages/Account/Signup.cshtml is Account/Signup and so on. Again, these are the defaults, and they are the way they are so that each page has an intuitive, typable name, and so that there are no collisions.

Overriding Page Names

You can customize a page name by giving a logical name either through application model, or as an additional token in the @page directive.

@page Directive

@page "{id}" "GetWidget"

Application Model

.AddRazorPagesOptions(options => options.SetPageName("/Account/Login", "Login"))

Generating URL UX

Now for the fun stuff. This just works.

Tag Helpers

<a asp-route-page="GetWidget" asp-route-id="17">...</a>

HTML Helpers

@Html.RouteLink(new { page = "GetWidget", id = 17 }) { ... }

IUrlHelper

@Url.Route(new { page = "GetWidget", id = 17 });

This is all just basic routing using the existing APIs. We can make it a lot nicer by adding some convenience APIs.

Tag Helpers

<a asp-page="GetWidget" asp-route-id="17">...</a>

HTML Helpers

@Html.PageLink("GetWidget", new { id = 17 }) { ... }

IUrlHelper

@Url.Page("GetWidget", new { id = 17 });

What I like about it

I like this model because there's no ceremony if you want to just do the default, but you can give a logical name to the things that you commonly deep link to.

I like this because it gets you out of concatenating things manually which is a huge pain.


I think the most obvious reaction is to look at a mapping like /Pages/Account/SignUp.cshtml -> Account/SignUp and say something like

😲 That's it? That doesn't abstract away the URL.

Yeah. That's it. Pages is low ceremony, what's simpler than files on disk and URLs in a hierarchy?

I think that 80% of the value that our URL generation system provides is in how we're able to parameter substitution in the URL and dynamically build the query string. Basically getting you out of the concatenation game.

For the other 20% think about defining a logical name for your pages that support deep linking. If it's worth it, it's worth it. I had some similar thought here this week so it's in my brain right now. For someone looking to abstract away the physical URL from the logical unit of a linking, we don't have a lot of tools right now. This is something that I think this proposal actually does better than controllers with conventional routing, and about the same as controllers with attribute routing.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions