Class: Rhales::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/rhales/context.rb

Overview

RSFCContext provides a clean interface for RSFC templates to access server-side data. Follows the established pattern from InitScriptContext and EnvironmentContext for focused, single-responsibility context objects.

The context provides two layers of data:

  1. App: Framework-provided data (CSRF tokens, authentication, config)

  2. Props: Application data passed to the view (user, content, features)

App data is accessible as both direct variables and through the app.* namespace. Props take precedence over app data for variable resolution.

One RSFCContext instance is created per page render and shared across the main template and all partials to maintain security boundaries.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(req, sess = nil, cust = nil, locale_override = nil, props: {}, config: nil) ⇒ Context

Returns a new instance of Context.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rhales/context.rb', line 26

def initialize(req, sess = nil, cust = nil, locale_override = nil, props: {}, config: nil)
  @req           = req
  @sess          = sess || default_session
  @cust          = cust || default_customer
  @config        = config || Rhales.configuration
  @locale        = locale_override || @config.default_locale

  # Normalize props keys to strings for consistent access
  @props = normalize_keys(props).freeze

  # Build context layers (two-layer model: app + props)
  @app_data = build_app_data.freeze

  # Pre-compute all_data before freezing
  # Props take precedence over app data, and add app namespace
  @all_data = @app_data.merge(@props).merge({ 'app' => @app_data }).freeze

  # Make context immutable after creation
  freeze
end

Instance Attribute Details

#all_dataObject (readonly)

Get all available data (runtime + business + computed)



81
82
83
# File 'lib/rhales/context.rb', line 81

def all_data
  @all_data
end

#app_dataObject (readonly)

Returns the value of attribute app_data.



24
25
26
# File 'lib/rhales/context.rb', line 24

def app_data
  @app_data
end

#configObject (readonly)

Returns the value of attribute config.



24
25
26
# File 'lib/rhales/context.rb', line 24

def config
  @config
end

#custObject (readonly)

Returns the value of attribute cust.



24
25
26
# File 'lib/rhales/context.rb', line 24

def cust
  @cust
end

#localeObject (readonly)

Returns the value of attribute locale.



24
25
26
# File 'lib/rhales/context.rb', line 24

def locale
  @locale
end

#propsObject (readonly)

Returns the value of attribute props.



24
25
26
# File 'lib/rhales/context.rb', line 24

def props
  @props
end

#reqObject (readonly)

Returns the value of attribute req.



24
25
26
# File 'lib/rhales/context.rb', line 24

def req
  @req
end

#sessObject (readonly)

Returns the value of attribute sess.



24
25
26
# File 'lib/rhales/context.rb', line 24

def sess
  @sess
end

Class Method Details

.for_view(req, sess, cust, locale, config: nil, **props) ⇒ Object

Create context with business data for a specific view



230
231
232
# File 'lib/rhales/context.rb', line 230

def for_view(req, sess, cust, locale, config: nil, **props)
  new(req, sess, cust, locale, props: props, config: config)
end

.minimal(props: {}, config: nil) ⇒ Object

Create minimal context for testing



235
236
237
# File 'lib/rhales/context.rb', line 235

def minimal(props: {}, config: nil)
  new(nil, nil, nil, 'en', props: props, config: config)
end

Instance Method Details

#available_variablesObject

Get list of all available variable paths (for validation)



89
90
91
# File 'lib/rhales/context.rb', line 89

def available_variables
  collect_variable_paths(all_data)
end

#get(variable_path) ⇒ Object

Get variable value with dot notation support (e.g., “user.id”, “features.account_creation”)



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rhales/context.rb', line 48

def get(variable_path)
  path_parts    = variable_path.split('.')
  current_value = all_data

  path_parts.each do |part|
    case current_value
    when Hash
      if current_value.key?(part)
        current_value = current_value[part]
      elsif current_value.key?(part.to_sym)
        current_value = current_value[part.to_sym]
      else
        return nil
      end
    when Object
      if current_value.respond_to?(part)
        current_value = current_value.public_send(part)
      elsif current_value.respond_to?("#{part}?")
        current_value = current_value.public_send("#{part}?")
      else
        return nil
      end
    else
      return nil
    end

    return nil if current_value.nil?
  end

  current_value
end

#resolve_variable(variable_path) ⇒ Object

Resolve variable (alias for get method for hydrator compatibility)



94
95
96
# File 'lib/rhales/context.rb', line 94

def resolve_variable(variable_path)
  get(variable_path)
end

#variable?(variable_path) ⇒ Boolean

Check if variable exists

Returns:

  • (Boolean)


84
85
86
# File 'lib/rhales/context.rb', line 84

def variable?(variable_path)
  !get(variable_path).nil?
end