Add video plugin
parent
3efd0d7d29
commit
7c2d7831d8
@ -0,0 +1,93 @@
|
||||
# Liquid tag for embedding video.js players from assets, mirroring how images
|
||||
# are embedded via plain relative paths (see _includes/head.html's <base> tag).
|
||||
#
|
||||
# Syntax:
|
||||
# {% video urls [class names] [width height] [preload:auto|metadata|none] %}
|
||||
#
|
||||
# `urls` is a comma-separated list of one or more relative asset paths, used
|
||||
# as <source> elements (multiple formats/resolutions). Everything after that
|
||||
# is free-form, order-independent tokens classified by shape:
|
||||
# - preload:auto|metadata|none -> preload attribute
|
||||
# - a bare integer -> width, then height
|
||||
# - anything else -> appended to the CSS class list
|
||||
#
|
||||
# The rendered markup is a plain HTML5 <video controls> element with
|
||||
# class="video-js" and data-setup='{}', which is exactly what video.js
|
||||
# progressively enhances if/when its script loads (see head.html). If it
|
||||
# never loads, the element is already a fully working native player.
|
||||
require 'cgi'
|
||||
|
||||
module Jekyll
|
||||
class VideoTag < Liquid::Tag
|
||||
PRELOAD_TOKEN = /\Apreload:(auto|metadata|none)\z/
|
||||
INTEGER_TOKEN = /\A\d+\z/
|
||||
|
||||
MIME_TYPES = {
|
||||
'.mp4' => 'video/mp4',
|
||||
'.m4v' => 'video/mp4',
|
||||
'.webm' => 'video/webm',
|
||||
'.ogv' => 'video/ogg',
|
||||
}.freeze
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
args = markup.strip.split(/\s+/)
|
||||
|
||||
urls_arg = args.shift
|
||||
if urls_arg.nil? || urls_arg.empty?
|
||||
raise Liquid::SyntaxError, "Syntax error in tag 'video' - valid syntax: {% video urls [class names] [width height] [preload:auto|metadata|none] %}"
|
||||
end
|
||||
@urls = urls_arg.split(',').map(&:strip).reject(&:empty?)
|
||||
|
||||
@classes = []
|
||||
@width = nil
|
||||
@height = nil
|
||||
@preload = nil
|
||||
|
||||
args.each do |token|
|
||||
case token
|
||||
when PRELOAD_TOKEN
|
||||
@preload = Regexp.last_match(1)
|
||||
when INTEGER_TOKEN
|
||||
if @width.nil?
|
||||
@width = token
|
||||
else
|
||||
@height = token
|
||||
end
|
||||
else
|
||||
@classes << token
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render(_context)
|
||||
classes = (['video-js'] + @classes).join(' ')
|
||||
|
||||
attrs = [%(class="#{escape(classes)}")]
|
||||
attrs << 'controls'
|
||||
attrs << %(width="#{escape(@width)}") if @width
|
||||
attrs << %(height="#{escape(@height)}") if @height
|
||||
attrs << %(preload="#{escape(@preload)}") if @preload
|
||||
attrs << %(data-setup='{}')
|
||||
|
||||
sources = @urls.map do |url|
|
||||
%( <source src="#{escape(url)}" type="#{mime_type_for(url)}">)
|
||||
end.join("\n")
|
||||
|
||||
"<video #{attrs.join(' ')}>\n#{sources}\n</video>"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mime_type_for(url)
|
||||
ext = File.extname(url).downcase
|
||||
MIME_TYPES.fetch(ext, 'video/mp4')
|
||||
end
|
||||
|
||||
def escape(value)
|
||||
CGI.escapeHTML(value.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('video', Jekyll::VideoTag)
|
||||
Loading…
Reference in New Issue