Copyright
© 2001 Object Technology International, Inc.
 
Help – Part 1
Contributing a little help
Summary
The Eclipse platform’s help system defines two extension points ("contributions"
and"contexts")
that allow individual plug-ins to contribute online help and context-sensitive
help for their components. In this article we will investigate the “contributions”
extension point and how you can use it to contribute documentation for
your plug-in.
By Greg Adams, OTI and Dorian Birsan, IBM 
  Updated May 28, 2001 
Editor's note: This article describes the help system for Eclipse 
  release 1.0. There is an updated 
  version of this article for Eclipse release 2.0.
  
Introduction
The Eclipse platform’s help system allows you to contribute your plug-in’s online 
help using the org.eclipse.help.contributions extension point. You can either 
contribute the online help as part of your code plug-in or provide it separately 
in its own documentation plug-in. This separation is beneficial in those situations 
where the code and documentation teams are different groups or where you want 
to reduce the coupling/dependency between the documentation and code. The platform’s 
help facilities provide you with the raw building blocks to structure and contribute 
your help. It does not dictate structure or granularity of documentation. The 
platform does however provide and control the integrated help viewers thus ensuring 
seamless integration of your documentation. 
The org.eclipse.help.contributions extension point provides four elements
through which you can contribute your help, they are:
- 
topics
- 
infoset (also known as a book)
- 
infoview
- 
actions (also known as wiring)
The topics, infoset and actions contributions all specify an associated
xml file that contains the details of the contribution. In the remainder
of this article we will create a documentation plug-in that uses all four
of these elements. By the time we’re done, you’ll have your first online
help plug-in.
Making the plug-in and content
A content author supplies one or more HTML files containing the actual
documentation. There are no restrictions imposed by the platform on the
granularity of the HTML files. That is, the documentation authors can opt
to use one massive HTML file, or numerous smaller granularity HTML files.
We will start by assuming that you already have some html files that you
want to integrate into the Eclipse platform. Let’s assume your content
is arranged into the following directory tree.
doc/
   concepts/
       concept1.html
       concept1_1.html
       concept1_2.html
   tasks/
       task1.html
       task2.html
       task3_1.html
       task3_2.html
   ref/
       ref1.html
       ref2.html
Create a plug-in directory called org.eclipse.helparticle and place the above 
doc\ sub-tree into it. Now create an initial plugin.xml file with 
the following content: 
<?xml version="1.0"?>
<plugin
   name = "Online Help Sample"
   id = "org.eclipse.helparticle"
   version = "0.9"
   provider-name = "Object Technology International,
Inc.">
</plugin>
To help you get started here is a zip file containing the above initial 
plug-in structure. This plug-in manifest file doesn't actually integrate anything 
yet but soon we will add our contributions to it. 
 
 
Topics & HTML Content
Now that we have our sample content files we are ready to create our topics
file.
A topics file defines the key entry points into the HTML content files
by mapping a topic id and label to a reference in one of the HTML files.
A topics file acts like a table of contents for a set of html content.
Teams migrating onto the Eclipse platform can quickly reuse existing documentation
by defining entry points into their existing documentation via the topics
file. A plug-in can have one or more topics files. Topics files are sometimes
referred to as navigation files since they describe how to navigate the
html content. We have three main content areas, concepts, tasks and reference.
Our obvious choices are one big topics file, or a topics file for each
main content area. Keep in mind this decision is ours to make, and is not
a decision the platform dictates to us. If we were “really” writing our
documentation we would have a larger number of files so, with that in mind
we will try and keep things manageable by creating a topics file for each
of the three content areas as follows:
topics_Tasks.xml
<topics id="tasksAll">
    <topic id="plainTasks" label="Plain Stuff">
        <topic label="Task1"
href="doc/tasks/task1.html"/>
        <topic label="Task2"
href="doc/tasks/task2.html"/>
    </topic>    
<topic id="funTasks" label="Fun Stuff" >
        <topic label="Task3_1"
href="doc/tasks/task3_1.html"/>
        <topic label="Task3_2"
href="doc/tasks/task3_2.html"/>
    </topic>
</topics>
topics_Concepts.xml
<topics id="conceptsAll">
    <topic label="Concept1" href="doc/concepts/concept1.html">
        <topic label="Concept1_1"
href="doc/concepts/concept1_1.html"/>
        <topic label="Concept1_2"
href="doc/concepts/concept1_2.html"/>
    </topic> </topics>
topics_Ref.xml
<topics id="refAll">
    <topic label="Ref1" href="doc/ref/ref1.html"/>
    <topic label="Ref2" href="doc/ref/ref2.html"/>
</topics>
Topics are contributed as part of the topics container element. A topic 
can be a simple link to content (e.g. Task1) or a hierarchical grouping of sub-topics 
(e.g. Fun Stuff), or both (e.g. Concept1). When we start wiring these topics into 
the overall documentation web we will refer to them by their id. When used as 
a link, the argument to href is assumed to be relative to the current plug-in. 
Only topics with an id can be manipulated. We can also refer to the id associated 
with the topics element if we want to refer to all of its enclosed topic entries. 
Later we will modify the plugin.xml to add the actual contributions pointing to 
these files. 
Creating a book
Now that we have our raw content and topic files it’s time to create our
infoset. An information set (infoset) is a documentation web or book. The
Eclipse platform can display any number of infosets. An infoset contains
one or more infoviews. An infoview provides a high-level semantic grouping
within the infoset. Infoviews could be used to create multiple views onto
the document web. For example we could use them to create an integrated
view of documentation supplied by many components, or a component based
view. We could also use them to create separate views for getting started,
tasks and concepts, or as we will shortly do, create one infoview to show
them all. The term infoview is used to avoid collision/confusion with the
term view in the platform’s user interface. Each infoview contains a collection
of topics. Sometimes a higher-level component or product team is responsible
for weaving together the documentation and topics supplied by a number
of its component teams. For our purposes we’ll assume that our plug-in
should supply both the topics and the book that integrates the topics.
Towards the end of the article we will look at how to make your documentation
plug-in live happily in both a component world and a product world.
 
The following infoset has id “infoset_SampleGuide” and declares one
infoview whose id is “view_Contents”. The id of the infoview will become
important as we start wiring in the high level structure for the infoview,
and ultimately wiring in the topics we defined earlier.
infoset_SampleGuide.xml
<infoset id="infoset_SampleGuide" label="Online Help
Sample" href="doc/splash.html">
    <infoview label="Content" id="view_Contents"
/>
</infoset>
Selecting the book called "Online Help Sample" shows one possible infoview
called "Content". The following figure shows the eventual look of our help.
If multiple infoviews had been declared by our xml file they would show
up as additional "infoview tabs" alongside the "Content" tab. Notice that
our splash page (contained in splash.html  and declared above) is
also displayed. 

 
Wiring in the top level structure
Next on our agenda is to define the top-level structure that a user will
see within our “Contents” infoview. We start by creating the following
topics file for the top-level topics:
topics_view_Contents.xml
<topics id="topics_view_Contents">
    <topic id="conceptsRoot" label="Concepts"
/>
    <topic id="tasksRoot" label="Tasks" />
    <topic id="funRoot" label="Fun Things" />
    <topic id="refRoot" label="Reference" />
</topics>
Now comes the fun part, time to “wire in” these topics into our “Contents”
infoview. Once we’ve done that we can then proceed to wire in all of our
other topics underneath the above top-level topics. We start by wiring
in the top-level topics using the following actions
file.
actions_view_Contents.xml
<actions infoview="org.eclipse.helparticle.view_Contents">
    <insert
        from="org.eclipse.helparticle.topics_view_Contents"
        to="org.eclipse.helparticle.view_Contents"
        as="child"/>
</actions>
The following snapshot shows what our infoset (Outline Help Sample) will
look like as a result of wiring in these top-level topics. The title (label)
of the infoset is only displayed in the combo box if there is more than
one infoset.
 
  
Taking a closer look at actions
Before we continue let’s take a closer look at the action file 
  and the action elements it contains. The actions file contains scripting actions 
  to be performed on topics and infoviews. Currently there is only one kind of 
  action, the insert action, which is used to wire topics and views together into 
  one integrated information web. The actions are structural actions (insert) 
  and, thus, apply to a certain infoview. So, all the insert actions in an actions 
  file wire their topics into one infoview. If you want to wire into different 
  infoviews, you will need an actions file for each. The insertion points can 
  be topics or infoviews.  A topic indicates its willingness to be an insertion 
  point by providing an id. Infoviews are required to have id's.  Only fully 
  qualified ids are used as references. For example, the fully qualified topic 
  id of the topic <topic id="conceptsRoot " label="Concepts">  in our 
  org.eclipse.helparticle plug-in is org.eclipse.helparticle.conceptsRoot. In 
  the above actions file we took the topics element with fully qualified id "org.eclipse.helparticle.topics_viewContents"  
  and wired it into the infoview with id "org.eclipse.helparticle.view_Contents". 
Since the insertion points are sometimes located in other plug-ins,
and these plug-ins may not be installed, one can specify an alternate insertion
point. By default, if none of the choices succeed, the topic stays under
its component hierarchy. The "to" attribute specifies the target insertion
point. The topic specified by the "from" attribute is the topic being inserted. 
Followings are some possible ways to insert a topic and they are specified
using the "as" attribute:
- 
As a child of the insertion point, which is the most common. Attribute: 
as = "child".
- 
As the first child of the insertion point. Attribute as = "first-child".
- 
As the last child of the insertion point. Attribute as = "last-child".
- 
As the previous sibling of the insertion point (i.e., just before the insertion
point at the same level in the navigation tree). Attribute as = "prev-sib".
- 
As the next sibling of the insertion point (i.e., just after the insertion
point at the same level in the navigation tree). Attribute as = "next-sib".
Alternative insertion options can be provided. The nested insert sub-elements 
of the insert element provide these alternatives. This can be thought of as a 
"fall-back" mechanism where if an insert action fails, the nested insert action 
will be executed. Once the first choice insertion point has been satisfied, the 
other alternative insertion points are ignored.
 
Integrating our topics
The time has come to finally integrate our topics into the top-level topics of 
the “Contents” infoview. To do this we need another actions file that we will 
call actions_All.xml (since it integrates all of our topics). 
actions_All.xml
<actions infoview="org.eclipse.helparticle.view_Contents">
    <insert
        from="org.eclipse.helparticle.conceptsAll"
        to="org.eclipse.helparticle.conceptsRoot"
        as="child"/>
    <insert
        from="org.eclipse.helparticle.refAll"
        to="org.eclipse.helparticle.refRoot"
        as="child"/>
    <insert
        from="org.eclipse.helparticle.plainTasks"
        to="org.eclipse.helparticle.tasksRoot"
        as="child"/>
    <insert
        from="org.eclipse.helparticle.funTasks"
        to="org.eclipse.helparticle.funRoot"
        as="child"/> </actions>
Recall that we had a number of task related html files, and the structure/navigation
of these files was defined by topics_tasks.xml as follows:
topics_Tasks.xml
<topics id="tasksAll">
    <topic id="plainTasks" label="Plain Stuff">
        <topic label="Task1"
href="doc/tasks/task1.html"/>
        <topic label="Task2"
href="doc/tasks/task2.html"/>
    </topic>
    <topic id="funTasks" label="Fun Stuff" >
        <topic label="Task3_1"
href="doc/tasks/task3_1.html"/>
        <topic label="Task3_2"
href="doc/tasks/task3_2.html"/>
    </topic>
</topics>
In the above actions file we use the insert as child action to take the topic 
with id org.eclipse.helparticle.plainTasks and insert it and its sub-topics under 
the topic with id org.eclipse.helparticle.tasksRoot 
<insert
    from="org.eclipse.helparticle.plainTasks"
    to="org.eclipse.helparticle.tasksRoot"
    as="child"/>
The actions file also takes some of our more entertaining tasks and inserts
them into the “Fun Things” area of the web using the following action.
<insert
    from="org.eclipse.helparticle.funTasks"
    to="org.eclipse.helparticle.funRoot"
    as="child"/>
Finishing our plugin
Before we continue a brief recap is in order:
- 
We started by creating our plug-in and document files.
- 
Next we created topic files to describe the structure/navigation of our
content.
- 
We then moved up one level above content, to the wiring and integration
of our book. To do this we created our infoset with its single Contents
infoview.
- 
Next we created another topics file (topics_view_Contents.xml) to define
the top-level topics.
- 
Finally we wired it all together using the action files actions_view_Contents.xml
(to wire in the top level topics) and actions_All.xml (to wire in the bulk
of our topics).
The one remaining piece of work is to update our plugin.xml to actually
contribute the action, topics, and infoset files that we created. Start
with updating the plugin.xml to contribute our infoset:
<extension point="org.eclipse.help.contributions">
    <infoset name="infoset_SampleGuide.xml"/></extension>
Next we contribute the top-level topics, and the actions file that wires
them into our infoset:
<extension point="org.eclipse.help.contributions">
    <topics name="topics_view_Contents.xml"/>
    <actions name="actions_view_Contents.xml"
/>
</extension>
Lastly we contribute the bulk of our topics and wire them in:
<extension point="org.eclipse.help.contributions">
    <topics name="topics_Concepts.xml" />
    <topics name="topics_Tasks.xml" />
    <topics name="topics_Ref.xml" />
    <actions name="actions_All.xml" />
</extension>
That’s it, you’re done. Now take your plugin (click here for a zip 
file of the final plugin) and drop it into the platform’s plugins directory, 
start eclipse and choose Help -> Help Contents. Once you expand the topics in 
the “Contents” infoview you will see the following. 
 
 
 
   
 
Non-integrated components
What if we expect our plug-in will sometimes be installed by itself, and in other 
cases it will be installed as part of a larger component or product. When deploying 
a free floating plug-in we want to ensure that our infoset is visible. When topics 
from a plug-in are integrated into a larger web it probably doesn’t make sense 
for their standalone book to show up anymore. To support this nonintegrated or 
loosely integrated documentation, a plug-in can define an infoset and associated 
actions and set their standalone attribute to true. This has the effect 
of executing the inserts only when those topics have never been contributed anywhere 
else and only display the infoset if it is not empty. In other words, this behaves 
as: "if this is an independent plug-in, and there are no topics contributed to 
some well-known infoset, then insert the documentation into a standalone info 
set". Empty standalone infosets are not shown. This really says that if the topics 
contributed by the plug-in are inserted into well-known infosets, then the standalone 
actions did not insert anything in the standalone infoset, so just ignore this 
empty infoset. Setting standalone attributes on actions and infosets is useful 
when providing a "Catch all" scenario, when documentation cannot be contributed 
to a well-known infoset but the plug-in documentation should still appear somewhere. 
To support standalone mode we need to make the following additions to our infoset 
and action xml files. The addition is marked in bold. 
infoset_Guide.xml
    <infoset id="infoset_Guide"label="Online
Help Sample" href="doc/splash.html"
standalone="true">
actions_All.xml
    <actions infoview="org.eclipse.platform.doc.user.view_Contents"
standalone="true">
actions_view_Contents.xml
    <actions infoview="org.eclipse.platform.doc.user.view_Contents"
standalone="true">
Now if someone includes our topics our actions will not be used, and
consequently our infoset will be empty and not show up.
 
 Externalizing Strings in your XML files
Plugin.xml files externalize their strings by replacing the string with
a key (e.g. %pluginName) and creating an entry in the plugin.properties
file of the form:
    pluginName = “Online Help Sample Plugin”
The contribution XML files are externalized using a similar approach.
To externalize <topic id="plainTasks" label="Plain Stuff"> we replace
its label with a key %plainStuff . Our topic now looks like:
    <topic id="plainTasks" label="%plainStuff">
Create an entry in the document.properties file containing the entry:
    plainStuff = Plain Stuff
The help system will use document.properties when looking up strings
externalized by our online help contributions.
 
Server and zip files
The platform utilizes its own documentation server to provide the actual web pages 
from within the document web.  A custom server allows the platform to handle 
the wide variety of web browsers in a browser independent way while also providing 
plugin aware support. The platform's help server allows the documentation to also 
be deliver in a zip file thus avoiding problems that may result when a large number 
of files are present. In our example plugin we created a sub-directory called 
"doc". Alternatively we could have placed our html files into a zip file called 
"doc.zip". 
 
Conclusions
We have seen how we can use the infoset, infoview to declare books the
user can see. We then used the actions contribution and the topics contribution
to declare and integrate our topics. The platform’s mechanisms can be used
to integrate new documentation, or to quickly wire in existing html based
documentation without rewriting it. The mechanisms allow you to create
multiple different views onto your documentation web. In our plug-in we
only created a single infoview but additional infoviews could easily be
created. Component documentation can either be written to be a standalone
book, or optionally marked such that if it is integrated into a larger
document web, the individual component book will automatically be hidden.
Lastly, we observed that the platform provides the building blocks for
doc integration but does not set out any style or structuring guidelines.