# apostrophe-attachments
# Inherits from: apostrophe-module
# apos.attachments
This module implements the attachment schema field type, which makes it straightforward to allow users to attach uploaded files to docs.
# Options
# addImageSizes
Add an array of image sizes, in addition to Apostrophe's standard sizes. For example:
[
{
name: 'tiny',
width: 100,
height: 100
}
]
The resulting image will not exceeed either dimension given, and will preserve its aspect ratio.
These extra sizes are then available as the size
option to apostrophe-images
widgets
and when calling apos.attachments.url
.
# imageSizes
Like addImageSizes
, but Apostrophe's standard sizes are completely replaced. Bear in mind
that certain sizes are used by Apostrophe's editing interface unless overridden. We recommend
using addImageSizes
.
# fileGroups
Apostrophe will reject files that do not have extensions configured via fileGroups
.
the default setting is:
[
{
name: 'images',
label: 'Images',
extensions: [ 'gif', 'jpg', 'png' ],
extensionMaps: {
jpeg: 'jpg'
},
// uploadfs should treat this as an image and create scaled versions
image: true
},
{
name: 'office',
label: 'Office',
extensions: [ 'txt', 'rtf', 'pdf', 'xls', 'ppt', 'doc', 'pptx', 'sldx', 'ppsx', 'potx', 'xlsx', 'xltx', 'csv', 'docx', 'dotx' ],
extensionMaps: {},
// uploadfs should just accept this file as-is
image: false
}
]
NOTE: adding another extension for images
will not make web browsers
magically know how to show it or teach uploadfs how to scale it. So don't do that.
However, see svgImages
below.
You may add extensions to the office
fileGroup.
# svgImages
If set to true
, SVGs are permitted to be uploaded as "images" in Apostrophe. This
means they may appear in any widget that uses images, such as the apostrophe-images
widget. Since programmatically cropping SVGs across all possible SVG configurations is
difficult if not impossible, manual cropping is not permitted, and autocropping does
not take place either, even if an aspectRatio
option is present for the widget.
To help you account for this, the CSS class apos-slideshow-item--svg
is added
to the relevant item in the slideshow on the front end. And, the standard widgetBase.html
for this module works together with styles provided in always.less
to do something
reasonable, presenting the svg with background-size: contain
, which leverages the
fact that most SVGs play very nicely with your background.
If you have overridden widget.html
for apostrophe-images-widgets
, view recent commits
on widgetBase.html
to see how to implement this technique yourself.
# Methods
# addFieldType() [schemaField]
# fieldTypePartial(data) [schemaField]
# indexer(value, field, texts) [schemaField]
# acceptableExtension(field, attachment) [schemaField]
# accept(req, file, callback) [api]
For backwards compatibility. Equivalent to calling insert
with
the same three arguments.
# insert(req, file, options, callback) [api]
Insert a file as an Apostrophe attachment. The file
object
should be an object with name
and path
properties.
name
must be the name the user claims for the file, while path
must be the actual full path to the file on disk and need not have
any file extension necessarily.
Note that when using Express to handle file uploads, req.files['yourfieldname'] will be such an object as long as you configure jquery fileupload to submit one per request.
The options
argument may be omitted completely.
If options.permissions
is explicitly set to false
,
permissions are not checked.
callback
is invoked with (null, attachment)
where
attachment
is an attachment object, suitable
for passing to the url
API and for use as the value
of an type: 'attachment'
schema field.
If callback
is omitted completely, a promise is returned.
The promise resolves to an attachment object.
# getFileGroup(extension) [api]
# crop(req, _id, crop, callback) [api]
# sanitizeCrop(crop) [api]
# clone(req, source, callback) [api]
Clones a file
# getMissingAttachmentUrl() [api]
This method return a default icon url if an attachment is missing to avoid template errors
# url(attachment, options) [api]
This method is available as a template helper: apos.attachments.url
Given an attachment object,
return the URL. If options.size is set, return the URL for
that size (one-third, one-half, two-thirds, full). full is
"full width" (1140px), not the original. For the original,
pass original
. If size is not specified, you will receive
the full
size if an image, otherwise the original.
If the "uploadfsPath" option is true, an uploadfs path is returned instead of a URL.
# first(within, options) [api]
This method is available as a template helper: apos.attachments.first
Find the first attachment referenced within any object with attachments as possible properties or sub-properties.
For best performance be reasonably specific; don't pass an entire page or piece object if you can pass page.thumbnail to avoid an exhaustive search, especially if the page has many joins.
Returns the first attachment matching the criteria.
For ease of use, a null or undefined within
argument is accepted.
Examples:
- In the body please
apos.attachments.first(page.body)
- Must be a PDF
apos.attachments.first(page.body, { extension: 'pdf' })
- May be any office-oriented file type
apos.attachments.first(page.body, { group: 'office' })
apos.images.first is a convenience wrapper for fetching only images.
OPTIONS:
You may specify extension
, extensions
(an array of extensions)
or group
to filter the results.
# all(within, options) [api]
This method is available as a template helper: apos.attachments.all
Find all attachments referenced within an object, whether they are properties or sub-properties (via joins, etc).
For best performance be reasonably specific; don't pass an entire page or piece object if you can pass piece.thumbnail to avoid an exhaustive search, especially if the piece has many joins.
Returns an array of attachments, or an empty array if none are found.
When available, the _description
, _credit
, _creditUrl
, and '_title' are
also returned as part of the object.
For ease of use, a null or undefined within
argument is accepted.
Examples:
- In the body please
apos.attachments.all(page.body)
- Must be a PDF
apos.attachments.all(page.body, { extension: 'pdf' })
- May be any office-oriented file type
apos.attachments.all(page.body, { group: 'office' })
apos.images.all is a convenience wrapper for fetching only images.
OPTIONS:
You may specify extension
, extensions
(an array of extensions)
or group
to filter the results.
If options.annotate
is true, a ._urls
property is added to all
image attachments wherever they are found in within
, with
subproperties for each image size name, including original
.
For non-images, a ._url
property is set.
# each(criteria, limit, each, callback) [api]
Iterates over all of the attachments that exist, processing
up to limit
attachments at any given time.
If only 3 arguments are given the limit defaults to 1.
For use only in command line tasks, migrations and other batch operations in which permissions are a complete nonissue. NEVER use on the front end.
# hasFocalPoint(attachment) [api]
Returns true if, based on the provided attachment object,
a valid focal point has been specified. Useful to avoid
the default of background-position: center center
if
not desired.
# focalPointToBackgroundPosition(attachment) [api]
If a focal point is present on the attachment, convert it to
CSS syntax for background-position
. No trailing ;
is returned.
The coordinates are in percentage terms.
# getFocalPoint(attachment) [api]
Returns an object with x
and y
properties containing the
focal point chosen by the user, as percentages. If there is no
focal point, null is returned.
# isCroppable(attachment) [api]
Returns true if this type of attachment is croppable. Available as a template helper.
# isSized(attachment) [api]
Returns true if this type of attachment is sized, i.e. uploadfs produces versions of it for each configured size, as it does with GIF, JPEG and PNG files.
Accepts either an entire attachment object or an extension.
Can accept jpeg
or jpg
, because it is needed prior to the
imagemagick code that resolves that difference.
# resolveExtension(extension) [api]
Resolve a file extension such as jpeg to its canonical form (jpg). If no extension map is configured for this extension, return it as-is.
# addTypeMigration() [api]
# addDocReferencesMigration() [api]
# addRecomputeAllDocReferencesTask() [api]
# recomputeAllDocReferences(callback) [api]
Recompute the docIds
and trashDocIds
arrays
from scratch. Should only be needed by the
one-time migration that fixes these for older
databases, but can be run at any time via the
apostrophe-attachments:recompute-doc-references
task, just in case the need arises or your site
was affected by the very brief availability of 2.77.0
which effectively marked all attachments as
not in use.
# addFixPermissionsMigration() [api]
# addResetUploadfsPermissionsTask() [api]
# resetUploadfsPermissions(callback) [api]
# docAfterSave(req, doc, options, callback) [api]
# docAfterTrash(req, doc, callback) [api]
# docAfterRescue(req, doc, callback) [api]
# updateDocReferences(doc, callback) [api]
When the last doc that contains this attachment goes to the trash, its permissions should change to reflect that so it is no longer web-accessible to those who know the URL.
This method is invoked after any doc is inserted, updated, trashed or rescued.
# updatePermissions(callback) [api]
Update the permissions in uploadfs of all attachments
based on whether the documents containing them
are in the trash or not. Specifically, if an attachment
has been utilized at least once but no longer has
any entries in docIds
and trash
is not yet true,
it becomes web-inaccessible, utilized
is set to false
and trash
is set to true. Similarly, if an attachment
has entries in docIds
but trash
is true,
it becomes web-accessible and trash becomes false.
This method is invoked at the end of updateDocReferences
and also at the end of the migration that adds docIds
to legacy sites. You should not need to invoke it yourself.
# applyPermissions(attachment, trash, callback) [api]
Enable or disable access to the given attachment via uploadfs, based on whether
trash is true or false. If the attachment is an image, access
to the size indicated by the sizeAvailableInTrash
option
(usually one-sixth
) remains available. This operation is carried
out across all sizes and crops.
# migrateToDisabledFileKeyTask(argv, callback) [api]
# migrateFromDisabledFileKeyTask(argv, callback) [api]
# urlsTask(callback) [api]
# addFixOrientationsMigration() [api]
# pushAssets() [browser]
# pushCreateSingleton() [browser]
# initUploadfs(callback)
# apostropheDestroy(callback)
# enableCollection(callback)
# ensureIndexes(callback)
# enableHelpers()
# addPermissions()
# Nunjucks template helpers
# url(attachment, options)
This method is available as a template helper: apos.attachments.url
Given an attachment object,
return the URL. If options.size is set, return the URL for
that size (one-third, one-half, two-thirds, full). full is
"full width" (1140px), not the original. For the original,
pass original
. If size is not specified, you will receive
the full
size if an image, otherwise the original.
If the "uploadfsPath" option is true, an uploadfs path is returned instead of a URL.
# first(within, options)
This method is available as a template helper: apos.attachments.first
Find the first attachment referenced within any object with attachments as possible properties or sub-properties.
For best performance be reasonably specific; don't pass an entire page or piece object if you can pass page.thumbnail to avoid an exhaustive search, especially if the page has many joins.
Returns the first attachment matching the criteria.
For ease of use, a null or undefined within
argument is accepted.
Examples:
- In the body please
apos.attachments.first(page.body)
- Must be a PDF
apos.attachments.first(page.body, { extension: 'pdf' })
- May be any office-oriented file type
apos.attachments.first(page.body, { group: 'office' })
apos.images.first is a convenience wrapper for fetching only images.
OPTIONS:
You may specify extension
, extensions
(an array of extensions)
or group
to filter the results.
# all(within, options)
This method is available as a template helper: apos.attachments.all
Find all attachments referenced within an object, whether they are properties or sub-properties (via joins, etc).
For best performance be reasonably specific; don't pass an entire page or piece object if you can pass piece.thumbnail to avoid an exhaustive search, especially if the piece has many joins.
Returns an array of attachments, or an empty array if none are found.
When available, the _description
, _credit
, _creditUrl
, and '_title' are
also returned as part of the object.
For ease of use, a null or undefined within
argument is accepted.
Examples:
- In the body please
apos.attachments.all(page.body)
- Must be a PDF
apos.attachments.all(page.body, { extension: 'pdf' })
- May be any office-oriented file type
apos.attachments.all(page.body, { group: 'office' })
apos.images.all is a convenience wrapper for fetching only images.
OPTIONS:
You may specify extension
, extensions
(an array of extensions)
or group
to filter the results.
If options.annotate
is true, a ._urls
property is added to all
image attachments wherever they are found in within
, with
subproperties for each image size name, including original
.
For non-images, a ._url
property is set.
# hasFocalPoint(attachment)
Returns true if, based on the provided attachment object,
a valid focal point has been specified. Useful to avoid
the default of background-position: center center
if
not desired.
# getFocalPoint(attachment)
Returns an object with x
and y
properties containing the
focal point chosen by the user, as percentages. If there is no
focal point, null is returned.
# focalPointToBackgroundPosition(attachment)
If a focal point is present on the attachment, convert it to
CSS syntax for background-position
. No trailing ;
is returned.
The coordinates are in percentage terms.
# isCroppable(attachment)
Returns true if this type of attachment is croppable. Available as a template helper.