Class: Woods::Extractors::ViewEngines::Base Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/woods/extractors/view_engines/base.rb

Overview

This class is abstract.

Abstract base class documenting the TemplateEngine contract that Woods::Extractors::ViewTemplateExtractor dispatches to.

Concrete engines (e.g. Erb, and future HAML / Slim / Turbo implementations) subclass Base and override the abstract methods. The orchestrator consults the engine collection via Woods::Extractors::ViewTemplateExtractor::ENGINES, finds the first engine whose #handles? returns true for a file, and delegates scanning and partial-identifier resolution to that engine.

#parse is an optional per-engine memoization seam: engines whose parse step is expensive (e.g. HAML / Slim compiling through Temple) can override it to return an internal IR and call it once before the three scan operations. ERB and Turbo Streams, whose scanners regex raw source, leave the identity default in place. The orchestrator does not invoke #parse — engines opt in internally when it pays off.

Direct Known Subclasses

Erb

Instance Method Summary collapse

Instance Method Details

#extensionsArray<String>

File extensions this engine handles, each including the leading dot (e.g. ‘.html.erb`).

Returns:

  • (Array<String>)

Raises:

  • (NotImplementedError)


41
42
43
# File 'lib/woods/extractors/view_engines/base.rb', line 41

def extensions
  raise NotImplementedError, "#{self.class.name} must implement #extensions"
end

#handles?(file_path) ⇒ Boolean

Whether this engine handles the given file path. The default implementation suffix-matches against #extensions; engines with more elaborate discrimination (e.g. looking at file content) can override.

Parameters:

  • file_path (String)

Returns:

  • (Boolean)


52
53
54
# File 'lib/woods/extractors/view_engines/base.rb', line 52

def handles?(file_path)
  extensions.any? { |ext| file_path.end_with?(ext) }
end

#nameSymbol

Stable engine identifier surfaced through Woods::Extractors::ViewTemplateExtractor.supported_template_engines and the MCP ‘structure` tool.

Returns:

  • (Symbol)

Raises:

  • (NotImplementedError)


33
34
35
# File 'lib/woods/extractors/view_engines/base.rb', line 33

def name
  raise NotImplementedError, "#{self.class.name} must implement #name"
end

#parse(source) ⇒ Object

Optional memoization hook for engines whose parse step is expensive. Default is identity — returns the source string unchanged — so engines that scan raw source (ERB, Turbo Streams) pay no overhead. HAML/Slim implementations can override to compile once and cache an internal IR, then call #parse inside their own #scan_partials / #scan_instance_variables / #scan_helpers.

The orchestrator does not invoke this method; it is a convention for engine-internal reuse.

Parameters:

  • source (String)

    Template source code

Returns:

  • (Object)

    An engine-private IR, or the source itself



69
70
71
# File 'lib/woods/extractors/view_engines/base.rb', line 69

def parse(source)
  source
end

#resolve_partial_identifier(_partial_name, _current_identifier) ⇒ String

Resolve a partial name (as it appeared in a render call) to the file identifier of the partial template. Engines own this because the filename convention is engine-specific: ERB looks for ‘_foo.html.erb`, HAML for `_foo.html.haml`, etc.

Parameters:

  • partial_name (String)

    The partial name from the render call

  • current_identifier (String)

    Identifier of the template issuing the render, used to anchor relative partial names

Returns:

  • (String)

Raises:

  • (NotImplementedError)


114
115
116
117
# File 'lib/woods/extractors/view_engines/base.rb', line 114

def resolve_partial_identifier(_partial_name, _current_identifier)
  raise NotImplementedError,
        "#{self.class.name} must implement #resolve_partial_identifier"
end

#scan_helpers(_source) ⇒ Array<String>

Helper method names detected in the template source, returned sorted. The set of “helpers” is engine-defined — ERB scans for the common Rails view-helper vocabulary, HAML/Slim would scan the same vocabulary in their own syntaxes.

Parameters:

  • source (String)

    Template source code

Returns:

  • (Array<String>)

Raises:

  • (NotImplementedError)


101
102
103
# File 'lib/woods/extractors/view_engines/base.rb', line 101

def scan_helpers(_source)
  raise NotImplementedError, "#{self.class.name} must implement #scan_helpers"
end

#scan_instance_variables(_source) ⇒ Array<String>

Instance-variable names referenced in the template source, returned sorted and deduplicated (including the leading ‘@`).

Parameters:

  • source (String)

    Template source code

Returns:

  • (Array<String>)

Raises:

  • (NotImplementedError)


90
91
92
# File 'lib/woods/extractors/view_engines/base.rb', line 90

def scan_instance_variables(_source)
  raise NotImplementedError, "#{self.class.name} must implement #scan_instance_variables"
end

#scan_navigation_candidates(_source) ⇒ Array<Hash>

Route-helper references found in the template source. Each candidate is a hash shaped ‘{ helper: ’posts_path’, via: Symbol }‘ where `via` is typically `:link_to` or `:form_action`. The orchestrator resolves each candidate’s ‘helper` to a controller target via RouteHelperResolver — engines do NOT need to know about Rails route state, they only surface raw helper calls from the source in whatever way their syntax requires.

Engines matter here because form-call syntax differs across engines (e.g. ERB’s ‘<%= form_with … %>` vs. HAML’s ‘= form_with …`); returning candidates rather than resolved edges keeps Rails-coupled logic off the engine.

Parameters:

  • source (String)

    Template source code

Returns:

  • (Array<Hash>)

Raises:

  • (NotImplementedError)


134
135
136
137
# File 'lib/woods/extractors/view_engines/base.rb', line 134

def scan_navigation_candidates(_source)
  raise NotImplementedError,
        "#{self.class.name} must implement #scan_navigation_candidates"
end

#scan_partials(_source) ⇒ Array<String>

Partial names referenced by render calls in the given source. Returns the raw partial names as they appear in render calls (e.g. ‘’comments/comment’‘, `’sidebar’‘, `’header’‘); the orchestrator calls #resolve_partial_identifier per entry to translate each into a canonical file identifier.

Parameters:

  • source (String)

    Template source code

Returns:

  • (Array<String>)

Raises:

  • (NotImplementedError)


81
82
83
# File 'lib/woods/extractors/view_engines/base.rb', line 81

def scan_partials(_source)
  raise NotImplementedError, "#{self.class.name} must implement #scan_partials"
end