Difference between revisions of "File Uploads"
(Created page with "SocialStack has a mechanism for uploading public or private files. When a file is uploaded, the upload endpoint will return a file ref of the new file.") |
|||
| Line 1: | Line 1: | ||
SocialStack has a mechanism for uploading public or private files. When a file is uploaded, the upload endpoint will return a [[file ref]] of the new file. | SocialStack has a mechanism for uploading public or private files. When a file is uploaded, the upload endpoint will return a [[File Refs|file ref]] for the new file, which is then typically the main way to refer to a particular file. | ||
By default, when uploading an image file, it will automatically be resized into a collection of different sizes for convenience. This works on modern image formats like webp too. | |||
If you need video to be handled as well, you can either install the Api/FFmpeg module and ffmpeg on the target servers (ffmpeg is installed by default on all SocialStack cloud servers), or perform remote transcoding with huddle servers. Transcoding video is a very heavy process but usually mandatory if a CDN is involved in your project due to the file size limits of a CDN, and also end users benefit by being able to skip through the video substantially faster. | |||
= Displaying a file uploader = | |||
Use type="file" for a file uploader. When the form is submitted, the value will be the [[File Refs|file ref]]: | |||
<syntaxhighlight lang="javascript"> | |||
import Input from 'UI/Input'; | |||
... | |||
<Input type="file" name="myFile" label="My File Uploader" /> | |||
</syntaxhighlight> | |||
This defaults to storing files in the public file store. If you want them to be private, add the isPrivate prop: | |||
<syntaxhighlight lang="javascript"> | |||
import Input from 'UI/Input'; | |||
... | |||
<Input type="file" name="myFile" label="My File Uploader" isPrivate /> | |||
</syntaxhighlight> | |||
= Making use of an uploaded file = | |||
== On the frontend == | |||
An uploaded file is represented as a [[File Refs|file ref]] on the frontend - see the [[File Refs|file ref wiki article]] on how to work with those on the frontend. | |||
== In the API == | |||
As an upload is a content type, you can subscribe to Upload related events to handle when a new file is uploaded. This is often not the easiest to work with though; more on that in a moment: | |||
<syntaxhighlight lang="csharp"> | |||
Events.Upload.AfterCreate.AddEventListener(async (Context context, Upload upload) => { | |||
if(upload == null) { | |||
return upload; | |||
} | |||
// Do something with upload here. | |||
return upload; | |||
}); | |||
// AfterUpdate, AfterDelete etc | |||
</syntaxhighlight> | |||
However, because this event runs whenever any file is uploaded, there's no context on why it was uploaded. This is fine if you're building something like a transcoder which just cares about file type, but not if you're making something that requires a specific file. Instead, it's recommended to make a custom endpoint which receives a ref for that situation. | |||
For example, the frontend may have a form like this: | |||
<syntaxhighlight lang="csharp"> | |||
<Form action="attendee/from-csv" submitLabel="Apply"> | |||
<Input type="file" label="Attendee CSV" name="csvRef" isPrivate/> | |||
</Form> | |||
</syntaxhighlight> | |||
When the file is uploaded and the form is submitted, a JSON payload containing field called csvRef will get posted to the endpoint, and the payload would look something like this: | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"csvRef": "private:42.csv?s=..." | |||
} | |||
</syntaxhighlight> | |||
From there, a C# asp.net controller method can capture the ref value: | |||
<syntaxhighlight lang="json"> | |||
[HttpPost("from-csv")] | |||
public async ValueTask FromCsv([FromBody] CsvRefPayload payload) | |||
{ | |||
var context = await Request.GetContext(); | |||
var csvRef = payload.csvRef; // the string | |||
// Do something fun with the csvRef here! (there's more on handling refs in the API in the file ref wiki). | |||
} | |||
... | |||
public class CsvRefPayload | |||
{ | |||
public string csvRef; | |||
} | |||
</syntaxhighlight> | |||
For information on using a ref in the API, see the [[File Refs|file ref wiki page]]. | |||
= Upload metadata = | |||
== On the frontend == | |||
File uploads are a content type (called Upload), meaning all the usual conveniences apply: you can list all uploads, use Loop on them and so on - provided the user has permission to do so. | |||
<syntaxhighlight lang="javascript"> | |||
<Loop over='upload'>{anUpload => <>{anUpload.originalName}</>}</Loop> | |||
// Or if you want an array of uploads: | |||
webRequest('upload/list').then(response => { | |||
// response.json.results | |||
}) | |||
</syntaxhighlight> | |||
== In the API == | |||
As with other content types, either use injection or Services.Get to access the UploadService. From there, you can List/ Update and so on the upload you're interested in. | |||
Revision as of 17:10, 17 January 2023
SocialStack has a mechanism for uploading public or private files. When a file is uploaded, the upload endpoint will return a file ref for the new file, which is then typically the main way to refer to a particular file.
By default, when uploading an image file, it will automatically be resized into a collection of different sizes for convenience. This works on modern image formats like webp too.
If you need video to be handled as well, you can either install the Api/FFmpeg module and ffmpeg on the target servers (ffmpeg is installed by default on all SocialStack cloud servers), or perform remote transcoding with huddle servers. Transcoding video is a very heavy process but usually mandatory if a CDN is involved in your project due to the file size limits of a CDN, and also end users benefit by being able to skip through the video substantially faster.
Displaying a file uploader
Use type="file" for a file uploader. When the form is submitted, the value will be the file ref:
import Input from 'UI/Input';
...
<Input type="file" name="myFile" label="My File Uploader" />
This defaults to storing files in the public file store. If you want them to be private, add the isPrivate prop:
import Input from 'UI/Input';
...
<Input type="file" name="myFile" label="My File Uploader" isPrivate />
Making use of an uploaded file
On the frontend
An uploaded file is represented as a file ref on the frontend - see the file ref wiki article on how to work with those on the frontend.
In the API
As an upload is a content type, you can subscribe to Upload related events to handle when a new file is uploaded. This is often not the easiest to work with though; more on that in a moment:
Events.Upload.AfterCreate.AddEventListener(async (Context context, Upload upload) => {
if(upload == null) {
return upload;
}
// Do something with upload here.
return upload;
});
// AfterUpdate, AfterDelete etc
However, because this event runs whenever any file is uploaded, there's no context on why it was uploaded. This is fine if you're building something like a transcoder which just cares about file type, but not if you're making something that requires a specific file. Instead, it's recommended to make a custom endpoint which receives a ref for that situation.
For example, the frontend may have a form like this:
<Form action="attendee/from-csv" submitLabel="Apply">
<Input type="file" label="Attendee CSV" name="csvRef" isPrivate/>
</Form>
When the file is uploaded and the form is submitted, a JSON payload containing field called csvRef will get posted to the endpoint, and the payload would look something like this:
{
"csvRef": "private:42.csv?s=..."
}
From there, a C# asp.net controller method can capture the ref value:
[HttpPost("from-csv")]
public async ValueTask FromCsv([FromBody] CsvRefPayload payload)
{
var context = await Request.GetContext();
var csvRef = payload.csvRef; // the string
// Do something fun with the csvRef here! (there's more on handling refs in the API in the file ref wiki).
}
...
public class CsvRefPayload
{
public string csvRef;
}
For information on using a ref in the API, see the file ref wiki page.
Upload metadata
On the frontend
File uploads are a content type (called Upload), meaning all the usual conveniences apply: you can list all uploads, use Loop on them and so on - provided the user has permission to do so.
<Loop over='upload'>{anUpload => <>{anUpload.originalName}</>}</Loop>
// Or if you want an array of uploads:
webRequest('upload/list').then(response => {
// response.json.results
})
In the API
As with other content types, either use injection or Services.Get to access the UploadService. From there, you can List/ Update and so on the upload you're interested in.