DamianEdwards / TagHelperStarterWeb

ASP.NET 5 Starter Web project template converted to use Tag Helpers
Apache License 2.0
80 stars 24 forks source link

Tag Helpers suggestion, round 2. #5

Open Bartmax opened 9 years ago

Bartmax commented 9 years ago

I'm pretty sure this is coming too late, it's ok. After playing around I want to suggest minor modifications to the current proposal.

TL;DR There are two suggestion here: Syntactic sugar & the removal of special attributes that targets existing attributes (like having an action and controller attributes for an existing href [anchor tag example]). And some crazy things as bonus ;)


So, instead of using asp specific tags, one can use existing tags (when they exist) and apply some char suggesting to be resolved by tag helpers. ($ is used here for demonstration purposes only).

<input value="${Age}" class="form-control" />

this simple input, will render the input with the value of Model.Age and the correct type (number in this case) and name if not specified. I can still override the html if I provide a type. The idea here is that tag helpers doesn't get in my way of me authoring the html.

<input type="text" value="${Age}" class="form-control" />
<span asp-validation-for="UserName" class="text-danger"></span>

this get no modification, there's no tag for validation so it's ok to go with a span (or any tag) and use asp- specific annotation. but the asp- is not required, more on that later.

<label for="${Password}" class="col-md-2 control-label"></label>

This will of course create the input for the Model.Password property. I can do write text outside the {} like:

<label for="$MyPrefix{Password}AndSuffix" class="col-md-2 control-label"></label>

the benefit of the above is clear on the form tag:

<form action="$~/{controller}/Register" method="post" class="form-horizontal" role="form">

Instead of using controller and action, I more forward using html5 existing types. the $ hints razor that this is generated via a tag helper.

Tag helpers could then be defined with: tag.attr (example: form.action, a.href, button.type, etc) attr (example class, value, type, style, etc) and maybe: tag.tag.attr (but i dont find a good example).

This definitions will not only help in throwing errors when a tag helper is used where it shouldn't but also for intellisense (usefull when one is authoring tag helpers)

Tag helpers in this way won't need the asp- prefix because if there's a $ at the start, it means it should try to get a tag helper for that attr, so in the case of <span asp-validation-for="UserName" class="text-danger"></span> we can safe write :

<span validation-for="${UserName}" class="text-danger"></span>

still, the asp- can be supported in the sense that you can do asp-tag and you don't need to specify the $ character. so both scenarios apply.

<label asp-for="Password" class="col-md-2 control-label"></label>
<label for="${Password}" class="col-md-2 control-label"></label>

both are valid and should output the same results.

I don't see it as a major difference on how they are implemented now, except maybe for the form tag, but for me it looks like more html, not obscure on when is asp or not processing the data, and less verbose with less asp- strings.

another interesting important technique that can be used is intellisense, lets take a look at the anchor tag.

<a href="$Home/About">Abount</a>
<a href="${controller}/Index">Go back to index</a>

When we write <a href="$ <--- here we can retrieve intellisense for all actions in all controllers and narrowing down as we type, much like project.json autocomplete works.

More crazy or future things we can do

<form  method=$put> ... // this can return method post and an http-override input put.
<div class="$active(false)" ... // receive parameters. this may return a class hide.
<input $disabled({!IsActive}) /> // this can set the input as disabled if the IsActive model property evaluates to false
<img src="$http://cdn.somedomain.com/Images/picture.jpg$header({dpi})" /> // this can append a header to the request with the value of the dpi retrieved by a javascript on the client side, so our cdn can serve a more appropriate image for the requested dpi device.

As I pointed out, I know, kinda late to the party, but maybe someone find something valuable here.

janus007 commented 9 years ago

Yes, once again Microsoft develops a feature to fix a bug. When will they learn?

Why on earth do we need more magic strings in our html, seems 2 steps backward. And please spare me for prefixing the tag-helpers so we can distinguish them.

More magic @im-an-attribute-that-runat-server=true?. Please stop our pain, seems that people got wiped their brains... anyone even remember WebForms?

Back then it was clear what run at server actually did, you either liked it or hated it, but nevertheless it made the butter for our bread.

It would be a lot better if Microsoft looked at T4MVC and tried to learn something about how developers would like to eat code.

T4MVC is a T4 template for ASP.NET MVC apps that creates strongly typed helpers that eliminate the use of literal strings in many places.

e.g. instead of

@Html.ActionLink("Delete Dinner", "Delete", "Dinners", new { id = Model.DinnerID }, null)

T4MVC lets you write

@Html.ActionLink("Delete Dinner", MVC.Dinners.Delete(Model.DinnerID))

andreminelli commented 8 years ago

I fully agree with the idea of get rid of 'magic strings'!! @Bartmax proposal have a good balance between embrace HTML standards and still make use of server side compile time features.

Bartmax commented 8 years ago

After using for a while, I had to say that I like the current version of TH better than my proposal. The only thing may have a place is the use of href instead of asp-action/asp-controller. but currently, th are awesome.