Skip to content

Herb: Implement Action View Helper Registry#1611

Merged
marcoroth merged 1 commit intomainfrom
actionview-helper-registry
Apr 5, 2026
Merged

Herb: Implement Action View Helper Registry#1611
marcoroth merged 1 commit intomainfrom
actionview-helper-registry

Conversation

@marcoroth
Copy link
Copy Markdown
Owner

@marcoroth marcoroth commented Apr 5, 2026

This pull request introduces a comprehensive Action View Helper Registry, a single source of truth for all Rails view helper methods, generated across C, TypeScript, Ruby, Java, and Rust from individual YAML configuration files.

Motivation

Previously, metadata about Action View helpers (signatures, documentation URLs, tag mappings, options) was scattered across multiple hand-written files:

  • C handler files (image_tag.c, link_to.c, etc.) with hardcoded detect/extract functions
  • A hand-written TypeScript file in the language server (action_view_helpers.ts)
  • Hardcoded source strings in linter rules and rewriter code

Adding or modifying a helper required touching 3+ files across multiple languages. There was no central place to answer "what helpers exist?" or "what does this helper produce?"

Additionally, for the precompilation and reactivity it is important to understand which built-in helpers are being used in a template, so that we can either handle it accordingly, or warn/error when we see the usage of one of these helpers in the compilation step for reactive templates.

What changed

Registry data (config/action_view_helpers/)

YAML files organized by gem and module:

config/action_view_helpers/
  actionview/           (187 helpers)
    url_helper/           link_to, button_to, mail_to, ...
    asset_tag_helper/     image_tag, video_tag, ...
    form_tag_helper/      text_field_tag, select_tag, ...
    form_helper/          form_with, text_field, ...
    text_helper/          truncate, highlight, ...
    ...
  actionpack/           (6 helpers)
    polymorphic_routes/   polymorphic_url, polymorphic_path
    ...
  turbo-rails/          (16 helpers)
  actioncable/          (1 helper)
  actiontext/           (3 helpers)

Code generation (templates/template.rb)

New classes (HelperType, HelperTagInfo, HelperContent, HelperSpecialBehavior, etc.) parse the YAML and feed 8 ERB templates that generate:

  • C: helper_registry.h/c (type enum, registry struct, lookup functions) + generated_handlers.c/h (detect, extract_tag_name, extract_content functions for all supported helpers)
  • TypeScript: action-view-helpers.ts (enum, interfaces, registry maps, scoped query functions)
  • Ruby: helper_registry.rb (typed classes, registry module with lookup methods, scoped queries)
  • Java: HelperRegistry.java (enum, entry class, static registry)
  • Rust: action_view_helpers.rs (enum, structs, lookup functions)

Generated C handlers replace hand-written code

6 of 7 supported helpers now have their detect, extract_tag_name, extract_content, and supports_block functions generated from YAML instead of hand-written. The individual .c files
(image_tag.c, turbo_frame_tag.c, etc.) were stripped down to only their unique helper-specific functions (src extraction, path wrapping, id wrapping). Only link_to.c retains its hand-written transform
due to complex href/route-helper logic.

Language server improvements

  • Hover for all helpers: Hovering over any of the registered helpers in ERB shows signature, description, and documentation link, not just the 7 supported ones
  • Nested helper hover: Hovering over dom_id inside <%= turbo_frame_tag dom_id(user) do %> shows dom_id's documentation
  • Registry-driven lookups: HELPER_BY_SOURCE, HELPERS_BY_TAG_NAME, findPreferredHelperForTag() replace all hardcoded source strings
CleanShot.2026-04-05.at.19.31.21.mp4

Consumer code updates

  • Linter: erb-no-javascript-tag-helper, html-require-script-nonce, a11y-no-autofocus-attribute now use registry lookups instead of hardcoded strings
  • Rewriter: html-to-action-view-tag-helper uses findPreferredHelperForTag() and HELPER_REGISTRY for tag-to-helper mapping
  • Language server: hover_service.ts and rewrite_code_action_service.ts use registry for all helper resolution

Deleted

  • javascript/packages/language-server/src/action_view_helpers.ts replaced by generated @herb-tools/core export
  • src/analyze/action_view/content_tag.c fully generated
  • src/analyze/action_view/tag.c fully generated

Copy link
Copy Markdown

@github-advanced-security github-advanced-security AI left a comment

Choose a reason for hiding this comment

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

CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

@marcoroth marcoroth force-pushed the actionview-helper-registry branch from 9eae332 to c25e3ac Compare April 5, 2026 06:22
@marcoroth marcoroth added this to the v1.0.0 milestone Apr 5, 2026
@marcoroth marcoroth force-pushed the actionview-helper-registry branch 2 times, most recently from 9607ba5 to 70a3f77 Compare April 5, 2026 06:31
@github-actions github-actions bot added the node label Apr 5, 2026
@marcoroth marcoroth force-pushed the actionview-helper-registry branch 2 times, most recently from 73f2627 to d2b5a27 Compare April 5, 2026 17:26
Comment thread templates/template.rb Fixed
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 5, 2026

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

commit: 050f94a

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 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 050f94a


✅ Preview deployment has been cleaned up.

@marcoroth marcoroth force-pushed the actionview-helper-registry branch from 8354968 to 050f94a Compare April 5, 2026 19:25
@marcoroth marcoroth merged commit 63bca2c into main Apr 5, 2026
32 checks passed
@marcoroth marcoroth deleted the actionview-helper-registry branch April 5, 2026 19:34
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.

2 participants