Aspnetcore: HTML-only templates or plugin-based templating engine

Created on 30 Nov 2018  Â·  16Comments  Â·  Source: dotnet/aspnetcore

Blazor should remove the use of C# within the HTML templates and move to pure HTML Attribute logic like angular/vuejs/knockout.

*Note: This is a follow-up action after asking for vuejs/angular-style templates during the community standup a while back [https://youtu.be/CWuIz9khK-o?list=PL1rZQsJPBU2StolNg0aqvQswETPcYnNKL&t=3857] (I know it was a super long time ago 🤦‍♂️ )

My intent isn't to copy other popular frameworks but to take the learnings and knowledge that MS already has when developing UI frameworks. Notably the shift to having a declarative language like XAML which uses data binding on attributes like 'ItemSource' or 'Visibility' instead of allowing code to reside inside those templates. It promotes the separation of business logic from residing within the template and makes it more readable for programmers/designers. In the field, I've observed that pure web designers on teams are often discouraged or restricted from committing changes to templates that have languages injected into them which makes them more dependent on developers to make cosmetic changes. Personally, I don't enjoy having two languages in the same file (even in vuejs or angular) and wish it followed the XAML/XAML.cs style. On the other hand, I understand the convenience of having them within the same file, but I do not agree with mixing the languages (one of the main reasons I don't prefer react).

I understand that Blazor uses the Razor templating engine and we are currently restricted to what it offers. IMO, since Razor templates only work on the server, I would relate them to server-side frameworks like jinja2 or Django templates. These frameworks address a different use case of back-end engineers optionally sending parts of HTML to the client and doesn't tool for SPAs. I understand the convience of using it as the engine but I do not think its practices migrate well to a client UI framework.

Since there seems to be a strong tension to have a story for migrating Razor users and templates to Blazor, I would suggest investing in a layer of abstraction where other template engines may be exchanged from the one out of the box. I'd personally invest a large quantity of development time to make sure that a pure attribute option become available.

area-blazor

Most helpful comment

@peterblazejewicz my opinion is of course biased - I have more than 30 years of experience in strongly typed languages like Pascal, C, C++ and now C#. Blazor is the first SPA framework for people like me. Those people have to write big applications. Code have to be well structured and easy to understand for maintainers. We often need to maintain this code for the period of 10 years or more. Those who prefer JavaScript and ngIf or v-if attributes already have a lot of other frameworks. Hopefully Blazor will never drift in that direction.

All 16 comments

Im sorry, but I really hope this will never happen. That's what makes blazor unique, using c # on the client side(within the html)

@GoranHalvarsson you understand that this doesn't eliminate C# as the view logic that lives in the '@functions' section. I am excited to see C# be used on the client side as well but not in the middle of my UI elements.

Yes, but that’s what makes blazor so wonderful. Look at the community standup(from october) where steve does a demo on tabs (in blazor). Specially that part where he puts a simple if statement for the ”third tab”.
https://youtu.be/wwi55L6Qb18

Personally i dont like the @functions thing. I prefer Razor pages way much more. Write any C# code anywhere using @{...}.

@jtillman I understand what you mean. It will be cleaner(don’t mess upp the html with razor/c# code...)

@jtillman I filed #960 asking for something similar. Steve punted it over to Razor team, but they didn't have any interest in focusing on it at the time, https://github.com/aspnet/Razor/issues/2397. Understandable, but it would be nice if we could plug something like this into Razor.

Maybe you could create your own <if> or <for-each> element to get a more declarative syntax?

@jtillman Blazor is created to free professional programmers from JavaScript mess. As @andoband said it has already been discussed in #960. Notice there are a lot of supporters (probably JavaScript programmers) and a lot of opponents (probably C# programmers). It is difficult to please everyone.

to free professional programmers from JavaScript mess

Hey, this seems to be strong, biased opinion.

Not really a fan of those imo since it's basically control flows acting as attributes. It also has a problem when it comes to grouping stuff into a block without messing up markup where frameworks go around by adding virtual tags e.g. <ng-template> <template> which further pollutes the markup and adds more overhead for new users to remember.

The great thing with C# statements in razor is that it differentiates what's deemed markup and what's a control flow. If the developer is already familiar with C# it's quite easy to digest, it's razor's simplicity that makes it possible and avoids the problem of having too many attributes handling too many responsibilities from handling data from props, handling control statements (e.g. [*ngIf], v-if), and normal html tags (class, id, name). A new developer could go in reading the markup with only a C# and html background and immediately get a gist of how the markup is structured and composed.

In the end you'd end up forcing conventions on attribute order to separate control attributes from data attributes and normal html attributes which isn't easy to enforce. Another good thing about it being normal C# is that new C# features would be available immediately if applicable than having to wait for the team to add special attributes for them. That's just opinion on it.

The Razor syntax is one of the strong arguments FOR Blazor. This is not Angular. And maaan I am happy about that!

@xclud If I am not mistaken, there is little difference between Razor Pages and Blazor. You can put any C# code in the page, wherever you like.

The @functions {} block is just a simpler version for the inheritance model. You can move the @functioins {} code into a separate file and class and inherit from it. It is a nice way to separate the code from the presentation.

Separating code and presentation of Blazor pages
Separation of concerns

@peterblazejewicz my opinion is of course biased - I have more than 30 years of experience in strongly typed languages like Pascal, C, C++ and now C#. Blazor is the first SPA framework for people like me. Those people have to write big applications. Code have to be well structured and easy to understand for maintainers. We often need to maintain this code for the period of 10 years or more. Those who prefer JavaScript and ngIf or v-if attributes already have a lot of other frameworks. Hopefully Blazor will never drift in that direction.

Microsoft has used attributes to control User Interfaces way before these other frameworks existed. So those building Microsoft UI should already be familiar with the concept. I believe that a portion of the other frameworks success in large teams was accredited to the attribute based pattern.

Frameworks with Workflow Statements as Attributes

Year 2006/2008 WPF <- Microsoft

  • ItemSource="{Binding Cards}" & Visibility="{Binding HasCards}"

Year 2010 Knockout Js <- Microsoft employees

  • data-bind="foreach: Cards, visible: HasCards"

Year 2010 Angular

  • *ngFor="let card of Cards" & *ngFor="HasCards"

Year 2014 VueJs

  • v-for="card in Cards" & v-if="HasCards"

Lets steer the conversation to answering some fundamental questions:

Why are we explicitly NOT following the pattern that we had with XAML?
Is our position that attribute binding is a bad thing in Xamarin and WPF so we're diverging from it?
If we encourage teams to have code within the template, what good or bad side effect are they likely to experience?
How much should building UI for the desktop be from building UI for the browser (using MS technologies)?

Why are we explicitly NOT following the pattern that we had with XAML?

Because Blazor is the next big step in the ASP.NET Core evolution and not Xamarin/WPF.

If we encourage teams to have code within the template, what good or bad side effect are they likely to experience?

This v-for="card in Cards" & v-if="HasCards" is also code in the template but written in different "language". Simple templates alone are never enough, so people add "artificial languages" to them. Those "languages" are never as good and complete as standard programming languages. Some constructs in those templates look like a poor workarounds to suddenly encountered problems. In Blazor/Razor we have standard well designed C# language and we don't have to learn anything new and ugly.

Do you really think that this example "without code" taken from VueJs doc:

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

is better than this with one C# instruction?

@if (ok)
{
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
}

How much should building UI for the desktop be from building UI for the browser (using MS technologies)?

Do you want to have yet another Silverlight? You can read these issues: #111, #143, #840.

In initial post you have written:

Personally, I don't enjoy having two languages in the same file (even in vuejs or angular) and wish it followed the XAML/XAML.cs style.

This was discussed a few months ago here #278

Razor is pretty mature. It does a lot of things very well. Blazor is Razor in the Browser!

We should try to get the most out of Razor before changing it into something completely different. XAML is maybe a nice idea for many people, but it has nothing to do with Razor. I could envision a different SPA Framework with XAML as frontend language, but Blazor isn't it.

Idea: Maybe we could implement something like Taghelpers, that a component can be used as an additional attribute on many different tags. So you could implement this functionality yourself.

No plans to do anything here, so closing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

githubgitgit picture githubgitgit  Â·  3Comments

ermithun picture ermithun  Â·  3Comments

farhadibehnam picture farhadibehnam  Â·  3Comments

TanvirArjel picture TanvirArjel  Â·  3Comments

Kevenvz picture Kevenvz  Â·  3Comments