Sunday, January 13, 2008

Attachments Hack

Until recently, my development work was sequestered to either the Notes Client or the Browser, with very little crossover. A project I'm currently working on made me realize how much I take for granted the ease of programming for just the Notes Client. Even browser-only programming is just slightly more work. Trying to get your application to behave nicely in both worlds can be a bit of a challenge.

Although on a basic level Notes does a fairly nice job of translating between these two worlds, there are some paradigms that work but take alot of effort to approximate. One of those paradigms that does not translate easily between the two platforms is file attachments.

If you've ever worked with attachments in both worlds, you know that Domino sticks them at the bottom of your web page and not in the rich text field you had them in on the Notes client side — rich text is another thing that doesn't translate well, but that's a subject for a future post. To get attachments to approximate the Notes Client experience, start out by borrowing some code from Jake's example database for handling attachments on the web. He uses a few hacks such as '$V2AttachmentOptions', and '%%Detach', along with the familiar '$File', '@Attachments', and '@AttachmentNames'.

That should cover things from the browser side, now throw in a little LotusScript in the WebQuerySave event from the Breaking Par website to clean things up for anyone seeing the document on the Notes client side.
**See my tip at the bottom.

Here's my version of the Breaking Par code sample that I wanted to share:


Option Public
Use "OpenLogFunctions"

Sub Initialize
' This agent moves a file attached via the Web with the File Upload Control to a rich text field.
' Much credit to the Breaking Par site http://www.breakingpar.com
On Error Goto ERRORHANDLER

Dim doc As notesDocument
Dim s As NotesSession
Dim tempDir As String
Dim attached As Variant
Dim fileToEmbed As notesEmbeddedObject
Dim filePath As String
Dim rtItem As notesRichTextItem
Dim moveToFieldName As String

Set s = New notesSession
Set doc = s.documentContext
Let moveToFieldName = "rtf_Attachments"
numAtt = Evaluate("@Attachments", doc)

If numAtt(0) > 0 Then
attached = Evaluate("@AttachmentNames", doc)
tempDir = s.getEnvironmentString("Directory", True)
'Put a trailing slash at the end of the directory if it is needed
If Instr(tempDir, "/") <> 0 And Right(tempDir, 1) <> "/" Then tempDir = tempDir & "/"
If Instr(tempDir, "\") <> 0 And Right(tempDir, 1) <> "\" Then tempDir = tempDir & "\"

Forall i In attached 'extract all attachments to the file system
If i <> "" Then
Set fileToEmbed = doc.getAttachment(i)
filePath = tempDir & i
Call fileToEmbed.extractFile(filePath) ' Save the file on the server
End If
End Forall

Forall i In doc.Items 'remove all attachments from document
If i.Type = 1084 Then
Call i.Remove
End If
End Forall

Call doc.RemoveItem(moveToFieldName) 'remove current attachments field...
Set rtItem = New notesRichTextItem(doc, moveToFieldName) '...and start over

Forall i In attached 're-attach the files to the rich text field
filePath = tempDir & i
Call rtItem.embedObject(1454, "", filePath)
Kill filePath ' Delete the file(s) from the server file system
End Forall
End If

Exit Sub
ERRORHANDLER:
Call LogError
End Sub


This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.


Although we rely on these 'hacks' to get Notes to behave in these two different worlds, I feel that this is what makes Notes such a valueable tool in the enterprise. And by extension, makes Notes developers valuable too. Leave a comment if you now of any other attachment hacks.


** I know blogs like CodeStore have become the 'go to' sites for sample solutions; Lord knows I rely on them a ton. The new stuff is great, but the old Breaking Par site still has alot of great information, as do the Notes forums at Developerworks. Similarly, I used to rely alot on the old notes list, LNotesL, but it died not too long ago; some posts have been archived though.

0 comments: