-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
set context's template_name with template's name #1692
Conversation
This is by design, since we wouldn't want to leak the full file path. Liquid is designed to allow users to design the page without given those users full system access, meaning that we do want to limit the path to the subpath that the user has access to.
Liquid doesn't have the concept of multiple folders, but in practice the partials can end up in a different directory than the template. Once a layout template is introduced, which may be in another folder, then this can easily introduce confusion. As such, it makes sense to have the template name to include the subpath from the root of the directory that the user stores liquid code in. E.g. if they stored their code in a github repo, it could give the path from the root of that repo, as opposed to the subpath for the partials/snippets. |
lib/liquid/tags/include.rb
Outdated
context.template_name = if Template.file_system.respond_to?(:actual_template_name) | ||
Template.file_system.actual_template_name(template_name).delete_suffix('.liquid') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the .delete_suffix('.liquid')
part could be handled in the file system itself.
Also, it would be preferable for this to be cached as part of the PartialCache.load
. In fact, it would be more natural to give the Liquid::Template an attr_accessor :name
, which could be set when loading the template from a template factory. PartialCache.load
could then set template.name ||= template_name
to preserve this existing behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other reason having a Template#name property would be useful is that it could be used as part of given a name to the initial template. I think we could provide that as a parse option, then Template#render can set context.template_name = template.name if template.name
. I think that would make it easy to set the top-level template name so that it can be included in error messages.
9a2abd2
to
428c66f
Compare
lib/liquid/partial_cache.rb
Outdated
partial.name ||= if context.registers[:file_system]&.respond_to?(:actual_template_name) | ||
context.registers[:file_system].actual_template_name(template_name) | ||
else | ||
template_name | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the partial.name
can be set in the template factory in applications that want to customize this. That way this can just set the default
partial.name ||= if context.registers[:file_system]&.respond_to?(:actual_template_name) | |
context.registers[:file_system].actual_template_name(template_name) | |
else | |
template_name | |
end | |
partial.name ||= template_name |
lib/liquid/tags/include.rb
Outdated
begin | ||
context.template_name = template_name | ||
context.partial = true | ||
context.template_name = partial.name if partial.name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be set unconditionally. The reason why I was saying to make it conditional in Template#render (if we support a template name parse argument) is to preserve the behaviour of any application that sets Context#template_name on the passed in Context.
context.template_name = partial.name if partial.name | |
context.template_name = partial.name |
lib/liquid/tags/render.rb
Outdated
@@ -76,7 +76,9 @@ def render_tag(context, output) | |||
|
|||
render_partial_func = ->(var, forloop) { | |||
inner_context = context.new_isolated_subcontext | |||
inner_context.template_name = template_name | |||
|
|||
inner_context.template_name = partial.name if partial.name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inner_context.template_name = partial.name if partial.name | |
inner_context.template_name = partial.name |
5dba73b
to
0502673
Compare
0502673
to
24dceef
Compare
Problem
When Liquid is used with a
FileSystem
that allowsrender
andinclude
tags to render a file just by its filename, the error message does not show its actual file path.setup:
output:
This becomes an issue when Liquid developers have duplicate filenames in multiple folders, which creates confusion where the error is actually coming from.
Solution
In
render
andinclude
tag, it will set thecontext.template
withtemplate.name
.The Liquid users can use
TemplateFactory
to create aTemplate
with a name: