Skip to content

Add configurable DefaultFileExtension to TemplateOptions - #858

Merged
sebastienros merged 2 commits into
mainfrom
copilot/add-custom-file-extensions
Nov 16, 2025
Merged

Add configurable DefaultFileExtension to TemplateOptions#858
sebastienros merged 2 commits into
mainfrom
copilot/add-custom-file-extensions

Conversation

Copilot AI commented Nov 16, 2025

Copy link
Copy Markdown
Contributor

Currently {% render %} and {% include %} tags only look for files with .liquid extension, preventing IDE syntax highlighting for templates with extensions like .html or .css.

Changes

  • TemplateOptions: Added DefaultFileExtension property (defaults to .liquid for backward compatibility)
  • RenderStatement & IncludeStatement: Modified file resolution to:
    1. Try exact filename first
    2. Append DefaultFileExtension if file not found and extension is set
    3. Use filename as-is if DefaultFileExtension is null/empty

Usage

// Use .html extension for IDE support
var options = new TemplateOptions 
{ 
    FileProvider = fileProvider,
    DefaultFileExtension = ".html" 
};

// Now works with both:
{% include 'template' %}        // Resolves to template.html
{% include 'other.html' %}      // Uses explicit extension

// Disable extension appending
options.DefaultFileExtension = null;
{% include 'template' %}        // Uses exact name 'template'

Explicit extensions in template names take precedence over the default. The .liquid default preserves existing security boundaries.

Original prompt

This section details on the original issue you should resolve

<issue_title>{% render "filename" %} with custom extensions</issue_title>
<issue_description>Currently, {% render "filename" %} will only look for a file called filename.liquid. However, would be great to make it use the IFileProvider to figure out the proper file, allowing users to customize this behavior.

It's particularly good if the liquid template is actually creating a known format in IDE, like HTML, CSS. Using the destination format extension like filename.html, filename.css, filename.liquid.html would allow the IDE to highlight the code properly.

it's somewhat related to #357

probable targets:

  • Fluid/Ast/RenderStatement.cs
  • Fluid/Ast/IncludeStatement.cs</issue_description>

<agent_instructions>Add a string DefaultFileExtension { get; set; } = ".liquid"; to TemplateOptions. If it's defined then any FileProvider usage should first check if the extension is used or add it (today's behavior). If it's null/empty then the filename can be used as-is.

</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@hishamco I think it's fine to keep it as its. In your case, you can customize `FluidMvcViewOptions` @sebastienros There is already an `IFileProvider` in the general options:

https://github.com/sebastienros/fluid/blob/main/Fluid/TemplateOptions.cs#L19-L22

So you can set it as default options or per template (in TemplateContext). You can provide a custom implementation of IFileProvider to return the stream you want to use for any filename. Can you try them and let us know if that works?</comment_new>
<comment_new>@sebastienros
@brmassa What about a DefaultLiquidExtension property set to .liquid that would be used if the specific file is not found. This wouldn't break the current behavior.

A concern I have is for security reasons, where one could request a file that is not liquid... The .liquid helping limit what types of files can be read.</comment_new>
<comment_new>@sebastienros

I don't see much risk on inputting an arbitrary file
File extensions don't prevent anything.

I believe there is already a limitation to only include files that don't escape the root of the FileProvider. But even in this case allowing any extension could mean accessing security sensitive information, like other templates, configuration files, data files ... It could be anything so it's potentially a risk. Adding .liquid is mitigating it by only allowing something that is templatable. Be aware that the include tag accepts variables, and this could be compromised in that case.

But with all these concerns I also thing it's fine, and opt-in. If you can create a PR that adds string DefaultFileExtension { get; set; } = ".liquid"; to TemplateOptions. If it's defined then any FileProvider usage should first check if the extension is used or add it (today's behavior). If it's null/empty then the filename can be used as-is. </comment_new>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI self-assigned this Nov 16, 2025
…nsion support

Co-authored-by: sebastienros <1165805+sebastienros@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for custom file extensions in render statement Add configurable DefaultFileExtension to TemplateOptions Nov 16, 2025
Copilot AI requested a review from sebastienros November 16, 2025 06:53
@sebastienros
sebastienros marked this pull request as ready for review November 16, 2025 19:00
@sebastienros
sebastienros enabled auto-merge (squash) November 16, 2025 19:00
@sebastienros
sebastienros merged commit aed211b into main Nov 16, 2025
6 checks passed
@sebastienros
sebastienros deleted the copilot/add-custom-file-extensions branch November 16, 2025 19:03
sebastienros added a commit that referenced this pull request Aug 20, 2026
* Initial plan

* Add DefaultFileExtension property to TemplateOptions with custom extension support

Co-authored-by: sebastienros <1165805+sebastienros@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sebastienros <1165805+sebastienros@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ee9c8775-0354-41dd-8226-89a69c60241c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

{% render "filename" %} with custom extensions

2 participants