Class: Dryml::TemplateEnvironment

Inherits:
Object
  • Object
show all
Includes:
Helper
Defined in:
lib/dryml/template_environment.rb

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helper

#context_map, #create_part_id, #first_item?, #last_item?, #param_name_for, #param_name_for_this, #param_name_for_this_parent

Constructor Details

#initialize(view = nil) ⇒ TemplateEnvironment

Returns a new instance of TemplateEnvironment.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/dryml/template_environment.rb', line 28

def initialize(view=nil)
  unless view.nil?
    @view = view
    @_erb_binding = binding
    @_part_contexts = {}
    @_scoped_variables = ScopedVariables.new
    @_polymorphic_tag_cache = {}

    # Make sure the "assigns" from the controller are available (instance variables)
    if view
      view.assigns.each do |key, value|
        instance_variable_set("@#{key}", value)
      end

      # copy view instance variables over
      view.instance_variables.each do |iv|
        instance_variable_set(iv, view.instance_variable_get(iv))
      end

      # Copy some class attributes needed for Sprockets to work correctly
      self.extend ::Sprockets::Rails::Helper

      self.debug_assets        = view.try(:debug_assets)
      self.digest_assets       = view.try(:digest_assets)
      self.assets_prefix       = view.try(:assets_prefix)
      self.assets_precompile   = view.try(:assets_precompile)

      self.assets_environment  = view.try(:assets_environment)
      self.assets_manifest     = view.try(:assets_manifest)

      self.resolve_assets_with = view.try(:resolve_assets_with)

      # Expose the app precompiled asset check
      self.precompiled_asset_checker = view.try(:precompiled_asset_checker)
    end
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &b) ⇒ Object



658
659
660
661
662
663
664
# File 'lib/dryml/template_environment.rb', line 658

def method_missing(name, *args, &b)
  if @view
    @view.send(name, *args, &b)
  else
    raise NoMethodError, name.to_s
  end
end

Class Attribute Details

.compiled_local_namesObject

Returns the value of attribute compiled_local_names.



9
10
11
# File 'lib/dryml/template_environment.rb', line 9

def compiled_local_names
  @compiled_local_names
end

.load_timeObject

Returns the value of attribute load_time.



9
10
11
# File 'lib/dryml/template_environment.rb', line 9

def load_time
  @load_time
end

Class Method Details

._register_tag_attrs(tag_name, attrs) ⇒ Object



12
13
14
15
# File 'lib/dryml/template_environment.rb', line 12

def _register_tag_attrs(tag_name, attrs)
  @tag_attrs ||= {}
  @tag_attrs[tag_name] = attrs
end

.inherited(subclass) ⇒ Object



6
7
8
# File 'lib/dryml/template_environment.rb', line 6

def inherited(subclass)
  subclass.compiled_local_names = []
end

.tag_attrsObject



18
19
20
# File 'lib/dryml/template_environment.rb', line 18

def tag_attrs
  @tag_attrs ||= {}
end

Instance Method Details

#_tag_context(attributes) ⇒ Object



390
391
392
393
394
395
396
397
398
399
400
401
402
403
# File 'lib/dryml/template_environment.rb', line 390

def _tag_context(attributes)
  with  = attributes[:with]
  field = attributes[:field]

  if with && field
    new_object_context(with) { new_field_context(field) { yield } }
  elsif field
    new_field_context(field) { yield }
  elsif attributes.has_key?(:with)
    new_object_context(with) { yield }
  else
    new_context { yield }
  end
end

#_tag_locals(attributes, locals) ⇒ Object



424
425
426
427
428
429
430
431
432
433
434
435
436
# File 'lib/dryml/template_environment.rb', line 424

def _tag_locals(attributes, locals)
  attributes = attributes.symbolize_keys
  #ensure with and field are not in attributes
  attributes.delete(:with)
  attributes.delete(:field)

  # declared attributes don't appear in the attributes hash
  stripped_attributes = HashWithIndifferentAccess.new.update(attributes)
  locals.each {|a| stripped_attributes.delete(a.to_sym) }

  # Return locals declared as local variables (attrs="...")
  locals.map {|a| attributes[a.to_sym]} + [stripped_attributes]
end

#add_classes(attributes, *classes) ⇒ Object



134
135
136
# File 'lib/dryml/template_environment.rb', line 134

def add_classes(attributes, *classes)
  add_classes!(HashWithIndifferentAccess.new(attributes), classes)
end

#add_classes!(attributes, *classes) ⇒ Object



127
128
129
130
131
132
# File 'lib/dryml/template_environment.rb', line 127

def add_classes!(attributes, *classes)
  classes = classes.flatten.select{|x|x}
  current = attributes[:class]
  attributes[:class] = (current ? current.split + classes : classes).uniq.join(' ')
  attributes
end

#add_data_rapid(attrs, tag, options) ⇒ Object



151
152
153
# File 'lib/dryml/template_environment.rb', line 151

def add_data_rapid(attrs, tag, options)
  add_data_rapid!(HashWithIndifferentAccess.new(attrs), tag, options)
end

#add_data_rapid!(attrs, tag, options) ⇒ Object



145
146
147
148
149
# File 'lib/dryml/template_environment.rb', line 145

def add_data_rapid!(attrs, tag, options)
  data_rapid = ActiveSupport::JSON.decode(attrs["data_rapid"] || "{}")
  attrs["data_rapid"] = data_rapid.update(tag => options).to_json
  attrs
end

#attrs_for(name) ⇒ Object



118
119
120
# File 'lib/dryml/template_environment.rb', line 118

def attrs_for(name)
  self.class.tag_attrs[name.to_sym]
end

#call_part(part_node_id, part_name, *locals) ⇒ Object



194
195
196
197
198
199
200
201
# File 'lib/dryml/template_environment.rb', line 194

def call_part(part_node_id, part_name, *locals)
  res = ''
  new_context do
    @_part_contexts[part_node_id] = PartContext.for_call(part_name, self, locals)
    res = send("#{part_name}_part", *locals)
  end
  res
end

#call_polymorphic_tag(name, *args) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/dryml/template_environment.rb', line 246

def call_polymorphic_tag(name, *args)
  name = name.to_s.gsub('-', '_')
  type = args.first.is_a?(Class) ? args.shift : nil
  attributes, parameters = args

  tag = find_polymorphic_tag(name, type)
  if tag != name
    send(tag, attributes || {}, parameters || {})
  else
    block_given? ? yield : nil
  end
end

#call_tag_parameter(the_tag, attributes, parameters, caller_parameters, param_name) ⇒ Object



460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
# File 'lib/dryml/template_environment.rb', line 460

def call_tag_parameter(the_tag, attributes, parameters, caller_parameters, param_name)
  overriding_proc = caller_parameters[param_name]
  replacing_proc  = caller_parameters[:"#{param_name}_replacement"]

  unless param_name == the_tag || param_name == :default
    classes = attributes[:class]
    param_class = param_name.to_s.gsub('_', '-')
    attributes[:class] = if classes
                           classes =~ /\b#{param_class}\b/ ? classes : "#{classes} #{param_class}"
                         else
                           param_class
                         end
  end

  if param_name == :default && overriding_proc && overriding_proc.arity>0
    # :default content is handled specially

    call_tag_parameter_with_default_content(the_tag, attributes, parameters[:default], overriding_proc)

  elsif replacing_proc
    # The caller is replacing this parameter. Don't call the tag
    # at all, just the overriding proc, but pass the restorable
    # tag as a parameter to the overriding proc

    tag_restore = proc do |restore_attrs, restore_params|
      # Call the replaced tag with the attributes and parameters
      # as given in the original tag definition, and with the
      # specialisation given on the 'restore' call

      if overriding_proc
        overriding_attributes, overriding_parameters = overriding_proc.call
        restore_attrs  = overriding_attributes.merge(restore_attrs)
        restore_params = overriding_parameters.merge(restore_params)
      end

      override_and_call_tag(the_tag, attributes, parameters, restore_attrs, restore_params)
    end
    replacing_proc.call(tag_restore)

  else
    overriding_attributes, overriding_parameters = overriding_proc._?.call
    override_and_call_tag(the_tag, attributes, parameters, overriding_attributes, overriding_parameters)
  end
end

#call_tag_parameter_with_default_content(the_tag, attributes, default_content, overriding_content_proc) ⇒ Object



439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
# File 'lib/dryml/template_environment.rb', line 439

def call_tag_parameter_with_default_content(the_tag, attributes, default_content, overriding_content_proc)
  if the_tag.is_one_of?(String, Symbol) && the_tag.to_s.in?(Dryml.static_tags)
    body = if overriding_content_proc
             new_context { overriding_content_proc.call(proc { default_content._?.call(nil) }) }
           elsif default_content
             new_context { default_content.call(nil) }
           else
             nil
           end
    element(the_tag, attributes, body)
  else
    d = if overriding_content_proc
          proc { |default| overriding_content_proc.call(proc { default_content._?.call(default) }) }
        else
          proc { |default| default_content._?.call(default) }
        end
    send(the_tag, attributes, { :default => d })
  end
end

#configObject



654
655
656
# File 'lib/dryml/template_environment.rb', line 654

def config
  @view ? @view.config : {}
end

#deunderscore_attributes(attrs) ⇒ Object



123
124
125
# File 'lib/dryml/template_environment.rb', line 123

def deunderscore_attributes(attrs)
  HashWithIndifferentAccess[attrs.map{ |attr, value| [attr.to_s.gsub('_', '-'), value]}]
end

#element(name, attributes, content = nil, escape = true, empty = false, &block) ⇒ Object



616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
# File 'lib/dryml/template_environment.rb', line 616

def element(name, attributes, content=nil, escape = true, empty = false, &block)
  unless attributes.blank?
    attrs = []
    if escape
      attributes.each do |key, value|
        next unless value
        key = key.to_s.gsub("_", "-")

        value = if ActionView::Helpers::TagHelper::BOOLEAN_ATTRIBUTES.include?(key)
                  key
                else
                  # escape once
                  value.to_s.gsub(/[\"><]|&(?!([a-zA-Z]+|(#\d+));)/) { |special| ERB::Util::HTML_ESCAPE[special] }
                end
        attrs << %(#{key}="#{value}")
      end

    else
      attrs = options.map do |key, value|
        key = key.to_s.gsub("_", "-")
        %(#{key}="#{value}")
      end
    end
    attr_string = " #{attrs.sort * ' '}" unless attrs.empty?
  end
  content = capture { new_context &block } if block_given?
  if empty
    "<#{name}#{attr_string}#{scope.xmldoctype ? ' /' : ''}>".html_safe
  else
    "<#{name}#{attr_string}>".html_safe + content + "</#{name}>".html_safe
  end
end

#find_form_field_path(object) ⇒ Object



370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/dryml/template_environment.rb', line 370

def find_form_field_path(object)
  back = []
  while object
    path = @_form_field_paths_by_object[object]
    if path
      path = path + back unless back.empty?
      return path
    end
    if object.respond_to? :origin
      back.unshift object.origin_attribute
      object = object.origin
    else
      return nil
    end
  end
end

#find_polymorphic_tag(name, call_type = nil) ⇒ Object



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/dryml/template_environment.rb', line 260

def find_polymorphic_tag(name, call_type=nil)
  call_type ||= (this.respond_to?(:member_class) && this.member_class) || this_type
  begin
    found = nil
    while true
      # ActiveSupport::TimeWithZone.name would return 'Time'
      # so we add an exception to pick the right datetime type
      type_name = ( call_type == ActiveSupport::TimeWithZone ? 'datetime' : call_type.name.to_s).underscore.gsub('/', '__')
      if respond_to?(poly_name = "#{name}__for_#{type_name}")
        found = poly_name
        break
      else
        if call_type == Object
          found = name
          break
        else
          call_type = call_type.superclass
        end
      end
    end
    found
  end
end

#merge_attrs(attrs, overriding_attrs) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/dryml/template_environment.rb', line 155

def merge_attrs(attrs, overriding_attrs)
  attrs = {}.update(attrs)
  return attrs if overriding_attrs.nil?
  attrs = attrs.with_indifferent_access unless attrs.is_a?(HashWithIndifferentAccess)
  classes = overriding_attrs[:class]
  add_classes!(attrs, *classes.split) if classes
  remove_classes!(attrs, *(overriding_attrs[:remove_class].split)) if overriding_attrs[:remove_class]
  if (data_rapid = overriding_attrs["data_rapid"])
    attrs["data_rapid"]=ActiveSupport::JSON.decode(attrs["data_rapid"] || "{}").
      update(ActiveSupport::JSON.decode(data_rapid)).to_json
  end

  attrs.update(overriding_attrs - [:class, :data_rapid])
end

#merge_parameter_hashes(given_parameters, overriding_parameters) ⇒ Object



590
591
592
593
594
595
596
597
598
599
# File 'lib/dryml/template_environment.rb', line 590

def merge_parameter_hashes(given_parameters, overriding_parameters)
  to_merge = given_parameters.keys & overriding_parameters.keys
  no_merge = overriding_parameters.keys - to_merge
  result = given_parameters.dup

  no_merge.each { |k| result[k] = overriding_parameters[k] }
  to_merge.each { |k| result[k] = merge_tag_parameter(given_parameters[k], overriding_parameters[k])}

  result
end

#merge_tag_parameter(general_proc, overriding_proc) ⇒ Object

This method is used where ‘param’ is declared on a tag that is itself a parameter tag. Takes two procs that each return a pair of hashes (attributes and parameters). Returns a single proc that also returns a pair of hashes - the merged atributes and parameters.



552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
# File 'lib/dryml/template_environment.rb', line 552

def merge_tag_parameter(general_proc, overriding_proc)
  if overriding_proc.nil?
    general_proc
  else
    if overriding_proc.arity == 1
      # The override is a replace parameter - just pass it on
      overriding_proc
    else
      proc do
        overriding_attrs, overriding_parameters = overriding_proc.call
        general_attrs, general_parameters = general_proc.call

        attrs  = merge_attrs(general_attrs, overriding_attrs)
        overriding_default = overriding_parameters.delete(:default)
        params = merge_parameter_hashes(general_parameters, overriding_parameters)

        # The overrider should provide its :default as the new
        # 'default_content'
        if overriding_default
          params[:default] =
            if general_parameters[:default]
              proc do |default|
                overriding_default.call(proc { new_context { concat(general_parameters[:default].call(default)) } } )
              end
            else
              proc do |default|
                overriding_default.call(default)
              end
            end
        end

        [attrs, params]
      end
    end
  end
end

#new_contextObject



298
299
300
301
302
303
304
305
306
307
# File 'lib/dryml/template_environment.rb', line 298

def new_context
  ctx = [ @_this, @_this_parent, @_this_field, @_this_type,
          @_form_field_path, @_form_field_paths_by_object ]
  @_this_type = nil
  res = nil
  outer_res = @view.with_output_buffer { res = yield }
  Rails.logger.error("new_context: #{caller.first}") if !outer_res.blank? && outer_res.to_s != res.to_s
  @_this, @_this_parent, @_this_field, @_this_type, @_form_field_path, @_form_field_paths_by_object = ctx
  res.to_s
end

#new_field_context(field_path, new_this = nil) ⇒ Object



345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/dryml/template_environment.rb', line 345

def new_field_context(field_path, new_this=nil)
  new_context do
    path = if field_path.is_a? String
             field_path.split('.')
           else
             Array(field_path)
           end
    if new_this
      raise ArgumentError, "invlaid context change" unless path.length == 1
      @_this_parent, @_this_field, @_this = this, path.first, new_this
    else
      parent, field, obj = Dryml.get_field_path(this, path)
      @_this, @_this_parent, @_this_field = obj, parent, field
    end

    if @_form_field_path
      @_form_field_path += path
      @_form_field_paths_by_object[@_this] = @_form_field_path
    end

    yield
  end
end

#new_object_context(new_this) ⇒ Object



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/dryml/template_environment.rb', line 316

def new_object_context(new_this)
  new_context do
    if new_this.respond_to?(:origin)
      refl = (new_this.origin && new_this.origin_attribute.is_a?(Symbol) && new_this.origin.class.respond_to?(:reflections) && new_this.origin.class.reflections[new_this.origin_attribute])
      if refl.nil? || refl.macro==:belongs_to || refl.macro==:has_one
        @_this_parent, @_this_field = new_this.origin, new_this.origin_attribute
      else
        # See bug #989 for more discussion.   The commented out
        # section is more 'correct', but it is expensive and since
        # nobody really ran into this before, setting to nil seems
        # more appropriate.
        @_this_parent, @_this_field = nil, nil
        #@_this_parent = new_this.origin.send(new_this.origin_attribute)
        #@_this_field = @_this_parent.index(new_this) || @_this_parent.length
      end
    else
      @_this_parent, @_this_field = [nil, nil]
    end
    @_this = new_this

    # We might have lost track of where 'this' is relative to the form_this
    # check if this or this_parent are objects we've seen before in this form
    @_form_field_path = find_form_field_path(new_this) if @_form_field_path

    yield
  end
end

#override_and_call_tag(the_tag, general_attributes, general_parameters, overriding_attributes, overriding_parameters) ⇒ Object



506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
# File 'lib/dryml/template_environment.rb', line 506

def override_and_call_tag(the_tag, general_attributes, general_parameters, overriding_attributes, overriding_parameters)
  attributes = overriding_attributes ? merge_attrs(general_attributes, overriding_attributes) : general_attributes
  if overriding_parameters
    overriding_default_content = overriding_parameters.delete(:default)
    parameters = general_parameters.merge(overriding_parameters)
  else
    parameters = general_parameters
  end

  default_content = parameters[:default]

  if the_tag.is_one_of?(String, Symbol) && the_tag.to_s.in?(Dryml.static_tags)
    body = if overriding_default_content
             new_context { overriding_default_content.call(proc { default_content.call(nil) if default_content }) }
           elsif default_content
             new_context { default_content.call(nil) }
           else
             nil
           end
    element(the_tag, attributes, body)
  else
    if default_content || overriding_default_content
      d = if overriding_default_content
            proc { |default| overriding_default_content.call(proc { default_content.call(default) if default_content }) }
          else
            proc { |default| default_content.call(default) if default_content }
          end
      parameters = parameters.merge(:default => d)
    end

    if the_tag.is_one_of?(String, Symbol)
      # It's a defined DRYML tag
      send(the_tag, attributes, parameters)
    else
      # It's a proc - restoring a replaced parameter
      the_tag.call(attributes, parameters)
    end
  end
end

#parse_for_type(attributes) ⇒ Object



231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/dryml/template_environment.rb', line 231

def parse_for_type(attributes)
  t = attributes[:for_type]
  if t.nil?
    nil
  elsif t.is_a?(Class)
    t
  elsif t =~ /^[A-Z]/
    t.constantize
  elsif t =~ /^[a-z]/ && defined?(HoboFields.to_class)
    HoboFields.to_class(t)
  else
    nil
  end
end

#part_contexts_storage_uncodedObject



602
603
604
# File 'lib/dryml/template_environment.rb', line 602

def part_contexts_storage_uncoded
  PartContext.client_side_storage_uncoded(@_part_contexts, session)
end

#path_for_form_fieldObject



72
73
74
75
76
# File 'lib/dryml/template_environment.rb', line 72

def path_for_form_field
  @_form_field_path.nil? and raise Dryml::DrymlException,
    "DRYML cannot provide the correct form-field name here (this_field = #{this_field.inspect}, this = #{this.inspect})"
  @_form_field_path
end

#refresh_part(encoded_context, session, dom_id) ⇒ Object



204
205
206
207
208
209
210
# File 'lib/dryml/template_environment.rb', line 204

def refresh_part(encoded_context, session, dom_id)
  context = Dryml::PartContext.for_refresh(encoded_context, @this, session)

  with_part_context(context) do
    send("#{context.part_name}_part", *context.locals)
  end
end

#register_form_field(name) ⇒ Object



419
420
421
# File 'lib/dryml/template_environment.rb', line 419

def register_form_field(name)
  scope.form_field_names << name
end

#remove_classes!(attributes, *remove_classes) ⇒ Object



138
139
140
141
142
143
# File 'lib/dryml/template_environment.rb', line 138

def remove_classes!(attributes, *remove_classes)
  if attributes[:class]
    attributes[:class] = (attributes[:class].split - remove_classes).join(' ')
  end
  attributes
end

#render_tag(tag_name, attributes) ⇒ Object



606
607
608
609
610
611
612
613
# File 'lib/dryml/template_environment.rb', line 606

def render_tag(tag_name, attributes)
  method_name = tag_name.to_s.gsub('-', '_')
  if respond_to?(method_name)
    send(method_name, attributes).strip
  else
    false
  end
end

#repeat_attribute(string_or_array) ⇒ Object



285
286
287
288
289
290
291
292
293
294
295
# File 'lib/dryml/template_environment.rb', line 285

def repeat_attribute(string_or_array)
  res = nil
  if string_or_array.instance_of?(String)
    new_field_context(string_or_array) do
       res = context_map { yield }
     end
  else
    res = context_map(string_or_array) { yield }
  end
  res.safe_join
end

#scopeObject



171
172
173
# File 'lib/dryml/template_environment.rb', line 171

def scope
  @_scoped_variables
end

#sessionObject



650
651
652
# File 'lib/dryml/template_environment.rb', line 650

def session
  @view ? @view.session : {}
end

#this_field_reflectionObject



112
113
114
115
# File 'lib/dryml/template_environment.rb', line 112

def this_field_reflection
  this.try.proxy_association._?.reflection ||
    (this_parent && this_field && this_parent.class.respond_to?(:reflections) && this_parent.class.reflections[this_field.to_s])
end

#this_key=(key) ⇒ Object



79
80
81
# File 'lib/dryml/template_environment.rb', line 79

def this_key=(key)
  @_this_key = key
end

#this_typeObject

The type of this, or when this is nil, the type that would be expected in the current field



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/dryml/template_environment.rb', line 85

def this_type
  @_this_type ||= if this == false || this == true
                    Hobo::Boolean
                  elsif this
                    this.class
                  elsif this_parent && this_field && (parent_class = this_parent.class).respond_to?(:attr_type)
                    type = parent_class.attr_type(this_field)
                    if type.is_a?(ActiveRecord::Reflection::AssociationReflection)
                      reflection = type
                      if reflection.macro == :has_many
                        Array
                      elsif reflection.options[:polymorphic]
                        # All we know is that it will be some active-record type
                        ActiveRecord::Base
                      else
                        reflection.klass
                      end
                    else
                      type
                    end
                  else
                    # Nothing to go on at all
                    Object
                  end
end

#typed_id(object = nil, attribute = nil) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/dryml/template_environment.rb', line 176

def typed_id(object=nil, attribute=nil)
    if object.nil?
      # nothing passed -- use context
      if this_parent && this_field && !this_parent.respond_to?(:member_class)
        object, attribute = this_parent, this_field
      else
        object = this
      end
    end
    id = if (!object.is_a?(ActiveRecord::Relation) && typed_id = object.try.typed_id)
        typed_id
      else
        "this"
      end
    attribute ? "#{id}:#{attribute}" : id
end

#with_form_context(form_this = this, form_field_path = [form_this.class.name.underscore]) ⇒ Object



406
407
408
409
410
411
412
413
414
415
416
# File 'lib/dryml/template_environment.rb', line 406

def with_form_context(form_this=this, form_field_path=[form_this.class.name.underscore])
  ctx = [@_form_this, @_form_field_path, @_form_field_paths_by_object]
  @_form_this = form_this
  @_form_field_path = form_field_path
  @_form_field_paths_by_object = { form_this => form_field_path }
  res = scope.new_scope :in_form => true, :form_field_names => [] do
    yield
  end
  @_form_this, @_form_field_path, @_form_field_paths_by_object = ctx
  res
end

#with_part_context(context, &block) ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/dryml/template_environment.rb', line 213

def with_part_context(context, &block)
  this, this_field = context.this, context.this_field

  b = if context.form_field_path
        proc { with_form_context(:unknown, context.form_field_path, &block) }
      else
        block
      end

  if this && this_field
    new_object_context(this) { new_field_context(this_field, &b) }
  elsif this
    new_object_context(this, &b)
  else
    new_context(&b)
  end
end

#yield_output_bufferObject



309
310
311
312
313
# File 'lib/dryml/template_environment.rb', line 309

def yield_output_buffer
  res = nil
  @view.with_output_buffer { res = yield }
  res.to_s
end