Rich Text 101 - Doclinks
Sat 5 Jul 2003, 02:02 PM
by Ben Langhinrichs
Doclinks are an integral part Lotus Notes/Domino, and have been for a long time (OK, I started back in R3 days, and they were used then, but I don't know when they were added), but they still seem a bit mysterious to some developers. I thought I'd kick off this occasional series on rich text topics by explaining a few of the mysteries. I'll try to keep this at a comprehensible level, but no promises.
Composition of a doclink
There are several parts to a doclink. The most critical parts are:
- the DB Replica ID (identifies the database)
- the View Universal ID (identifies the view through which to open the document - more on this later)
- the Note Universal ID (identifies the actual document to open)
As might be expected, a view link contains a null (zero filled) Note Universal ID, while a db link contains both a null Note Universal ID and a null View Universal ID. What is not so expected is that even though a document can be retrieved by universal id from a database (e.g. GetDocumentByUNID method in LotusScript), the view universal id is still critical. See below for the Mystery of the Invalid View. There two other optional parts to doclink which are also related to "navigation". The first is the Server Hint, which is either blank or contains the name of a server. The second is the anchor, which exists when the link is an anchor link . The Server Hint is the subject of much confusion and consternation, as it can lead to accessing a database in Tokyo even when you have a perfectly usable replica at your server in London. See below for the Mystery of the Roving Replica.
Besides the navigational pieces, there is popup text/mouseover text, which is the text which displays in the status bar when you put the mouse over the link in the Notes client. This is known in R5 as the "Link description" and is editable in the properties box when the doclink is selected. It usually contains the database title, the view title and the document subject, but these are purely for visual aid. Similarly, there are various HTML attributes which can be set using the <HTML> tab of the properties box for the doclink.
Mystery of the Invalid View
It is not uncommon to try to access a doclink and have an error such as "Doclink not found" come up, even though you can check and see that the document exists. There are three closely related causes for this mystery, but all three are related to the View Universal ID mentioned above.
- Created from a private view - The user who created the doclink did so while accessing the document from a private view stored on their desktop. When the doclink is accessed, Lotus Notes looks to the view to see if the Note Universal ID exists in that view. If the view does not exist, Notes returns either an error that the doclink is not found or that the view is not found.
- Created from a secured view - The user who created the doclink did so while accessing the document from a view which the current user is not permitted to access. When the doclink is accessed, Lotus Notes looks to the view to see if the Note Universal ID exists in that view. If the view cannot be opened, Notes returns an error that the doclink is not found or that the view is not found or that access is denied, depending on the circumstance.
- Created from a view which no longer contains the document - The user who created the doclink did so while accessing the document from a view which no longer contains the document. This can happen if the document changes status, or if the doclink is created programmatically and the default view does not contain the document. When the doclink is accessed, Lotus Notes looks to the view to see if the Note Universal ID exists in that view. If the document does not exist in that view, Notes returns an error that the document has been deleted or that the "linked document cannot be found in the view".
It is important to ensure that in the normal workflow, doclinks are created from shared views, preferably from an All Documents type of view. It is also important that designers make the default view an All Documents type of view. If these are not possible, it may be wise to use a tool such as our Midas Rich Text LSX to programmatically "fix" the links by re-assigning the View Universal ID in a QuerySave event or a scheduled cleanup agent. In Notes 6, you can also do this with the NotesRichTextDoclink class (but why would you when Midas is so easy?).
Mystery of the Roving Replica
One of the most annoying bugs/features with doclinks has to do with the Hint Server. This is supposed to give the Notes client a hint as to which server to use when accessing the document, so that a replica in a foreign city is not used when a perfectly acceptable replica is available locally or on a server a short distance away. There are two common scenarios:
- Database is accessed from nearby Server A, but doclink was created on distant Server B - The user who created the doclink did so while accessing the document from Server B, so the hint says Server B. Notes thinks it should access the document from the database on Server B, but that is the wrong choice for the current user.
- Database is accessed locally, but doclink was created on Server B - The user who created the doclink did so while accessing the document from Server B, so the hint says Server B. Notes thinks it should access the document from the database on Server B, but that is the wrong choice for the current user since there is a local replica.
What makes this especially annoying is that the server to be used is not obvious. Sometimes Notes will access the replica on Server B even though the doclink was made locally. Sometimes Notes will access the replica on Server A even though it should use Server B since the document has not yet replicated. Sometimes Notes will check multiple servers, but not the correct one. Argghhh!! Update on 08/19/2003: This technote explains the behavior a bit better, even though it is counterintuitive.
Different releases of Notes treat the Server Hint slightly differently, but a few things are generally true. Despite the server Hint, the top replica of the stacked replicas on your Workspace (if you still use the Workspace) is mostly likely to be used if the Hint Server is blank (created from a local replica). Thus, clearing the Hint Server is often the best way to ensure that "your" replica, whether a local database or replica on a nearby server, is used to access the document. Again, Midas can be used to do this or you can use the NotesRichTextDoclink class from Notes 6.
Mystery of the Missing $Links
A mystery for many developers who have tried to access doclink properties is what is the relationship between the $Links field and the doclinks. Sometimes it appears to contain entries for each link, sometimes it doesn't exist at all and yet there are doclinks, and sometimes it contains some, but not all, doclink information.
The basic issue is that there are two forms which a doclink may take. One is the standard form used when a doclink is created by a user using the menu, and in this, there is a CDLINK2 record created in the rich text (Composite Data record stream, for those who think like that), which contains all of the parts listed above except the first three, the replica id and view and note universal ids. Those three pieces of information comprise the NOTELINK information, and are stored as an entry in the $Links item, with just an offset stored in the CDLINK2 record. Actually, the CDLINK2 record does not contain the HTML attributes, but I that is a matter for a different technote.
The second form a doclink may take is a CDLINKEXPORT2 record which contains all of the same information as a CDLINK2 record, except that instead of an offset to $Links, it stores the NOTELINK information (db, view, note ids) directly. The ius the form doclinks take when created by virtually any API solution, or by the LotusScript classes. Midas uses this format as well.
Given these two forms, all three situations make sense. If all links have been created manually, or if the document has been edited manually, which converts the links to CDLINK2 format, then $Links will represent all the doclinks. If some have been created manually and some programmatically, $Links will only contain some of the link information. Finally, if all of the links are created programmatically, there will be no $Links item.
What does this mean> Don't rely on the $Links information. When processing doclinks, use a solution like Midas which hides such silly details and lets you use the doclink information as if it were all stored the way it should be, as CDLINKEXPORT2 records.
So, why do I think everything should be stored as CDLINKEXPORT2, and not the standard CDLINK2 format? Ask yourself what happens if a document with doclinks is shown on a form with doclinks. Oops, perhaps you should ask Lotus, as they don't seem to have a grasp of it.
Mystery of the Incorrect Form
One of the features with doclinks which is not a bug, but is somewhat misunderstood, has to do with a document that opens with the "wrong" form. This has caused much hair pulling by developers and admins, but has a fairly simple cause. If the View Universal ID points to a view with a form formula, the form formula will be used, which can change the form which is used to display the document. This is actually a very powerful feature, allowing you to create doclinks which force users into individual forms, but make sure they know what is going on or they will think Notes is buggy. Nah, that could never be!
Tricky Trick for Anchor Links on Forms
Those developers who actually understand anchor links, and they seem few and far between, often wonder why it is not possible to add anchors to a form and then create links to the anchors. Thus, a long form could have an anchor for its abstract, its footnotes and its table of contents, and a link could be made to each at the top of the form. The problem is, Notes does not give an easy way to create such links, since the anchor link contains a full link to a document, and each document read through the form is different. Here is a trick to create such links on forms, and it works in the Notes client as well as on the web.
- First, pick a journal document or some other document which you can use as a scratch pad. Save it so you will be able to create links from it.
- Create an anchor link using the standard Edit - Copy As Link - Anchor Link, and give it the appropriate anchor name. Paste the anchor link after the anchor marker. Create appropriate text and do a Create - Hotspot - Link to create a hypertext anchor link.
- Repeat Step 2 for each of the different anchors you want on the form.
- Open the Designer while leaving open the Notes client with the scratch document. Copy and paste each of the anchors (not links) from the scratch document to the desired places on the form.
- Now, copy the anchor links or anchor link hotspots to where those should be on the form (e.g. in a mini-menu at the top).
- Final step, use Midas to access the document and blank out the DB Replica ID for each anchor link. When Notes sees these anchor links, it will simply use the current document, whatever that may be.
And there you have it. Anchor links that work with a form.
It's my blog, so I don't have to write any conclusion, except to note that doclinks are wonderful, but wonderful in the way toddlers are wonderful. They're great, you wouldn't want to do without them, but they can make you pull your hair out at the same time.
Copyright © 2003 Genii Software Ltd.