Auto-embed URLs from YouTube, Vimeo, Gists and more
to run in your site's root directory
View template source
create_file "app/processors/embed_processor", <<~RUBY
class EmbedProcessor < Perron::HtmlProcessor::Base
def process
@html.css("p").each do |paragraph|
text = paragraph.text
provider = PROVIDERS.find { it.constantize.matches?(text) } if text.present?
paragraph.replace(provider.constantize.embed(text, @html)) if provider
end
end
private
PROVIDERS = %w[
EmbedProcessor::Codepen
EmbedProcessor::Gist
EmbedProcessor::Loom
EmbedProcessor::Vimeo
EmbedProcessor::Youtube
]
end
RUBY
file "app/processors/embed_processor/codepen.rb" do
<<~"_"
class EmbedProcessor
class Codepen
def self.matches?(text)
text.match?(%r{https?://codepen\.io/})
end
def self.embed(text, html)
# extracts username/pen_id from URLs like `https://codepen.io/railsdesigner/pen/PwZJqqb`
username, id = text.match(%r{codepen\.io/([^/]+)/pen/([^\s?]+)}).captures
Nokogiri::XML::Node.new("iframe", html).tap do |iframe|
iframe["src"] = "https://codepen.io/#{username}/embed/#{id}?default-tab=result"
iframe["width"] = "100%"
iframe["height"] = "500"
iframe["allowfullscreen"] = "true"
end
end
end
end
_
end
file "app/processors/embed_processor/gist.rb" do
<<~"_"
class EmbedProcessor
class Gist
def self.matches?(text)
text.match?(%r{https?://gist\.github\.com/})
end
def self.embed(text, html)
url = text[%r{https?://gist\.github\.com/[^\s]+}, 0]
Nokogiri::XML::Node.new("script", html).tap do |script|
script["src"] = "#{url}.js"
end
end
end
end
_
end
file "app/processors/embed_processor/loom.rb" do
<<~"_"
class EmbedProcessor
class Loom
def self.matches?(text)
text.match?(%r{https?://(?:www\.)?loom\.com/share/})
end
def self.embed(text, html)
id = text[%r{loom\.com/share/([^\s?]+)}, 1]
Nokogiri::XML::Node.new("iframe", html).tap do |iframe|
iframe["src"] = "https://www.loom.com/embed/#{id}"
iframe["width"] = "100%"
iframe["height"] = "400"
iframe["allowfullscreen"] = "true"
iframe["frameborder"] = "0"
end
end
end
end
_
end
file "app/processors/embed_processor/vimeo.rb" do
<<~"_"
class EmbedProcessor
class Vimeo
def self.matches?(text)
text.match?(%r{https?://(?:www\.)?vimeo\.com/})
end
def self.embed(text, html)
id = text[%r{vimeo\.com/(\d+)}, 1]
Nokogiri::XML::Node.new("iframe", html).tap do |iframe|
iframe["src"] = "https://player.vimeo.com/video/#{id}"
iframe["width"] = "100%"
iframe["height"] = "400"
iframe["allowfullscreen"] = "true"
end
end
end
end
_
end
file "app/processors/embed_processor/youtube.rb" do
<<~"_"
class EmbedProcessor
class Youtube
def self.matches?(text)
text.match?(%r{https?://(?:www\.)?(?:youtube\.com/watch\?v=|youtu\.be/)})
end
def self.embed(text, html)
id = text[/(?:v=|youtu\.be\/)([^&?\s]+)/, 1]
Nokogiri::XML::Node.new("iframe", html).tap do |iframe|
iframe["src"] = "https://www.youtube.com/embed/#{id}"
iframe["width"] = "100%"
iframe["height"] = "400"
iframe["allowfullscreen"] = "true"
end
end
end
end
_
end
end
This processor automatically converts plain text URLs in paragraphs to embedded content. Simply paste a URL to a supported platform and it will be transformed into an interactive embed.
Example
When you write:
```markdown
Check out this video:
https://www.youtube.com/watch?v=dQw4w9WgXcQ
```
It automatically becomes an embedded YouTube player instead of plain text.
Supported platforms
- YouTube
- Vimeo
- GitHub Gist
- CodePen
- Loom
Adding your own providers
To add support for a new platform, create a new class in app/processors/embed_processor/ and add it to the PROVIDERS array in EmbedProcessor. Each provider needs a matches? method to detect URLs and an embed method to generate the iframe or script tag.
Usage
Add the processor to your pipeline and paste any supported URL on its own line. The processor will detect and transform it automatically.