SPFE Documentation | Collections > SPFE Development > Fragments

Fragments

Fragments are a content reuse feature of the EPPO-simple plugin.

A fragment is an arbitrary sequence of text structures (paragraphs, lists, etc.) that has been given an id so that it can be included by reference at other points in the content.

Fragments can be defined inline in a topic file, or they can be defined in separate fragment collections. If a fragment is defined inline, it is included where it occurs. Fragments in fragment files are not included anywhere unless they are pulled in by a fragment reference.

A fragment reference inserts a fragment by ID at the place it occurs in the text.

Fragments are recursive. That is, fragments can contain other fragments and fragment references.

Because you often want to change some part of a text when it is being reused, fragments and fragment references can both define local strings. Any string references inside a fragment will be resolved by looking first at local-strings defined in the fragment reference, then at local strings defined in the fragment definition, and then at global strings. In effect, this means that you can define string substitutions whenever you insert a fragment into your content.

The following sample show the definition of a fragment and its subsequent use within the same file.

<fragment id="test-fragment">
    <local-strings>
        <string id="test-string-1"><bold>test string one</bold></string>
        <string id="test-string-2"><italic>test string two</italic></string>
    </local-strings>
    <p>This is a piece of text in a fragment. It includes references to local 
       strings <string-ref id-ref="test-string-1"/> and 
       <string-ref id-ref="test-string-2"/>. 
       And to a global string <string-ref id-ref="product"/></p>
</fragment>
<p>The following is a reference to the fragment defined above:</p>
<fragment-ref id-ref="test-fragment">
    <local-strings>
        <string id="test-string-1"><code>this is test string number one</code></string>
        <string id="product">Acme Anvil</string>
    </local-strings>
</fragment-ref>

When the topic containing this fragment and fragment ref is resolved, and assuming that there is a more globally defined string with the ID product and the value “SPFE Open Toolkit”, the result will be as follows:

<p>This is a piece of text in a fragment. It includes references to local 
   strings <bold>test string one</bold> and 
   <italic>test string two</italic>. 
   And to a global string SPFE Open Toolkit.</p>
<p>The following is a reference to the fragment defined above:</p>
<p>This is a piece of text in a fragment. It includes references to local 
   strings <code>this is test string number one</code> and 
   <italic>test string two</italic>. 
   And to a global string Acme Anvil.</p>

As the fragment itself was being resolved, it the string references it contains were resolved using the local string definitions it contained and the global definition of product. As the fragment ref was being resolved, the string references it contains were resolved by first looking at the local string definitions it contained, than at the local string definitions of the fragment, then at the global string definitions. In this case, the fragment ref contained local definitions for the test-string-1 and product strings, and use the value of test-string-2 from the fragment definition.

Note that inline fragment definitions can only be referenced by a fragment references in the same file in which they occur. You cannot reference a fragment defined inline in another topic in the topic set. You can reference external fragments that are defined in an external fragments file. Also note that if you define a local fragment with the same ID as a global fragment, the local fragment will be used by any fragment reference in the file in which it occurs.

Fragments vs. conrefs

Fragments perform a function similar to that performed by conrefs in other systems. Conrefs (content references) are a mechanism for reusing content by reference from one file to another. The most commonly use application of conrefs today is in DITA. If you are used to using conrefs, this section will explain the differences between SPFE fragments and DITA conrefs.

Note that fragments are actually not a feature of SPFE proper. They are a feature of the EPPO-simple schema set. The resolution of fragments is performed as part of the schema resolve script for the EPPO-simple namespace. You could develop a schema set that implements conrefs if you wanted to, and resolve the conrefs in the resolve script of that schema set.

First, a fragment is defined by an elements that contains the content of the fragment. Only defined fragments can be included by a fragment ref. The source of a conref is not defined in any special way. Any element with an ID can be the source of a conref. You create a conref by adding an attribute to any element that supports the conref attribute and giving it the URL of the element you want to reference. This means that the conref mechanism give no indication that an element is being conrefed, or that editing it might change to meaning of the text that is conrefing it, or that deleting it might break the conref. A fragment, by contrast, makes it explicit that the text it contains is potentially being referenced elsewhere.

Second a conref can reference any element in any file. A fragment reference can only reference a local fragment in the same file or a global fragment in a fragments file. It cannot arbitrarily reference any content anywhere. This restriction corresponds to a frequently recommended best practice for handling conrefs -- namely to avoid arbitrary conrefs and only conref to material specificlly created for the purpose.

Third, a conref can only reference an element of the same type as the element that contains the conref. A fragment is an element in its own right, so it can contain any content of any length.

Forth, a conref uses a URL, to point to a specific file. A fragment uses an ID. This allows you to change which fragments are used by substituting a different fragments file with the same set of IDs. Note, however, that DITA supports conkeyrefs, in which the conref uses a key rather than a URL. This give you much the same capability as fragments.

Fifth, a conref can be used at any level of the tree structure of a document. You can conref a single word in a sentence. Fragments are supported only at the text structure level of the EPPO simple schema. You can't use a fragment to replace a single word in a sentence (though you can use string for this). You also can't use fragments to, for instance, reference a single step from a procedure or a single item from a list. This is because the fragment can contain an arbitrary sequence of elements that can occur at the text structure level of a schema, but which might not be allowed in a list item or a step. This prevents you from creating a fragment that produces invalid content when resolved. It should be noted that it is often recommended to use conref at a low level because of the complexity it creates in a document.

Sixth, fragments support the redefinition of local string in a fragment ref. Conrefs do not. This allows for more flexible use of fragments.

Seventh, fragments can be recursively defined. Conrefs cannot (though you can conref text that is part of a larger structure that is also being conreffed.

Eighth, fragment IDs can shadow more gobal fragment IDs, allowing local redefinition of a fragment. Conrefs cannot (though DITA conkeyref can accomplish something similar).

Overall, the design of fragments is meant to emphasize safety and transparency over maximizing reuse. At the same time, the ability to redefine local string and to nest fragments and override their IDs with local definitions, gives a capacity for reuse with variation not found in conrefs.