You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Dec 19, 2018. It is now read-only.
This is to open some discussion about an idea for a new language construct in Razor.
Background
While most of what we do is focused on compile and run time resolution, some "dynamic" things are better handled at design time. This proposal is to create a design-time directive in the Razor language. The design time directive indicates that the file contents following the directive will be modified by some process. The design-time directive provides hooks and extension points into a cshtml file to enable actions to take place at design time. These can be trigged manually, by Visual Studio, or other processing.
Design-Time Directive
The design-time directive is used to communicate with parsers, file processors, and the Razor Engine.
It takes the general form: @[...]
It can take parameters: @[parser, action, parameters]
It can have scope: @[...]{ ... }
The design-time directive indicates to a process (external or internal) that an area of the file will/can be modified by the process. The directive has no impact on it's own.
It is removed at compile time by the Razor Engine from the resulting html.
Examples
Substitution
The most trivial use of the directive is to insert a group of characters into the file.
Given - @[myText] = "This is some text to repeat."
Using - @[myText]
Produces => This is some text to repeat.
The directive isn't actually replaced. The text is inserted after the directive.
Any characters can be used - text, tags, code.
In initial cshtml:
@[myText]
After the substitution process runs, in cshtml:
@[myText]
This is some text to repeat.
In html:
This is some text to repeat.
Changing the text in the assignment changes the results in all files using the directive when the process runs again. Though the directive doesn't technically have impact on it's own, some features like substitution would be built into the environment.
Merging
Razor is especially interesting because it can be a mix of many languages - cs, css, js, html. Setting aside the "correctness" of putting css or js in an cshtml file, they provide fair examples. In an html/cshtml file, we can include <script></script> and <style></style> blocks. For the sake of argument, let's say we have a compelling reason to include content inside them in the file. Writing the code in the page is messy, and can be problematic. Worse, many of us prefer Less and Typescript, which we can't write in-page. The @[] directive helps.
We can write our css in a Less file - styles.less, that compiles into styles.css, and our js in scripts.ts, that compiles into scripts.js. We get full editor and intellisense support. In our Page.cshml we can include the results.
@[style, "~/styles.css"]
... The contents of styles.css are copied into the page here, in a <style> block.
@[script, "~/scripts.js]
... The contents of scripts.js are copied into the page here in a <script> block.
This happens during design - the file content is modified, triggered manually, by the IDE, or an extension. For example, after Web Essentials compiles a Less file into css, it could also update the pages that reference the css file through design-time directives. Though the end result is much like @render, we get a local copy that provides access to the internals, and allows modification if we turn "auto-update" off.
Selectors help keep files small. If we just need a couple of styles or functions, we can only copy them.
This would pull the two styles and single function out of the files, and insert them into the page inside<style> and <script> blocks. This can be helpful in building small, self-contained, and lightweight components.
Templates
Html Templating is another other possibility. This can be used in regular files or in template/scaffolding engines. An overly simple example is the common label-input-validation set - <label asp-for="ModelProperty"><input asp-for="ModelProperty"></input><...validationstuff...
There are many ways to approach this, but one could be (in a cshtml)
@[]{
form-line = "<label asp-for="@[param]" ... "
}
@[form-line, param="ModelProperty"]
... Fragment is expanded here, with replacement.
Templates are like advanced, dynamic Snippets, and can be defined in the page or in shared files. They can auto update, or be manually triggered.
Targeting
When we know we are running a file processor over the file, we can define targets. This can make the processor more efficient, and the file easier to parse. The processor can look for tagged areas to process, or even exclude.
@[fileProcessorName, processingAction, exclude] {
... This section is skipped by fileProcessorName when executing processingAction
- if it is aware of design-time directives.
}
Discussion Scope
This proposal isn't about any of the specific examples, but about the concept of being able to provide information to processes that manipulate code files. And if so, is @[] a good construct to use? More and more, we run processes against these files - from built-in formatting processes, to refactoring, to analysis processes. A standard way to communicate with these processors might be valuable.
Outside the Proposal
The concept can also extend into other languages.
Though advanced, this could allow things like name refactoring for related items in different technologies. For example, a C# class and Typescript class could have a design-time association. Changing one triggers changes to the other. This is a design-time change - the files are modified directly. The association doesn't exist at compile or run time. This would be a long time coming, but shows possible potential of the overall concept.
The text was updated successfully, but these errors were encountered:
Hi @RandyBuchholz.
Thanks for your feature proposal.
While this may be a good idea, this is not a priority for us for the near future.
If, however, we'll see a good community interest in this issue, we'll reconsider it in the future.
This is to open some discussion about an idea for a new language construct in Razor.
Background
While most of what we do is focused on compile and run time resolution, some "dynamic" things are better handled at design time. This proposal is to create a design-time directive in the Razor language. The design time directive indicates that the file contents following the directive will be modified by some process. The design-time directive provides hooks and extension points into a cshtml file to enable actions to take place at design time. These can be trigged manually, by Visual Studio, or other processing.
Design-Time Directive
The design-time directive is used to communicate with parsers, file processors, and the Razor Engine.
@[...]
@[parser, action, parameters]
@[...]{ ... }
The design-time directive indicates to a process (external or internal) that an area of the file will/can be modified by the process. The directive has no impact on it's own.
It is removed at compile time by the Razor Engine from the resulting html.
Examples
Substitution
The most trivial use of the directive is to insert a group of characters into the file.
Given -
@[myText] = "This is some text to repeat."
Using -
@[myText]
Produces =>
This is some text to repeat.
The directive isn't actually replaced. The text is inserted after the directive.
Any characters can be used - text, tags, code.
In initial cshtml:
After the substitution process runs, in cshtml:
In html:
Changing the text in the assignment changes the results in all files using the directive when the process runs again. Though the directive doesn't technically have impact on it's own, some features like substitution would be built into the environment.
Merging
Razor is especially interesting because it can be a mix of many languages - cs, css, js, html. Setting aside the "correctness" of putting css or js in an cshtml file, they provide fair examples. In an html/cshtml file, we can include
<script></script>
and<style></style>
blocks. For the sake of argument, let's say we have a compelling reason to include content inside them in the file. Writing the code in the page is messy, and can be problematic. Worse, many of us prefer Less and Typescript, which we can't write in-page. The@[]
directive helps.We can write our css in a Less file -
styles.less
, that compiles intostyles.css
, and our js inscripts.ts
, that compiles intoscripts.js
. We get full editor and intellisense support. In ourPage.cshml
we can include the results.This happens during design - the file content is modified, triggered manually, by the IDE, or an extension. For example, after Web Essentials compiles a Less file into css, it could also update the pages that reference the css file through design-time directives. Though the end result is much like
@render
, we get a local copy that provides access to the internals, and allows modification if we turn "auto-update" off.Selectors help keep files small. If we just need a couple of styles or functions, we can only copy them.
This would pull the two styles and single function out of the files, and insert them into the page inside
<style>
and<script>
blocks. This can be helpful in building small, self-contained, and lightweight components.Templates
Html Templating is another other possibility. This can be used in regular files or in template/scaffolding engines. An overly simple example is the common label-input-validation set -
<label asp-for="ModelProperty"><input asp-for="ModelProperty"></input><...validationstuff...
There are many ways to approach this, but one could be (in a cshtml)
Templates are like advanced, dynamic Snippets, and can be defined in the page or in shared files. They can auto update, or be manually triggered.
Targeting
When we know we are running a file processor over the file, we can define targets. This can make the processor more efficient, and the file easier to parse. The processor can look for tagged areas to process, or even exclude.
Discussion Scope
This proposal isn't about any of the specific examples, but about the concept of being able to provide information to processes that manipulate code files. And if so, is
@[]
a good construct to use? More and more, we run processes against these files - from built-in formatting processes, to refactoring, to analysis processes. A standard way to communicate with these processors might be valuable.Outside the Proposal
The concept can also extend into other languages.
Though advanced, this could allow things like name refactoring for related items in different technologies. For example, a C# class and Typescript class could have a design-time association. Changing one triggers changes to the other. This is a design-time change - the files are modified directly. The association doesn't exist at compile or run time. This would be a long time coming, but shows possible potential of the overall concept.
The text was updated successfully, but these errors were encountered: