{"id":13629425,"url":"https://github.com/ltrzesniewski/RazorBlade","last_synced_at":"2025-04-17T09:33:48.213Z","repository":{"id":60733427,"uuid":"533033648","full_name":"ltrzesniewski/RazorBlade","owner":"ltrzesniewski","description":"Compile Razor templates at build-time without a dependency on ASP.NET.","archived":false,"fork":false,"pushed_at":"2025-04-05T19:53:39.000Z","size":364,"stargazers_count":159,"open_issues_count":0,"forks_count":7,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-12T00:58:20.265Z","etag":null,"topics":["razor","template"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ltrzesniewski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-09-05T19:28:10.000Z","updated_at":"2025-04-05T19:53:43.000Z","dependencies_parsed_at":"2023-02-07T06:06:59.914Z","dependency_job_id":"20e79bc3-3a20-44f4-b7e2-f95859e179f5","html_url":"https://github.com/ltrzesniewski/RazorBlade","commit_stats":{"total_commits":151,"total_committers":4,"mean_commits":37.75,"dds":"0.019867549668874163","last_synced_commit":"eca1d89972fd5a3311f5921d9753fc948516576c"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ltrzesniewski%2FRazorBlade","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ltrzesniewski%2FRazorBlade/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ltrzesniewski%2FRazorBlade/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ltrzesniewski%2FRazorBlade/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ltrzesniewski","download_url":"https://codeload.github.com/ltrzesniewski/RazorBlade/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249323748,"owners_count":21251226,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["razor","template"],"created_at":"2024-08-01T22:01:10.233Z","updated_at":"2025-04-17T09:33:48.204Z","avatar_url":"https://github.com/ltrzesniewski.png","language":"C#","funding_links":[],"categories":["Content"],"sub_categories":["17. [RazorBlade](https://ignatandrei.github.io/RSCG_Examples/v2/docs/RazorBlade) , in the [Templating](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#templating) category"],"readme":"# RazorBlade                       \u003cpicture\u003e\u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"icon-dark.png\"\u003e\u003cimg src=\"icon.png\" align=\"right\" alt=\"Logo\"\u003e\u003c/picture\u003e\n\n[![Build](https://github.com/ltrzesniewski/RazorBlade/workflows/Build/badge.svg)](https://github.com/ltrzesniewski/RazorBlade/actions?query=workflow%3ABuild)\n[![NuGet package](https://img.shields.io/nuget/v/RazorBlade.svg?logo=NuGet)](https://www.nuget.org/packages/RazorBlade)\n[![GitHub release](https://img.shields.io/github/release/ltrzesniewski/RazorBlade.svg?logo=GitHub)](https://github.com/ltrzesniewski/RazorBlade/releases)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ltrzesniewski/RazorBlade/blob/master/LICENSE)\n\n**Compile Razor templates at build-time without a dependency on ASP.NET.**\n\nRazorBlade is meant to be *lightweight* and *self-contained*: cshtml files are compiled into C# classes at build-time with a Roslyn source generator. No reference to ASP.NET is required.\n\nA simple base class library is provided by default, but it can also be embedded into the target project, or even replaced by your own implementation.\n\n## Usage\n\nThis package will generate a template class for every `.cshtml` file in your project.\n\nThe generated classes will inherit from `RazorBlade.HtmlTemplate` by default, though it is advised to specify the base class explicitly to get the best IDE experience:\n\n\u003c!-- snippet: EmptyTemplate.cshtml --\u003e\n\u003ca id='snippet-EmptyTemplate.cshtml'\u003e\u003c/a\u003e\n```cshtml\n@inherits RazorBlade.HtmlTemplate\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/EmptyTemplate.cshtml#L1-L1' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-EmptyTemplate.cshtml' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\nA version with a model is also available for convenience. The following will add a `Model` property and a constructor with a `ModelType` parameter:\n\n\u003c!-- snippet: EmptyTemplateWithModel.cshtml --\u003e\n\u003ca id='snippet-EmptyTemplateWithModel.cshtml'\u003e\u003c/a\u003e\n```cshtml\n@inherits RazorBlade.HtmlTemplate\u003cMyApplication.ModelType\u003e\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/EmptyTemplateWithModel.cshtml#L1-L1' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-EmptyTemplateWithModel.cshtml' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\nPlease note that this will cause a constructor with a `ModelType` parameter to be added to the generated class, which may cause false errors to be shown in some IDEs.\n\nFurther [documentation](#Documentation) is provided below.\n\n## Example\n\nThe following template, in the `ExampleTemplate.cshtml` file:\n\n\u003c!-- snippet: ExampleTemplate.cshtml --\u003e\n\u003ca id='snippet-ExampleTemplate.cshtml'\u003e\u003c/a\u003e\n```cshtml\n@inherits RazorBlade.HtmlTemplate\n\nHello, \u003ci\u003e@Name\u003c/i\u003e!\n\n@functions\n{\n    public string? Name { get; init; }\n}\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/ExampleTemplate.cshtml#L1-L8' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-ExampleTemplate.cshtml' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\nWill generate the following class in your project:\n\n```cs\ninternal partial class ExampleTemplate : RazorBlade.HtmlTemplate\n{\n    // ...\n    public string? Name { get; init; }\n    // ...\n}\n```\n\nThat you can use like the following:\n\n\u003c!-- snippet: ExampleTemplate.Usage --\u003e\n\u003ca id='snippet-ExampleTemplate.Usage'\u003e\u003c/a\u003e\n```cs\nvar template = new ExampleTemplate\n{\n    Name = \"World\"\n};\n\nvar result = template.Render();\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/Examples.cs#L13-L22' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-ExampleTemplate.Usage' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\n### With a model\n\nA similar template with a model would be:\n\n\u003c!-- snippet: TemplateWithModel.cshtml --\u003e\n\u003ca id='snippet-TemplateWithModel.cshtml'\u003e\u003c/a\u003e\n```cshtml\n@using MyApplication\n@inherits RazorBlade.HtmlTemplate\u003cGreetingModel\u003e\n\nHello, \u003ci\u003e@Model.Name\u003c/i\u003e!\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/TemplateWithModel.cshtml#L1-L4' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-TemplateWithModel.cshtml' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\nInstantiating the generated class requires a model argument:\n\n\u003c!-- snippet: TemplateWithModel.Usage --\u003e\n\u003ca id='snippet-TemplateWithModel.Usage'\u003e\u003c/a\u003e\n```cs\nvar model = new GreetingModel { Name = \"World\" };\nvar template = new TemplateWithModel(model);\nvar result = template.Render();\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/Examples.cs#L27-L33' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-TemplateWithModel.Usage' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\nSince this generates a constructor with a `GreetingModel` parameter in the `TemplateWithModel` class, it may cause false errors to be shown in some IDEs, as they don't recognize this constructor signature.\n\n### With a manual model property\n\nAnother way of implementing a template with a model is to add a `Model` property in the template and mark it as `required`. This will work around false errors which can be shown in some IDEs.\n\n\u003c!-- snippet: TemplateWithManualModel.cshtml --\u003e\n\u003ca id='snippet-TemplateWithManualModel.cshtml'\u003e\u003c/a\u003e\n```cshtml\n@using MyApplication\n@inherits RazorBlade.HtmlTemplate\n\nHello, \u003ci\u003e@Model.Name\u003c/i\u003e!\n\n@functions\n{\n    public required GreetingModel Model { get; init; }\n}\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/TemplateWithManualModel.cshtml#L1-L9' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-TemplateWithManualModel.cshtml' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\nInstantiating the generated class is done similarly to the previous example:\n\n\u003c!-- snippet: TemplateWithManualModel.Usage --\u003e\n\u003ca id='snippet-TemplateWithManualModel.Usage'\u003e\u003c/a\u003e\n```cs\nvar model = new GreetingModel { Name = \"World\" };\nvar template = new TemplateWithManualModel { Model = model };\nvar result = template.Render();\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/Examples.cs#L38-L44' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-TemplateWithManualModel.Usage' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\n## Documentation\n\n### Base template classes\n\nFor HTML templates, specify one of the following base classes with an `@inherits` directive:\n\n- `RazorBlade.HtmlTemplate`\n- `RazorBlade.HtmlTemplate\u003cTModel\u003e`\n- `RazorBlade.HtmlTemplateWithLayout\u003cTLayout\u003e` (automatically applies the given layout)\n- `RazorBlade.HtmlLayout` (for layouts only)\n\nIf you'd like to write a plain text template (which never escapes HTML), the following classes are available:\n\n- `RazorBlade.PlainTextTemplate`\n- `RazorBlade.PlainTextTemplate\u003cTModel\u003e`\n\nThey all derive from `RazorBlade.RazorTemplate`, which provides the base functionality.\n\nYou can also write your own base classes. Marking a constructor with `[TemplateConstructor]` will forward it to the generated template class. \n\n### Writing templates\n\nHTML escaping can be avoided by using the `@Html.Raw(value)` method, just like in ASP.NET. The `IEncodedContent` interface represents content which does not need to be escaped. The `HtmlString` class is a simple implementation of this interface.\n\nTemplates can be included in other templates by evaluating them, since they implement `IEncodedContent`. For instance, a `Footer` template can be included by writing `@(new Footer())`. Remember to always create a new instance of the template to include, even if it doesn't contain custom code, as templates are stateful and not thread-safe.\n\nThe namespace of the generated class can be customized with the `@namespace` directive. The default value is deduced from the file location.\n\n### Layouts\n\nLayout templates may be written by inheriting from the `RazorBlade.HtmlLayout` class, which provides the relevant methods such as `RenderBody` and `RenderSection`. It inherits from `RazorBlade.HtmlTemplate`.\n\nThe layout to use can be specified by overriding the `CreateLayout` method of `RazorBlade.HtmlTemplate`. Given that all Razor templates are stateful and not thread-safe, always create a new instance of the layout page to use:\n\n\u003c!-- snippet: TemplateWithLayout.Usage --\u003e\n\u003ca id='snippet-TemplateWithLayout.Usage'\u003e\u003c/a\u003e\n```cshtml\n@functions\n{\n    protected override HtmlLayout? CreateLayout()\n        =\u003e new LayoutToUse();\n}\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/TemplateWithLayout.cshtml#L2-L8' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-TemplateWithLayout.Usage' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\nThis can be simplified by using the `HtmlTemplateWithLayout\u003cTLayout\u003e` class, which can be useful in `_ViewImports.cshtml` files:\n\n\u003c!-- snippet: TemplateWithLayoutFromBase.cshtml --\u003e\n\u003ca id='snippet-TemplateWithLayoutFromBase.cshtml'\u003e\u003c/a\u003e\n```cshtml\n@inherits RazorBlade.HtmlTemplateWithLayout\u003cLayoutToUse\u003e\n```\n\u003csup\u003e\u003ca href='/src/RazorBlade.IntegrationTest/Examples/TemplateWithLayoutFromBase.cshtml#L1-L1' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-TemplateWithLayoutFromBase.cshtml' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\nLayout pages can be nested, and can use sections. Unlike in ASP.NET, RazorBlade does not verify if the body and all sections have been used. Sections may also be executed multiple times.\n\n\u003e [!NOTE]  \n\u003e Layout usage is not compatible with direct output to the provided `TextWriter` and will cause buffering.  \n\u003e You may work around it by replacing layouts with partial templates such as:\n\u003e \n\u003e ```cshtml\n\u003e @(new Header())\n\u003e Your content\n\u003e @(new Footer())\n\u003e ```\n\n### Import files: `_ViewImports.cshtml`\n\nRazorBlade automatically applies the [`_ViewImports.cshtml` files](https://learn.microsoft.com/en-us/aspnet/core/mvc/views/layout#importing-shared-directives) from the project root to the given template directory.\n\nThese files can define default values for `@using`, `@inherits` and `@namespace`. For instance, an `@inherits RazorBlade.HtmlTemplateWithLayout\u003cLayoutToUse\u003e` directive in a `_ViewImports.cshtml` file will set a common default layout type for the templates in its directory and subdirectories.\n\n### Executing templates\n\nThe `RazorTemplate` base class provides `Render` and `RenderAsync` methods to execute the template.\n\nTemplates are stateful and not thread-safe, so it is advised to always create new instances of the templates to render.\n\n### MSBuild\n\nThe source generator will process `RazorBlade` MSBuild items which have the `.cshtml` file extension.\n\nBy default, all `.cshtml` files are included, unless one of the `EnableDefaultRazorBladeItems` or `EnableDefaultItems` properties are set to `false`. You can also manually customize this set.\n\n**Available property settings:**\n\n- `EnableDefaultRazorBladeItems`: Whether to automatically include all `.cshtml` files in the project. Default is `true`.\n- `RazorBladeDefaultAccessibility`: The default accessibility of the generated classes (`internal` or `public`). Default is `internal`.\n- `RazorBladeEmbeddedLibrary`: Whether to embed the RazorBlade library in the target project (see below). Default is `false`.\n\n**Available item metadata settings:**\n\n- `Accessibility`: The accessibility of the generated class (`internal` or `public`). Default is `$(RazorBladeDefaultAccessibility)`.\n\n### Removing the dependency on RazorBlade\n\nRazorBlade makes it possible to remove the dependency on its runtime assembly. This could be useful for library projects which should be self-contained, with no dependencies on external packages.\n\nThis mode is enabled by default when the `PackageReference` of RazorBlade has the `PrivateAssets=\"all\"` attribute. In order to avoid compilation warnings, the assembly reference also needs to be explicitly excluded with `ExcludeAssets=\"compile;runtime\"`.\n\n```XML\n\u003cPackageReference Include=\"RazorBlade\" Version=\"...\" ExcludeAssets=\"compile;runtime\" PrivateAssets=\"all\" /\u003e\n```\n\nA source generator will then embed an `internal` version of the RazorBlade library in the target project. This behavior can also be controlled by setting the `RazorBladeEmbeddedLibrary` MSBuild property to `true` or `false`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fltrzesniewski%2FRazorBlade","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fltrzesniewski%2FRazorBlade","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fltrzesniewski%2FRazorBlade/lists"}