Class: Curlybars::RenderingSupport
- Inherits:
-
Object
- Object
- Curlybars::RenderingSupport
- Defined in:
- lib/curlybars/rendering_support.rb
Instance Method Summary collapse
- #cached_call(meth) ⇒ Object
- #call(helper, helper_path, helper_position, arguments, options, &block) ⇒ Object
- #check_context_is_hash_or_enum_of_presenters(collection, path, position) ⇒ Object
- #check_context_is_presenter(context, path, position) ⇒ Object
- #check_timeout! ⇒ Object
- #coerce_to_hash!(collection, path, position) ⇒ Object
-
#initialize(timeout, contexts, variables, file_name, global_helpers_providers = [], cache = ->(key, &block) { block.call }) ⇒ RenderingSupport
constructor
A new instance of RenderingSupport.
- #optional_presenter_cache(presenter, template_cache_key, buffer) ⇒ Object
- #path(path, position) ⇒ Object
- #position(line_number, line_offset) ⇒ Object
- #presenter?(context) ⇒ Boolean
- #presenter_collection?(collection) ⇒ Boolean
- #to_bool(condition) ⇒ Object
- #variable(variable_path, position) ⇒ Object
Constructor Details
#initialize(timeout, contexts, variables, file_name, global_helpers_providers = [], cache = ->(key, &block) { block.call }) ⇒ RenderingSupport
Returns a new instance of RenderingSupport.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/curlybars/rendering_support.rb', line 3 def initialize(timeout, contexts, variables, file_name, global_helpers_providers = [], cache = ->(key, &block) { block.call }) @timeout = timeout @start_time = Time.now @contexts = contexts @variables = variables @file_name = file_name @cached_calls = {} @cache = cache @global_helpers = {} global_helpers_providers.each do |provider| provider.allowed_methods.each do |global_helper_name| symbol = global_helper_name.to_sym @global_helpers[symbol] = provider.method(symbol) end end end |
Instance Method Details
#cached_call(meth) ⇒ Object
107 108 109 110 111 |
# File 'lib/curlybars/rendering_support.rb', line 107 def cached_call(meth) return cached_calls[meth] if cached_calls.key? meth instrument(meth) { cached_calls[meth] = meth.call(*arguments_for_signature(meth, [], {})) } end |
#call(helper, helper_path, helper_position, arguments, options, &block) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/curlybars/rendering_support.rb', line 113 def call(helper, helper_path, helper_position, arguments, , &block) parameters = helper.parameters parameter_types = parameters.map(&:first) # parameters has value [[:rest]] when the presenter is using method_missing to catch all calls has_invalid_parameters = parameter_types.map { |type| type != :req }.any? && parameter_types != [:rest] if has_invalid_parameters source_location = helper.source_location file_path = source_location ? source_location.first : "n/a" line_number = source_location ? helper.source_location.last : "n/a" = "#{file_path}:#{line_number} - `#{helper_path}` bad signature " << "for #{helper} - helpers must have only required parameters" raise Curlybars::Error::Render.new('invalid_helper_signature', , helper_position) end instrument(helper) do helper.call(*arguments_for_signature(helper, arguments, ), &block) end end |
#check_context_is_hash_or_enum_of_presenters(collection, path, position) ⇒ Object
38 39 40 41 42 43 |
# File 'lib/curlybars/rendering_support.rb', line 38 def check_context_is_hash_or_enum_of_presenters(collection, path, position) return if presenter_collection?(collection) = "`#{path}` is not an array of presenters or a hash of such" raise Curlybars::Error::Render.new('context_is_not_an_array_of_presenters', , position) end |
#check_context_is_presenter(context, path, position) ⇒ Object
31 32 33 34 35 36 |
# File 'lib/curlybars/rendering_support.rb', line 31 def check_context_is_presenter(context, path, position) return if presenter?(context) = "`#{path}` is not a context type object" raise Curlybars::Error::Render.new('context_is_not_a_presenter', , position) end |
#check_timeout! ⇒ Object
23 24 25 26 27 28 29 |
# File 'lib/curlybars/rendering_support.rb', line 23 def check_timeout! return unless timeout.present? return unless (Time.now - start_time) > timeout = "Rendering took too long (> #{timeout} seconds)" raise ::Curlybars::Error::Render.new('timeout', , nil) end |
#coerce_to_hash!(collection, path, position) ⇒ Object
139 140 141 142 143 144 145 146 147 148 |
# File 'lib/curlybars/rendering_support.rb', line 139 def coerce_to_hash!(collection, path, position) check_context_is_hash_or_enum_of_presenters(collection, path, position) if collection.is_a?(Hash) collection elsif collection.respond_to? :each_with_index collection.each_with_index.map { |value, index| [index, value] }.to_h else raise "Collection is not coerceable to hash" end end |
#optional_presenter_cache(presenter, template_cache_key, buffer) ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/curlybars/rendering_support.rb', line 162 def optional_presenter_cache(presenter, template_cache_key, buffer) presenter_cache_key = presenter.respond_to?(:cache_key) ? presenter.cache_key : nil if presenter_cache_key cache_key = "#{presenter_cache_key}/#{template_cache_key}" buffer << cache.call(cache_key) do # Output from the block must be isolated from the main output buffer SafeBuffer.new.tap do |cache_buffer| yield cache_buffer end end else yield buffer end end |
#path(path, position) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/curlybars/rendering_support.rb', line 68 def path(path, position) return global_helpers[path.to_sym] if global_helpers.key?(path.to_sym) check_traverse_not_too_deep(path, position) path_split_by_slashes = path.split('/') backward_steps_on_contexts = path_split_by_slashes.count - 1 base_context_position = contexts.length - backward_steps_on_contexts return -> {} unless base_context_position > 0 base_context_index = base_context_position - 1 base_context = contexts[base_context_index] dotted_path_side = path_split_by_slashes.last chain = dotted_path_side.split('.') method_to_return = chain.pop resolved = chain.inject(base_context) do |context, meth| next context if meth == 'this' next context.count if meth == 'length' && presenter_collection?(context) raise_if_not_traversable(context, meth, position) outcome = instrument(context.method(meth)) { context.public_send(meth) } return -> {} if outcome.nil? outcome end return -> { resolved } if method_to_return == 'this' if method_to_return == 'length' && presenter_collection?(resolved) return -> { resolved.count } end raise_if_not_traversable(resolved, method_to_return, position) resolved.method(method_to_return.to_sym) end |
#position(line_number, line_offset) ⇒ Object
135 136 137 |
# File 'lib/curlybars/rendering_support.rb', line 135 def position(line_number, line_offset) Curlybars::Position.new(file_name, line_number, line_offset) end |
#presenter?(context) ⇒ Boolean
150 151 152 |
# File 'lib/curlybars/rendering_support.rb', line 150 def presenter?(context) context.respond_to? :allows_method? end |
#presenter_collection?(collection) ⇒ Boolean
154 155 156 157 158 159 160 |
# File 'lib/curlybars/rendering_support.rb', line 154 def presenter_collection?(collection) collection = collection.values if collection.is_a?(Hash) collection.respond_to?(:each) && collection.all? do |presenter| presenter?(presenter) end end |
#to_bool(condition) ⇒ Object
45 46 47 48 49 50 51 52 |
# File 'lib/curlybars/rendering_support.rb', line 45 def to_bool(condition) condition != false && condition != [] && condition != {} && condition != 0 && condition != '' && !condition.nil? end |
#variable(variable_path, position) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/curlybars/rendering_support.rb', line 54 def variable(variable_path, position) check_traverse_not_too_deep(variable_path, position) variable_split_by_slashes = variable_path.split('/') variable = variable_split_by_slashes.last.to_sym backward_steps_on_variables = variable_split_by_slashes.count - 1 variables_position = variables.length - backward_steps_on_variables scope = variables.first(variables_position).reverse.find do |vars| vars.key? variable end scope[variable] if scope end |