Open oyeanuj opened 8 years ago
Hey @oyeanuj! Thanks for interest in using oembed gem 😄
The gem is build with the idea of having very lightweight solution for making oEmbed clients. This gives freedom and flexibility. As you see there're no predefined/hardcoded providers or request parameters. That's the idea - the gem lets you define rules and just helps with everything related to oEmbed protocol.
That said there could be many possible solutions for your specific case. I will show you just one of them, but it's totally up to which one to choose.
require 'oembed'
class Provider
attr_reader :endpoint_uri
def initialize(endpoint_uri, resource_pattern)
@endpoint_uri = endpoint_uri
@resource_pattern = resource_pattern
end
# Returns True if a given resource URL matches to the pattern defined for
# the provider, or False otherwise.
def match?(resource_uri)
!resource_pattern.match(resource_uri).nil?
end
end
class MultiproviderClient
include Oembed::Client
attr_reader :endpoint_uri
# Adds new providers at runtime.
#
# provider - a provider that must be registered on the client.
# See Provider class for more details.
#
# Returns an Array of registered providers.
def register_provider(provider)
@providers << provider
end
# Overwritten interface of Oembed::Client. Every time a resource is fetched
# a client is looking for a suitable provider.
#
# The method could be improved for cases when no provider is found.
def fetch!(resource_uri, params = {})
@endpoint_uri = endpoint_uri_for(resource_uri)
super(resource_uri, params = {})
end
private
def providers
@providers ||= []
end
def endpoint_uri_for(resource_uri)
providers.find { |provider| provider.match?(resource_uri) }
end
end
# Example
client = MultiproviderClient.new
# Endpoint URL and patterns could be also loaded from configration file,
# database, or remote API.
providers = [
Provider.new('https://www.youtube.com/oembed', /^.*youtube.com.*$/),
Provider.new('http://api.instagram.com/oembed', /^.*instagr.*$/),
Provider.new('http://www.flickr.com/services/oembed.xml', /^.*flickr.com.*$/)
]
providers.each { |provider| client.register_provider(provider) }
client.fetch('http://www.flickr.com/photos/alex_soulim/3593916989')
# => oEmbed data for the Flickr resource
client.fetch('http://instagr.am/p/BUG/', maxwidth: 300)
# => oEmbed data for the Instagram resource
Note: I didn't have time to play with the code above, so some minor tweaks might be required. I just wanted to demonstrate you a possible solution.
Hi @soulim! Thanks for the library, it looks great!
I had a question pertaining to my use-case which I couldn't find doc or example for. If I am looking to builder a oEmbed client that can fetch oEmbed for multiple providers, do I have to create separate classes with their
endpoint_url
methods? Or is there a way to pass multiple providers and have the library use that to fetch oembed data?Thank you for open-sourcing this!