Class: LcpRuby::Display::RendererRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/lcp_ruby/display/renderer_registry.rb

Constant Summary collapse

BUILT_IN_RENDERERS =
{
  "heading"            => "LcpRuby::Display::Renderers::Heading",
  "badge"              => "LcpRuby::Display::Renderers::Badge",
  "collection"         => "LcpRuby::Display::Renderers::Collection",
  "truncate"           => "LcpRuby::Display::Renderers::Truncate",
  "boolean_icon"       => "LcpRuby::Display::Renderers::BooleanIcon",
  "progress_bar"       => "LcpRuby::Display::Renderers::ProgressBar",
  "image"              => "LcpRuby::Display::Renderers::Image",
  "avatar"             => "LcpRuby::Display::Renderers::Avatar",
  "currency"           => "LcpRuby::Display::Renderers::Currency",
  "percentage"         => "LcpRuby::Display::Renderers::Percentage",
  "number"             => "LcpRuby::Display::Renderers::Number",
  "date"               => "LcpRuby::Display::Renderers::Date",
  "datetime"           => "LcpRuby::Display::Renderers::Datetime",
  "relative_date"      => "LcpRuby::Display::Renderers::RelativeDate",
  "email_link"         => "LcpRuby::Display::Renderers::EmailLink",
  "phone_link"         => "LcpRuby::Display::Renderers::PhoneLink",
  "url_link"           => "LcpRuby::Display::Renderers::UrlLink",
  "external_link"      => "LcpRuby::Display::Renderers::UrlLink",
  "boolean"            => "LcpRuby::Display::Renderers::BooleanIcon",
  "email"              => "LcpRuby::Display::Renderers::EmailLink",
  "phone"              => "LcpRuby::Display::Renderers::PhoneLink",
  "url"                => "LcpRuby::Display::Renderers::UrlLink",
  "json"               => "LcpRuby::Display::Renderers::Code",
  "text"               => "LcpRuby::Display::Renderers::Text",
  "color_swatch"       => "LcpRuby::Display::Renderers::ColorSwatch",
  "rating"             => "LcpRuby::Display::Renderers::Rating",
  "code"               => "LcpRuby::Display::Renderers::Code",
  "copy_code"          => "LcpRuby::Display::Renderers::CopyCode",
  "file_size"          => "LcpRuby::Display::Renderers::FileSize",
  "rich_text"          => "LcpRuby::Display::Renderers::RichText",
  "attachment_preview" => "LcpRuby::Display::Renderers::AttachmentPreview",
  "attachment_list"    => "LcpRuby::Display::Renderers::AttachmentList",
  "attachment_link"    => "LcpRuby::Display::Renderers::AttachmentLink",
  "link"               => "LcpRuby::Display::Renderers::Link",
  "markdown"           => "LcpRuby::Display::Renderers::Markdown",
  "internal_link"      => "LcpRuby::Display::Renderers::InternalLink",
  "workflow_badge"     => "LcpRuby::Display::Renderers::WorkflowBadge",
  "workflow_timeline"  => "LcpRuby::Display::Renderers::WorkflowTimeline",
  "count_badge"        => "LcpRuby::Display::CountBadge",
  "text_badge"         => "LcpRuby::Display::TextBadge",
  "icon_badge"         => "LcpRuby::Display::IconBadge",
  "record_link"        => "LcpRuby::Display::Renderers::RecordLink",
  "link_list"          => "LcpRuby::Display::Renderers::LinkList"
}.freeze

Class Method Summary collapse

Class Method Details

.clear!Object



126
127
128
# File 'lib/lcp_ruby/display/renderer_registry.rb', line 126

def clear!
  @registry = {}
end

.discover!(base_path) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/lcp_ruby/display/renderer_registry.rb', line 107

def discover!(base_path)
  renderers_path = File.join(base_path, "renderers")
  return unless File.directory?(renderers_path)

  Dir[File.join(renderers_path, "**", "*.rb")].sort.each do |file|
    require file

    relative = file.sub("#{renderers_path}/", "").sub(/\.rb$/, "")
    class_name = "LcpRuby::HostRenderers::#{relative.split('/').map(&:camelize).join('::')}"

    begin
      renderer_class = class_name.constantize
      register(relative, renderer_class)
    rescue NameError => e
      LcpRuby.record_error(e, subsystem: "renderer", renderer: class_name)
    end
  end
end

.keysObject



95
96
97
# File 'lib/lcp_ruby/display/renderer_registry.rb', line 95

def keys
  registry.keys
end

.register(key, renderer_class) ⇒ Object



87
88
89
# File 'lib/lcp_ruby/display/renderer_registry.rb', line 87

def register(key, renderer_class)
  registry[key.to_s] = renderer_class.new
end

.register_built_ins!Object



99
100
101
102
103
104
105
# File 'lib/lcp_ruby/display/renderer_registry.rb', line 99

def register_built_ins!
  BUILT_IN_RENDERERS.each do |key, class_name|
    register(key, class_name.constantize)
  rescue NameError => e
    LcpRuby.record_error(e, subsystem: "renderer", renderer: class_name)
  end
end

.registered?(key) ⇒ Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/lcp_ruby/display/renderer_registry.rb', line 91

def registered?(key)
  registry.key?(key.to_s)
end

.renderer_for(key) ⇒ Object

Phase 4 of type-system defaults — Decision 4 revised. Resolves a renderer key to a renderer instance via two layers:

  1. Registered renderers (explicit hash lookup) — covers built-in renderer keys (“badge”, “boolean_icon”, “truncate”, …) AND the pre-existing alias entries (‘“boolean” => BooleanIcon`, `“email” => EmailLink`, etc., from BUILT_IN_RENDERERS). This layer wins.

  2. Type-name fallback (new in Phase 4) — when the key isn’t in the registered table, consult Types::TypeRegistry.renderer_for to resolve ‘:enum → “badge”`, `:rating (custom type with base_type: :integer) → its declared renderer`, etc. Re-looks up the resolved key in the registered table to return the actual renderer instance. So `renderer: :enum` in a hand- written presenter resolves to a BadgeRenderer at runtime without anyone having registered “enum” explicitly.

Existing alias precedence is preserved — ‘text → passthrough` (alias) wins over `text → truncate` (type registry’s default for the :text base type) because the alias is in the registered table. Two contexts, same string, two correct answers — explicit alias wins over type-driven default.

Returns nil when neither layer resolves — preserves today’s “unknown renderer” behavior so genuinely-bogus keys still hit the value-shape heuristic in the view template.



77
78
79
80
81
82
83
84
85
# File 'lib/lcp_ruby/display/renderer_registry.rb', line 77

def renderer_for(key)
  return unless key

  registered = registry[key.to_s]
  return registered if registered

  type_renderer_key = Types::TypeRegistry.renderer_for(key.to_s)
  registry[type_renderer_key.to_s] if type_renderer_key
end