Partial Templates

Notice: you should know about all the Templating section before reading this (see Templates, Template Sources, Tags, Variables and Interpolation).

Elastics Partial Templates are templates that will be inserted into other templates at interpolation time. They are used in a few different ways in order to make the templating system more dynamic and powerful. For example:

_a_partial_template:
  foo: <<bar>>

_another_partial_template:
  alpha: <<beta>>

a_template:
  <<_a_partial_template>>

The name of a partial template must start with '_'. Its content can be inserted into another template in a couple of ways: the most common is simply creating a tag with the same name in the other template (in our example the <<_a_partial_template>> tag). Then the value of the variable with the same name (in our example the :_a_partial_template variable) will determine what will be inserted in place of the tag.

Partial Template Interpolation

There are a few possible cases of interpolation, depending on the value of the variable with the same partial template name:

Type of Value Tag Replacement
Single Hash

Partial Insertion

MyClass.a_template(:_a_partial_template => {:bar => 'baz'})

will result as:

a_template:
  foo: baz
Array of Hashes

Partial Insertion repeated for each item in the hash

MyClass.a_template(:_a_partial_template => [{:bar => 'baz'}, {:bar => 'quux'})

will result as:

a_template:
  - foo: baz
  - foo: quux
true

Partial Insertion

MyClass.a_template(:bar => 'baz', :_a_partial_template => true)

will result as:

a_template:
  foo: baz
Symbol

Insertion of the partial named as the Symbol

MyClass.a_template(:_a_partial_template => :_another_partial_template, :beta => 'gamma')

will result as:

a_template:
  alpha: gamma
String

Will be evaluated as a Template and Inserted

MyClass.a_template(:_a_partial_template => 'oh: <<my>>', :my => 'god')

will result as:

a_template:
  oh: god
nil, false, "", {}, []

Branch Pruning

MyClass.a_template(:_a_partial_template => nil) # or '', [], {}

will result as:

a_template:

Example

The most common case of partial usage is when you need to generate a repetition. The structure you pass must be a (possibly empty) Array of Hashes, each hash containing the variables to interpolate with each single repeated fragment. For example:

_the_terms:
  term:
    <<attr>>: <<term>>

my_search:
- query:
    bool:
      must:
      - query_string:
          query: <<q= '*' >>
      - << _the_terms= ~ >>

The _the_terms template is a partial, its structure will be repeated and interpolated with the data passed as :_the_terms variable and will be inserted in place of _the_terms tag. If :_the_term is nil (or if it is an empty Array) the partial will be pruned.

Here are a couple possible usages of the same template, and the final data query they produce (translated in YAML for readability):

results1 = MyClass.my_search(:_the_terms => [{:attr => 'color', :term => 'blue'}, {:attr => 'year', :term => 1984}, ...])
# produced data query
query:
  bool:
    must:
      - query_string:
          query: "*"
      - term:
          color: blue
      - term:
          year: 1984
      ...
results2 = MyClass.my_search(:q => 'Chevrolet OR Fiat')
# produced data query
query:
  bool:
    must:
      - query_string:
          query: "Chevrolet OR Fiat"

But you could do the same with less, that may be simpler in your context. This partial would produce exactly the same data query, providing the simpler interpolation values:

_the_terms:
  term: <<terms>>
results1 = MyClass.my_search(:_the_terms => [{:terms => {'color'=> 'blue'}}, {:terms => {'year' => 1984}}, ...])