NAME
File::Tabular::Web::Attachments - Support for attached document in a File::Tabular::Web application
DESCRIPTION
This subclass adds support for attached documents in a File::Tabular::Web application. One or several fields of the tabular file may hold names of attached documents; these documents can be downloaded from or uploaded to the Web server.
Phases of file upload
When updating a record with attached files, files are first transfered to temporary locations by the "before_update" method. Then the main record is updated as usual through the parent method. Finally, files are renamed to their final location by the "after_update" method. If the update operation failed, files are destroyed by the "rollback_update" method.
CONFIGURATION FILE
There is one single addition to the configuration file.
[fields]
upload <field_name_1>
upload <field_name_2>
...
Declares field_name_1
, field_name_2
, etc. to be upload fields.
WRITING TEMPLATES
Downloading attachments
To link to an attached file, use the "download" method :
[% FOREACH record IN found.records %]
<A HREF="[% self.download(record, 'AttachedField') %]">
download document [%- record.AttachedField -%]
</A>
<HR>
[% END # FOREACH %]
Uploading attachments
To upload an attachment, use a input element of type FILE
, within an HTML form encoded as multipart/form-data
. Since HTML file input elements cannot have an initial value, it may be a good practice to indicate if an attachment is already present in this field and if so, insert a download link :
[% SET record = found.records.0 %]
<FORM METHOD="POST" ENCTYPE="MULTIPART/FORM-DATA">
<INPUT NAME="Field1" VALUE="[% record.Field1 | html %]"><br>
<INPUT NAME="Field2" VALUE="[% record.Field2 | html %]"><br>
..
<INPUT NAME="AttachedField1" TYPE="FILE">
[%- IF record.AttachedField1; # if an attachment is already present -%]
(current attachment :
<A HREF="[% self.download(record, 'AttachedField1') %]">
[%- record.AttachedField1 -%]
</A>)
...
</FORM>
METHODS
app_initialize
Calls the parent method. In addition, parses the upload
variable in [fields]
section, putting the result in the hash ref $self->{app}{upload_fields}
.
open_data
Calls the parent method. In addition, checks that fields declared as upload fields are really present in the data.
before_update
Calls the parent method. In addition, uploads submitted files to a temporary location in the application directory.
after_update
Calls the parent method, then renames the uploaded files to their final location.
rollback_update
Unlinks the uploaded files.
after_delete
Calls the parent method, then suppresses files attached to the deleted record.
do_upload_file
Internal method for implementing the file transfer. Checks that we are not going to clobber an existing file on the server.
generate_upload_name
my $name = $self->generate_upload_name($record, $field_name, $remote_name)
Returns the name that will be stored in the record field for the attached document. The actual path for that document on the server will be generated through method "upload_fullpath". The default implementation returns the last part of $remote_name
(removing initial directories).
upload_path
my $path = $self->upload_path($record, $fieldname)
Returns a relative path to the attached document. The default implementation takes the numeric id of the record (if any) and concatenates it with the name generated by "generate_upload_name"; furthermore, this is put into subdirectories by ranges of 100 numbers : so for example file foo.txt
in record with id 1234
will become 00012/1234_foo.txt
. This behaviour may be redefined in subclasses.
upload_fullpath
my $fullpath = $self->upload_fullpath($record, $fieldname)
Returns a full pathname to the attached document. This is the location where the file is stored on the server. The default value is the concatenation of $self->{app}{dir}
and $self->upload_path($record, $field)
.
download
my $url = $self->download($record, $fieldname)
Returns an url to the attached document, relative to the application url. So it can be used in templates as follows
[% IF record.fieldname %]
<a href="[% self.download(record, 'fieldname') %]">
Attached document : [% record.fieldname %]
</a>
[% END; # IF %]
hooks before / after adding or deleting attachments
$self->after_add_attachment($record, $field, $path)
$self->before_delete_attachment($record, $field, $path)
These methods are called each time an attachment is added or deleted. The default implementation is empty. Subclasses may add code for example for converting the file or indexing it (see File::Tabular::Web::Attachments::Indexed).
AUTHOR
Laurent Dami, <laurent.d...@justice.ge.ch>
COPYRIGHT & LICENSE
Copyright 2007 Laurent Dami, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.