Creating Attachments Manually

In a Webcrossing standard install, the forms to add a folder, discussion, or message all have a field to attach a file. Attached files show as hotlinks when the node is displayed. (There's also a configuration option to show images inline rather than as a download.)

While there are commands in both WCTL and SSJS to add an attachment to a node, the command takes as an argument an already-existing attachment on another node. One might reasonably ask, how do you script the creation of a new attachment from scratch? It's far from unusual to have to home-brew your node-creation process; sometimes a spec is odd enough that not even with the use of the pre- and post- filters can you shim the program's default behavior. There are scripting commands that directly replicate every part of the node-creation process, except for this one.

Fortunately, it only takes a little extra work. What's really going on is that when attachments are uploaded, they get saved with a MIME wrapper. That sounds like voodoo, but in truth all it means is that a couple of lines of plaintext are prepended to the file's binary content. The content of that header will be familiar to anyone who's ever perused the full headers on an email message. It might look something like this:

Content-Disposition: form-data; name="enclosure0"; filename="IMG_0002heads.jpg"
Content-Type: image/jpeg

This information gets sent by the browser when the upload is transmitted, and it's used to determine how the file should be handled by other clients.

The first step to capturing this is to make sure that your <form> element includes the attribute enctype="multipart/form-data". Leave that off, and only the file names will be uploaded, and you'll be snatching yourself bald trying to figure out why. But once you do that, all you need is to include this SSJS in your processing routine:

var z = form["inputName"];
var h = Mime.formHeader("inputName");
var attach = new ByteBuffer();
attach.append( h );
attach.crlf();
attach.crlf();
attach.append( z );
if (z.length > 0) var attachmentLocation = location.nodeAddAttachment( attach );

This code takes the upload from an file input field whose name is "inputName" and extracts the MIME wrapper, then concatenates it with the binary data to make a well-formed attachment. And that's all there is to it.

No comments:

Post a Comment