feat: allow hash keys to be resolved as template attributes#354
Open
papilip wants to merge 1 commit into
Open
Conversation
This makes it possible to access hash values using {{ my_hash.my_key }}
in templates, in addition to the standard hash methods (empty?, size, etc.).
Previously, only methods listed in template_attributes were accessible.
Hash keys were silently ignored, resulting in empty values in templates
with no error raised — a common pitfall when passing Hash(String, String)
to template contexts.
The key lookup takes precedence over standard attributes, with a fallback
to the original resolve_template_attribute for methods like size, keys, etc.
ellmetha
reviewed
Apr 19, 2026
Comment on lines
+12
to
+16
| if has_key?(key) | ||
| self[key] | ||
| else | ||
| previous_def | ||
| end |
Member
There was a problem hiding this comment.
Unfortunately, this change has serious limitations. If a hash contains a key like size, then it will be impossible to get the size from the hash when calling {{ my_hash.size }}. Similarly, any other method specified in #template_attributes will only work as long as a key with the same name is not part of the hash.
I think that we should give access to hash methods with priority over keys. That said, I don't want to allow hash key lookups if there is not a built-in way to actually do key lookups for keys such as "size".
The real way forward would be to add both support for dotted access and bracket access (eg. {{ my_hash["size"] }}).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Allow
Hashkeys to be used as template attributes, so that{{ my_hash.my_key }}resolves to the value associated withmy_key.Before: Only methods listed in
template_attributes(likeempty?,size,keys) were accessible. Hash keys were silently ignored, resulting in empty values with no error — a common pitfall.After: Hash keys are resolved first, with a fallback to the standard
template_attributesmethods.Motivation
When passing a
Hash(String, String)to a template context:Users expect
{{ item.type }}to outputorder. Instead, it silently outputs nothing becauseHashonly exposes methods likeempty?andsizeto the template engine.This is particularly confusing because:
NamedTupleworks as expected viaObject::AutoObject::Auto)Changes
src/marten/template/ext/hash.cr: Overrideresolve_template_attributeto checkhas_key?(key)before falling back to the macro-generated methodspec/marten/template/ext/hash_spec.cr: 4 new tests covering key access, fallback to standard attributes, and error on unknown keysTest plan
sizeattribute still works when a key namedsizedoes not exist (fallback)UnknownVariableis raised for non-existent keys that are not standard attributes