Skip to content

Conversation

@osteele
Copy link
Owner

@osteele osteele commented Aug 30, 2025

Checklist

  • I have read the contribution guidelines.
  • make test passes.
  • make lint passes.
  • New and changed code is covered by tests.
  • Performance improvements include benchmarks.
  • Changes match the documented (not just the implemented) behavior of Shopify. -- yes, because new behavior is hidden behind a flag; also, new behavior matches the implemented behavior of Jekyll (which should probably be added to this list)

Description

This PR adds support for Jekyll-compatible dot notation in the {% assign %} tag, allowing nested property assignment like {% assign page.canonical_url = "/about/" %}. This feature is gated behind the JekyllExtensions configuration flag to maintain backward compatibility.

Changes

Core Implementation

  • Extended assign tag syntax: Added support for dot notation in assign statements (e.g., obj.property = value)
  • Grammar updates: Modified the expression parser grammar to support property paths in assignments
  • Context API enhancement: Added SetPath() method to the render context for setting nested values
  • Backward compatibility: Feature is only enabled when JekyllExtensions flag is set to true

Parser Changes

  • Updated expressions.y grammar to parse dot notation in assign targets
  • Modified Assignment struct to include both Variable (for simple assignments) and Path (for dot notation)
  • Regenerated parser files using ragel/goyacc

Safety & Validation

  • Returns clear error message when dot notation is used without Jekyll extensions enabled
  • Automatically creates intermediate objects when setting nested properties
  • Prevents setting properties on non-object types with appropriate error handling

Testing

Comprehensive test coverage has been added in TestAssignTag_JekyllExtensions:

  • ✅ Dot notation works correctly with Jekyll extensions enabled
  • ✅ Dot notation properly fails with clear error message when Jekyll extensions are disabled
  • ✅ Simple assignments continue to work in both modes for backward compatibility
  • ✅ Nested object creation works as expected (e.g., creating new_obj.prop when new_obj doesn't exist)
  • ✅ All existing tests continue to pass

Examples

With Jekyll extensions enabled:

{% assign page.canonical_url = "/about/" %}
{% assign page.meta.description = "Test description" %}
{% assign new_obj.nested.deep = "value" %}

Without Jekyll extensions (standard mode):

{% assign simple_var = "value" %}  // ✅ Works
{% assign obj.prop = "value" %}    // ❌ Error: requires Jekyll extensions

Breaking Changes

None - the feature is opt-in via the JekyllExtensions configuration flag.

@osteele osteele requested a review from Copilot August 30, 2025 02:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds Jekyll-compatible dot notation support for assign tags, allowing syntax like {% assign page.canonical_url = "/about/" %} when Jekyll extensions are enabled. This feature is hidden behind a configuration flag to maintain backward compatibility with standard Shopify Liquid.

Key changes:

  • Added JekyllExtensions configuration option to control dot notation support
  • Modified assign tag parser to handle nested property paths
  • Added SetPath method to render context for setting nested object properties

Reviewed Changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
engine.go Added EnableJekyllExtensions() method to configure Jekyll compatibility
render/config.go Added JekyllExtensions boolean field to Config struct
render/context.go Implemented SetPath method for setting values at nested object paths
expressions/statements.go Extended Assignment struct to support property paths alongside simple variables
expressions/expressions.y Modified grammar to parse dot notation in assign targets
expressions/y.go Generated parser code reflecting grammar changes
tags/standard_tags.go Refactored assign tag to use configuration-aware factory function
tags/standard_tags_test.go Added comprehensive tests for Jekyll extensions functionality
README.md Added documentation for Jekyll compatibility features
Multiple test files Updated function calls to match new AddStandardTags signature

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@osteele osteele force-pushed the feature/assign-dot-notation branch from c8db49d to eceaefa Compare August 30, 2025 04:05
Implements #113 - Support assigning to object properties with dot notation

Changes:
- Updated Assignment struct to support property paths
- Modified parser grammar to accept dot notation (e.g., page.canonical_url)
- Added SetPath method to context for nested property setting
- Updated assignTag to handle both simple and dotted assignments
- Added comprehensive tests for the new functionality

This allows templates to use:
  {% assign page.canonical_url = page.url %}
  {% assign obj.nested.property = value %}

Maintains backward compatibility with simple assignments.
…s flag

Fixes #113 with proper Shopify Liquid compatibility

Changes:
- Added JekyllExtensions flag to render.Config (default: false)
- Added EnableJekyllExtensions() method to Engine API
- Dot notation in assign tags now requires Jekyll extensions to be enabled
- Standard mode (default) maintains strict Shopify Liquid compatibility
- Jekyll mode enables extensions for Jekyll/Gojekyll compatibility

Behavior:
- Standard mode: {% assign obj.prop = value %} is a syntax error
- Jekyll mode: {% assign obj.prop = value %} creates/updates nested properties
- Simple assignments work in both modes: {% assign var = value %}

This approach ensures backward compatibility while allowing Jekyll-specific
features to be enabled when needed for Gojekyll and other Jekyll-compatible
implementations.
@osteele osteele force-pushed the feature/assign-dot-notation branch from 880c139 to 06417ca Compare November 6, 2025 09:59
@osteele osteele merged commit f3dae68 into main Nov 6, 2025
8 checks passed
osteele pushed a commit that referenced this pull request Nov 6, 2025
- Added Unreleased section to CHANGELOG.md with recent features:
  - Jekyll Extensions Support (PR #114)
  - Auto-Escape Feature (PR #111)
  - Modernized Build Tooling (PR #115)
- Added steve-ky as contributor for ideas/feedback on PR #89

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
osteele pushed a commit that referenced this pull request Nov 6, 2025
Updated CHANGELOG.md to include all merged PRs since version 1.3.0 (2020-02-13):

Added features:
- Jekyll Extensions Support (#114)
- Auto-Escape Feature (#111)
- Template Loader (#107)
- BasicEngine (#104)
- JSON Filter (#84)
- Strict Variables Mode (#74)
- Custom Writer Support (#86)
- Template AST Access (#59, #66)
- For-Else Support (#93)
- Unless-Else Support (#68)
- General Range Expressions (#65)
- Loop Modifier Expressions (#67)

Fixes:
- Size filter, slice bounds, division by zero
- Nil pointer handling
- Whitespace control
- Multiline slice
- Block errors
- Map filter with structs
- And more

Also added steve-ky as contributor for ideas/feedback on PR #89.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@osteele osteele deleted the feature/assign-dot-notation branch November 8, 2025 03:13
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.

2 participants