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") }

File extension

A data URI doesn't convey any information about the file extension, so when attaching from a data URI, the uploaded file location will be missing an extension. If you want the upload location to always have an extension, you can load the infer_extension plugin to infer it from the MIME type.

plugin :infer_extension


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         # decoded content

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         #=> "raw content"

You can also assign a filename:

io = Shrine.data_uri("data:,content", filename: "foo.txt")
io.original_filename #=> "foo.txt"

UploadedFile#data_uri and UploadedFile#base64

This plugin also adds UploadedFile#data_uri method, which returns a base64-encoded data URI of the file content, and UploadedFile#base64, which simply returns the file content base64-encoded.

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


Public Class

  1. configure


BASE64_REGEXP = /;base64/  
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 93
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])

  Shrine.deprecation("The :filename option is deprecated for the data_uri plugin, and will be removed in Shrine 3. Use the infer_extension plugin instead.") if opts[:filename]