SparkleFormation includes functionality allowing SparklePacks to interact with previous layers when a file is requested from the collection. This functionality makes it easy to slightly modify files provided within previously registered SparklePacks without having to recreate the entire contents of the file. It also allows for creation of new templates based on existing templates.
Template inheritance allows a new template to inherit the data structures of an existing template. For example, lets start with a simple template:
SparkleFormation.new(:simple) do
simple_template true
end
The dumped result of this template is:
{
"SimpleTemplate": true
}
Suppose that we wanted create a new template that was composed of everything
described in the simple
template, but had an extra addition. Instead of
re-creating the contents in a new file, or attempting to break out components
or dynamics that may not be ideal, we can inherit the template instead:
SparkleFormation.new(:advanced, :inherit => :simple) do
advanced.item 'added'
end
When this template is dumped, it will inherit the simple
template and
add on to the resultant data structure giving the result:
{
"SimpleTemplate": true,
"Advanced": {
"Item": "added"
}
}
Inheritance is not restricted to templates at a common level. A new template can inherit templates provided by SparklePacks.
Template merging is only applicable when SparklePacks are in use. Template merging allows direct modification of a specific named template. This strategy is extremely useful when packs may be layering functionality into a template, or the root pack wants to make a specific adjustment without creating a new template.
The default behavior of SparkleFormation when a SparklePack provides a template with the same name as a previously loaded SparklePack, it will overwrite the original template. In some cases, this may not be the desired effect. If a pack would like to make a simple adjustment to the template, this would require duplicating the contents of the original template and appending the customization. Merging allows adding customization without recreation.
Lets assume we have a core SparklePack loaded and it provides us with the simple
template:
SparkleFormation.new(:simple) do
simple_template true
end
Now in our root SparklePack we want to make an adjustment to the simple
template
directly. We can do this by merging:
SparkleFormation.new(:simple, :layering => :merge) do
modifier 'spox'
end
When we dump the simple
template now we get:
{
"SimpleTemplate": true,
"Modifier": "spox"
}
This sort of merging make two strategies possible:
Merging behavior for components and dynamics follows the same pattern as templates.
Adding the :layering => :merge
option will cause the item to be merged instead
of overwritten.
For components:
SparkleFormation.component(:name, :layering => :merge)
and dynamics:
SparkleFormation.dynamic(:name, :layering => :merge)
The return value of a dynamic cannot be inferred. This is due to the freeform nature of dynamics leaving the resulting return value up to the author of the dynamic. When merging dynamics it can be easy to return the wrong value. The library could take care of this and always return the context provided by the initial dynamic, but this behavior is problematic: merges could remove the original context, or may want to change the return context completely. Returning the proper value is left to the author, but SparkleFormation makes it easy to return the previous context.
When the dynamics are merged, SparkleFormation will include an extra key in the
options Hash
for the dynamic: :previous_layer_result
. Now a dynamic can merge
in extra changes, and ensure the correct value is returned from the call:
SparkleFormation.dynamic(:name, :layering => :merge) do |name, args={}|
new.things.added 'here'
args[:previous_layer_result]
end
Registry items are exempt from the merging behavior described above. Registry items are always overwritten when redefined in higher level SparklePacks.