module Shrine::Plugins::DataUri

  1. lib/shrine/plugins/data_uri.rb

The data_uri plugin enables you to upload files as data URIs. This plugin is useful for example when using HTML5 Canvas.

plugin :data_uri

If your attachment is called “avatar”, this plugin will add #avatar_data_uri and #avatar_data_uri= methods to your model.

user.avatar #=> nil
user.avatar_data_uri = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA"
user.avatar #=> #<Shrine::UploadedFile>

user.avatar.mime_type         #=> "image/png"
user.avatar.size              #=> 43423

You can also use #data_uri= and #data_uri methods directly on the Shrine::Attacher (which the model methods just delegate to):

attacher.data_uri = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA"

If the data URI wasn't correctly parsed, an error message will be added to the attachment column. You can change the default error message:

plugin :data_uri, error_message: "data URI was invalid"
plugin :data_uri, error_message: ->(uri) { I18n.t("errors.data_uri_invalid") }

If you just want to parse the data URI and create an IO object from it, you can do that with Shrine.data_uri. If the data URI cannot be parsed, a Shrine::Plugins::DataUri::ParseError will be raised.

# or YourUploader.data_uri("...")
io = Shrine.data_uri("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA")
io.content_type #=> "image/png"
io.size         #=> 21

When the content type is ommited, text/plain is assumed. The parser also supports raw data URIs which aren't base64-encoded.

# or YourUploader.data_uri("...")
io = Shrine.data_uri("data:,raw%20content")
io.content_type #=> "text/plain"
io.size         #=> 11
io.read         #=> "raw content"

The created IO object won't convey any file extension (because it doesn't have a filename), but you can generate a filename based on the content type of the data URI:

require "mime/types"

plugin :data_uri, filename: ->(content_type) do
  extension = MIME::Types[content_type].first.preferred_extension
  "data_uri.#{extension}"
end

This plugin also adds a UploadedFile#data_uri method (and #base64), which returns a base64-encoded data URI of any UploadedFile:

uploaded_file.data_uri #=> "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA"
uploaded_file.base64   #=> "iVBORw0KGgoAAAANSUhEUgAAAAUA"

Methods

Public Class

  1. configure

Constants

BASE64_REGEXP = /;base64/  
CONTENT_SEPARATOR = /,/  
DATA_REGEXP = /data:/  
DEFAULT_CONTENT_TYPE = "text/plain"  
MEDIA_TYPE_REGEXP = /[-\w.+]+\/[-\w.+]+(;[-\w.+]+=[^;,]+)*/  

Public Class methods

configure (uploader, opts = {})
[show source]
# File lib/shrine/plugins/data_uri.rb, line 81
def self.configure(uploader, opts = {})
  uploader.opts[:data_uri_filename] = opts.fetch(:filename, uploader.opts[:data_uri_filename])
  uploader.opts[:data_uri_error_message] = opts.fetch(:error_message, uploader.opts[:data_uri_error_message])
end