Class: Dugway::Drops::FeaturesDrop
- Defined in:
- lib/dugway/liquid/drops/features_drop.rb
Overview
Provides access to specific account feature flags within Liquid templates, mirroring the behavior of the storefront’s FeaturesDrop but reading configuration from the Dugway store configuration (e.g., dugway.json).
Feature flags can have a default status (enabled or disabled). This status, along with the list of exposed features, opt-ins, and opt-outs, should be defined under a top-level “features” key in the store configuration file, making it a peer to “store” and “customization”.
Example structure expected within the store configuration (e.g., dugway.json): {
"store": { ... },
"customization": { ... },
"features": {
"definitions": {
"theme_bnpl_messaging": "enabled_by_default",
"theme_category_collages": "disabled_by_default"
},
"opt_ins": ["some_opted_in_feature"],
"opt_outs": ["some_opted_out_feature"]
}
} The ‘FeaturesDrop` receives the top-level `features` hash as its `source` via the ThemeDrop.
Usage in Liquid:
{% if features.has_theme_bnpl_messaging %} ... {% endif %}
Note: Liquid might require the trailing '?' depending on context,
but this implementation handles calls without it.
Instance Attribute Summary
Attributes inherited from BaseDrop
Instance Method Summary collapse
-
#before_method(method_or_key) ⇒ Object
Override BaseDrop’s ‘before_method` to intercept `has_…` calls directly.
-
#feature_definitions ⇒ Hash<String, String>
Memoized hash of feature definitions (name => default_status_string) read from the source (store configuration data).
-
#liquid_method_missing(method_name) ⇒ Object
Keep liquid_method_missing for compatibility or explicit Liquid contexts, We keep liquid_method_missing defined as it’s the official Liquid hook, although our ‘before_method` override likely handles most cases in Liquid 3.
-
#opt_ins ⇒ Array<String>
Returns a memoized list of features this account has explicitly opted into, filtered to only include features defined in the definitions.
-
#opt_outs ⇒ Array<String>
Returns a memoized list of features this account has explicitly opted *out of*, filtered to only include features defined in the definitions.
Methods inherited from BaseDrop
#cart, #context=, #error, #errors, #initialize, #method_missing, #store, #theme
Constructor Details
This class inherits a constructor from Dugway::Drops::BaseDrop
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Dugway::Drops::BaseDrop
Instance Method Details
#before_method(method_or_key) ⇒ Object
Override BaseDrop’s ‘before_method` to intercept `has_…` calls directly. This is called by BaseDrop’s ‘method_missing` and allows us to intercept `has_…` calls before BaseDrop tries to resolve them against the source hash.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/dugway/liquid/drops/features_drop.rb', line 74 def before_method(method_or_key) method_str = method_or_key.to_s if method_str.start_with?('has_') # Extract feature name, removing 'has_' prefix and optional trailing '?' # to handle calls like `features.has_feature_name` or `features.has_feature_name?` feature_name = method_str.sub(/^has_/, '').chomp('?') # Check if this feature is defined # If the extracted name doesn't match a defined feature, it's not available. unless feature_definitions.key?(feature_name) return false end # If defined, calculate availability based on defaults and overrides. is_feature_available?(feature_name) else # If it's not a 'has_' method, delegate to BaseDrop's original logic. super(method_or_key) end end |
#feature_definitions ⇒ Hash<String, String>
Memoized hash of feature definitions (name => default_status_string) read from the source (store configuration data).
39 40 41 |
# File 'lib/dugway/liquid/drops/features_drop.rb', line 39 def feature_definitions @feature_definitions ||= source&.fetch('definitions', {}) || {} end |
#liquid_method_missing(method_name) ⇒ Object
Keep liquid_method_missing for compatibility or explicit Liquid contexts, We keep liquid_method_missing defined as it’s the official Liquid hook, although our ‘before_method` override likely handles most cases in Liquid 3. This provides potential compatibility if Liquid internals change or call this directly.
100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/dugway/liquid/drops/features_drop.rb', line 100 def liquid_method_missing(method_name) method_str = method_name.to_s if method_str.start_with?('has_') feature_name = method_str.sub(/^has_/, '').chomp('?') # Check definition and calculate availability, returning false if undefined. feature_definitions.key?(feature_name) ? is_feature_available?(feature_name) : false else # Fallback for non-'has_' methods. super end end |
#opt_ins ⇒ Array<String>
Returns a memoized list of features this account has explicitly opted into, filtered to only include features defined in the definitions.
46 47 48 49 50 51 52 53 54 55 |
# File 'lib/dugway/liquid/drops/features_drop.rb', line 46 def opt_ins return @opt_ins if defined?(@opt_ins) source_opt_ins = source&.fetch('opt_ins', []) || [] # Ensure source data is treated as a Set for efficient intersection source_set = source_opt_ins.respond_to?(:to_set) ? source_opt_ins.to_set : Set.new(Array(source_opt_ins)) # Only keep opt-ins that correspond to defined features @opt_ins = (Set.new(feature_definitions.keys) & source_set).to_a end |
#opt_outs ⇒ Array<String>
Returns a memoized list of features this account has explicitly opted *out of*, filtered to only include features defined in the definitions.
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/dugway/liquid/drops/features_drop.rb', line 60 def opt_outs return @opt_outs if defined?(@opt_outs) source_opt_outs = source&.fetch('opt_outs', []) || [] # Ensure source data is treated as a Set for efficient intersection source_set = source_opt_outs.respond_to?(:to_set) ? source_opt_outs.to_set : Set.new(Array(source_opt_outs)) # Only keep opt-outs that correspond to defined features @opt_outs = (Set.new(feature_definitions.keys) & source_set).to_a end |