About Custom Elements
Most of the data processed by a template come from some external data source
via its virtual XML-like representation called Data Source Model (DSM),
which maps everything onto some elements and their attributes.
Therefore, most of the functionality available in templates (such as iterators,
hash-maps and so on) is intended for processing of elements and attributes.
But what if you want to use that functionality to process some different data,
for instance, those coming from template parameters or elsewhere?
Custom elements allow you to do that!
Using custom elements, you can wrap any your data in the form of elements
and attributes. Further, you can process such elements using
standard means either separately or together with some
elements from the main data source.
Basically, you may need custom elements in two situations:
-
1). Extending or completing a set of ordinary elements
of the main data source.
Suppose you have some set of references (coming, for instance,
from the values of attributes of other elements).
Those references contain the qualified names of some elements
that you need to print.
-
At minimum, you should print just the element names.
But it will be much better if you add some extended information
about each element.
Most of the referenced elements can be found in the data source.
The problem is that a few of them may not exist there.
That's because those few elements represent some well-known entities,
which do not need to be copied everywhere (e.g. this may be some built-in
predefined data types and so on). Everyone who knows the subject of that
external data source must also know about those basic things.
-
Well. Everyone, but not your templates!
If all the references could be resolved into elements, you would just
feed those elements to an Element Iterator, sort them as needed and
print everything about each element. But a few elements may be not found,
and yet you should print something about them too.
At least their names... You have them from the references.
But how can you feed such names, which are strings, to the Element Iterator?
Very simply. You should wrap each string with the name in a custom element
and pass that element to the Iterator along with the elements from the data source.
You can even construct such custom elements so that they will look like real ones
(e.g. contain some attributes expected from the real elements).
For instance, you may assign the name taken from the reference
to the "name" attribute. This may allow you to specify sorting of
all elements uniformly (e.g. by the values of "name" attributes contained
in both real and custom elements).
-
2). Using element/attribute functionality for non-DSM data.
Another situation is when you have some data completely different from
the main data source. However, you want to process them with some functionality
available only for elements and attributes.
-
Here is an example.
Suppose you need to design a template to process (document) certain "custom tags"
coming from the external data source.
Those tags describe some data source specific things.
To a template, all such tags will appear as ordinary DSM elements of the same type
and all the properties of the tags will be represented by the values of the element
attributes.
-
The "custom" means that some critical properties of those tags (such as possible
tag names and their meanings) are unknown in advance. Instead, they are created
by the user who produces the
data source. In fact, the same person may be using your template to document
his/her data source (which may be actually a representation of some project written
in Java or other language).
What is more, the user may want to be able to customize easily the appearance of
specific custom tags in the output documentation, for instance, to provide
the tag title and so on. At that, the user does not want to customize your template
each time a new tag is introduced. How can you implement such requirements?
You can do this by introducing a special template parameter
'customTag'
using which the user can specify how to document each particular custom tag.
The parameter would accept a multiple (list) value.
Each value item would specify a tag name and how to document that tag
(e.g. the tag title and other things).
-
Further, in your template, the first thing you may program to do will be
parsing all the tag specifications passed via
'customTag' parameter.
By each tag specification, you can create a custom element and store
all the settings from the specification as element attributes.
You can put each element in some
'custom-tags'
element map (which is a special kind of hash-maps adopted for DSM elements)
using the tag name as the hash key.
What is the advantage of all of this?
Using the 'custom-tags' element map,
you can find very quickly for each custom tag all the user-provided information
about how to document that tag! Without the element map, you would need
to re-parse the entire 'customTag' parameter
value each time you needed to process a particular tag.
That would slow down the processing very much (if not making it impossible)!
|
Using Custom Elements
Custom elements are created with CustomElement()
function.
You can load a custom element with some useful data
by specifying its value when you create it:
myData = ...; // some your data
...
el = CustomElement (myData);
Later, you can access the data via the GOMElement.value
property:
echo ("My data: " + el.value);
Additionally, you can attach to your custom element
any number of other pieces of information using attributes.
You can do it immediately, when you create the element:
value0 = ...; // some data
value1 = ...; // you want to associate
value2 = ...; // with a custom element
...
el = CustomElement (value0,
Array (
Attr ("item1", value1),
Attr ("item2", value2)
)
);
or you can add the attributes sometime later:
el.setAttr ("item1", value1);
el.setAttr ("item2", value2);
Further, you can access the values of such attributes
using any of the functions available for it:
echo ("value1: " + el.getAttrValue ("item1"));
A custom element may have unlimited number of attributes.
Using setAttr()
function, at any time, you can add new attributes
or change the values of existing ones.
You can equally remove any of the attributes:
el.removeAttr ("item1");
Effectively, each custom element serves as a hash-table of its attributes.
Custom Element Features
(1) Custom elements are created with CustomElement()
function, which returns an instance of GOMElement
type.
(2) Each instance returned by CustomElement()
function represents
a separate DSM element assigned with a unique ID irrelevant of what the element content
might be. For example, the following expression is always true:
-
CustomElement("one").id != CustomElement("one").id
You can retrieve a particular custom element by its ID
using findElementByID()
function.
(3) All custom elements have '#CUSTOM'
element type,
by which you can find or filter them for specific processing.
(4) Although custom elements are considered to be part of the DSM and
maintained by the DSM driver, they are not connected in any way to the external
data source (represented by that DSM).
Any data possible to obtain from a custom element are only those
that have been assigned to it initially in the form of the element value
and its attributes.
(5) The values of custom elements and their attributes have
'Object'
data type and may be single-component only
(no list values are possible).
For instance, that means that for a custom element the following expression
is always true:
-
el.value == el.fullValue
However, you can assign the objects of any types (including null
)
to values of custom elements and their attributes.
(6) Custom elements have no children and
cannot be children of any other elements.
Once all references to a custom element or its ID have been lost,
that element is lost too. After that, there is no way to retrieve it back!
The unused instances of custom elements may be automatically recycled and, then,
reappear back with the same IDs during the next CustomElement()
function calls. However, any old data previously associated with the recycled
custom elements will be lost.
(7) In any other respect, custom elements may be used
the same way as ordinary once. For instance, you can feed them to
Element Iterators, put in element maps and so on.
See Also:
GOMElement, CustomElement(), CustomElements(), Attr(), Array(),
setAttr(), removeAttr(), getAttrValue(), findElementById()