Currently ItemBlocks are defined within the file-scope of an attribute template file. Recently it has been asked if instead ItemBlocks could be made available to all template files that have an include path to the file containing the ItemBlock.
Expanding ItemBlock Scope
It would be relatively easy to allow an Item Block in template file A to be available in template file B (assuming either B includes A or if there is a path of includes between A and B). The idea would be to cache the Item Block Information as a set of XML encoded strings after reading one include file, and then passing them down on when processing the files that include them.
Issue with Overriding ItemBlocks
The issue is “what if a consuming template file wants to override some of the ItemBlocks it is inheriting?”
To get a handle on this we need to review how include files are processed with reading in a template file.
Lets assume we have the following case:
In this case the top-level template file H includes template files F and G (in that order).
The order in which the include files are processed is the following:
Use Case 1 - all Item Blocks are Unique
So lets assume that the names of all of the ItemBlocks are unique (hence no ItemBlock is redefined. Based on the processing order, an ItemBlock defined in A would be available in the processing of all of the other template files since it is pulled in first. Note that Definitions defined in A are also currently available in the processing of all of the other template file as well. This behavior is similar to how include files are processed in C++.
Use Case 2 - Redefining ItemBlocks
Let’s assume that C has an ItemBlock called IBC and that F redefines it (IBC’). Also assume that G uses ItemBlock IBC. In the above example, G is going to inherit IBC’ since F is processed before G. If the designer was to change the order of includes in H such that G was included before F, then G would be using IBC instead.
Suggestions For Controlling How ItemBlocks Can Be “Shared”
I think there are 3 cases SMTK should handle:
- The designer wants an ItemBlock to be private (i.e. only defined within file scope): This means that the ItemBlock would not be “exported” outside of the file and is the behavior we have today. It also replaces an exported ItemBlock with the same name (if one exists) only for processing that file.
- The designer wants an ItemBlock to be exported: This means that the ItemBlock should be accessible to all files that are processed after the one that contains the ItemBlock.
- The designer wants an ItemBlock to be a default that can be overridden by a previously exported ItemBlock with the same name (if one exists). This is sort of the the dual of #1. Here the ItemBlock will only be used if another has not already been defined previously.
So I propose adding 2 XML attributes to an Item Block XML Element:
- Export=‘true’ : indicates that the ItemBlock is to be exported (by default an ItemBlock is assumed to be private). An exported ItemBlock will replace a previously exported ItemBlock with the same name in the set of exported ItemBlocks. A private ItemBlock will replace a previously exported ItemBlock with the same name while processing the file that it is defined in only.
- Default=‘true’ : indicates that the ItemBlock is a Default and can be overridden by a previously exported ItemBlock.
Update Based on feedback, it was decided that supporting Default ItemBlocks will be put on since it felt that it was more academic and there were currently use cases requiring it. This could be added at anytime and should be pretty easy to do.
Adding Namespaces - Suggestion
One concern that has been raised has been how to better control the inheriting process since the current design is heavily dependent on the order in which the included files are processed. One idea is to introduce the concept of namespaces. The idea would be to introduce a Namespace XML attribute to the ItemBlocks XML node. The idea is that if specified, the ItemBlocks defined with an ItemBlocks node that specify a Namespace XML attribute would be considered part of that namespace. When referring to an ItemBlock with an associated namespace, the designer would add a Namespace XML attribute. If none is specified, it is assumed to be in the global namespace.
Adding Using Support
We could also add a Using XML node to the Definitions XML node that would act similar to the C++ using directive and would add those namespace names to a list that should be searched when looking for an ItemBlock Definition.
- If a namespace is declared in multiple included files and an ItemBlock name has been multiply defined, the above inheriting mechanism would then be used.
- If an ItemBlock name exists in multiple namespaces and as a result of using the Using mechanism, this would result in an error stating that there is ambiguity.