Skip to content

Parser: Support Action View render calls#1385

Merged
marcoroth merged 1 commit intomainfrom
parser-render
Mar 16, 2026
Merged

Parser: Support Action View render calls#1385
marcoroth merged 1 commit intomainfrom
parser-render

Conversation

@marcoroth
Copy link
Owner

@marcoroth marcoroth commented Mar 15, 2026

This pull request adds support for detecting ActionView render calls in ERB templates and representing them as structured ERBRenderNode nodes.

A new render_nodes parser option is available to enable this analysis (defaults to false, since render may mean something different outside of Rails).

When enabled, ERBContentNodes containing a render call are transformed into ERBRenderNodes with extracted fields that mirror ActionView's render keyword arguments.

For example, the following template:

<%= render partial: "card", locals: { title: @title, body: "Hello" } %>

Produces the following with render_nodes: true:

@ DocumentNode (location: (1:0)-(1:71))
└── children: (1 item)
    └── @ ERBRenderNode (location: (1:0)-(1:71))
        ├── tag_opening: "<%=" (location: (1:0)-(1:3))
        ├── content: " render partial: "card", locals: { title: @title, body: "Hello" } " (location: (1:3)-(1:69))
        ├── tag_closing: "%>" (location: (1:69)-(1:71))
        ├── partial: "card" (location: (1:20)-(1:26))
        ├── template_path: 
        ├── layout: 
        ├── file: 
        ├── inline_template: 
        ├── body: 
        ├── plain: 
        ├── html: 
        ├── renderable: 
        ├── collection: 
        ├── object: 
        ├── as: 
        ├── spacer_template: 
        ├── formats: 
        ├── variants: 
        ├── handlers: 
        ├── content_type: 
        └── locals: (2 items)
            ├── @ RubyRenderLocalNode (location: (1:38)-(1:51))
               ├── name: "title" (location: (1:38)-(1:44))└── value: 
                   └── @ RubyLiteralNode (location: (1:45)-(1:51))
                       └── content: "@title"
                       
            └── @ RubyRenderLocalNode (location: (1:53)-(1:66))
                ├── name: "body" (location: (1:53)-(1:58))
                └── value: 
                    └── @ RubyLiteralNode (location: (1:59)-(1:66))
                        └── content: "\"Hello\""

Resolves #1373

Enables #160
Enables #181
Enables #182
Enables #639
Enables #654
Enables #1386

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 16, 2026

npx https://pkg.pr.new/@herb-tools/formatter@1385
npx https://pkg.pr.new/@herb-tools/language-server@1385
npx https://pkg.pr.new/@herb-tools/linter@1385

commit: ade5af9

@github-actions
Copy link

github-actions bot commented Mar 16, 2026

🌿 Interactive Playground and Documentation Preview

A preview deployment has been built for this pull request. Try out the changes live in the interactive playground:


🌱 Grown from commit ade5af9


✅ Preview deployment has been cleaned up.

@marcoroth marcoroth merged commit 0544f50 into main Mar 16, 2026
32 checks passed
@marcoroth marcoroth deleted the parser-render branch March 16, 2026 00:23
@marcoroth marcoroth added this to the v1.0.0 milestone Mar 16, 2026
marcoroth added a commit that referenced this pull request Mar 16, 2026
This pull request adds support for detecting ActionView `render` calls
in ERB templates and representing them as structured `ERBRenderNode`
nodes.

A new `render_nodes` parser option is available to enable this analysis
(defaults to `false`, since `render` may mean something different
outside of Rails).

When enabled, `ERBContentNodes` containing a render call are transformed
into `ERBRenderNodes` with extracted fields that mirror ActionView's
render keyword arguments.

For example, the following template:
```erb
<%= render partial: "card", locals: { title: @title, body: "Hello" } %>
```

Produces the following with `render_nodes: true`:
```js
@ DocumentNode (location: (1:0)-(1:71))
└── children: (1 item)
    └── @ ERBRenderNode (location: (1:0)-(1:71))
        ├── tag_opening: "<%=" (location: (1:0)-(1:3))
        ├── content: " render partial: "card", locals: { title: @title, body: "Hello" } " (location: (1:3)-(1:69))
        ├── tag_closing: "%>" (location: (1:69)-(1:71))
        ├── partial: "card" (location: (1:20)-(1:26))
        ├── template_path: ∅
        ├── layout: ∅
        ├── file: ∅
        ├── inline_template: ∅
        ├── body: ∅
        ├── plain: ∅
        ├── html: ∅
        ├── renderable: ∅
        ├── collection: ∅
        ├── object: ∅
        ├── as: ∅
        ├── spacer_template: ∅
        ├── formats: ∅
        ├── variants: ∅
        ├── handlers: ∅
        ├── content_type: ∅
        └── locals: (2 items)
            ├── @ RubyRenderLocalNode (location: (1:38)-(1:51))
            │   ├── name: "title" (location: (1:38)-(1:44))
            │   └── value:
            │       └── @ RubyLiteralNode (location: (1:45)-(1:51))
            │           └── content: "@title"
            │
            └── @ RubyRenderLocalNode (location: (1:53)-(1:66))
                ├── name: "body" (location: (1:53)-(1:58))
                └── value:
                    └── @ RubyLiteralNode (location: (1:59)-(1:66))
                        └── content: "\"Hello\""
 ```

Resolves #1373

Enables #160
Enables #181
Enables #182
Enables #639
Enables #654
Enables #1386
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parser: Detect ActionView render calls

1 participant