Shrine has a lot of plugins built-in, but you can also easily create your own. Simply put, a plugin is a module:
module MyPlugin
# ...
end
Shrine.plugin MyPluginIf you would like to load plugins with a symbol, like you already load plugins
that ship with Shrine, you need to put the plugin in
shrine/plugins/my_plugin.rb in the load path, and register it:
# shrine/plugins/my_plugin.rb
class Shrine
module Plugins
module MyPlugin
# ...
end
register_plugin(:my_plugin, MyPlugin)
end
endShrine.plugin :my_pluginThe way to make plugins actually extend Shrine's core classes is by defining special modules inside the plugin. Here's a list of all "special" modules:
InstanceMethods # gets included into `Shrine`
ClassMethods # gets extended into `Shrine`
AttachmentMethods # gets included into `Shrine::Attachment`
AttachmentClassMethods # gets extended into `Shrine::Attachment`
AttacherMethods # gets included into `Shrine::Attacher`
AttacherClassMethods # gets extended into `Shrine::Attacher`
FileMethods # gets included into `Shrine::UploadedFile`
FileClassMethods # gets extended into `Shrine::UploadedFile`For example, this is how you would make your plugin add some logging to uploading:
module MyPlugin
module InstanceMethods
def upload(io, context)
time = Time.now
result = super
duration = Time.now - time
puts "Upload duration: #{duration}s"
end
end
endNotice that we can call super to get the original behaviour. In addition to
these modules, you can also make your plugin configurable:
Shrine.plugin :my_plugin, foo: "bar"You can do this by adding a .configure method to your plugin, which will be
given any passed in arguments or blocks. Typically you'll want to save these
options into Shrine's opts, so that you can access them inside of Shrine's
methods.
module MyPlugin
def self.configure(uploader, options = {})
uploader # The uploader class which called `.plugin`
uploader.opts[:my_plugin_options] = options
end
module InstanceMethods
def foo
opts[:my_plugin_options] #=> {foo: "bar"}
end
end
endIf your plugin depends on other plugins, you can load them inside of
.load_dependencies (which is given the same arguments as .configure):
module MyPlugin
def self.load_dependencies(uploader, *)
uploader.plugin :versions # depends on the versions plugin
end
end