Renaming/rearranging constants for clarity (#15911)
* Renaming/rearranging constants for clarity As I'm writing about the Unified Embed project and creating documentation for the upcoming Forem Fest, I realized that the naming convention created confusion. This commit is an effort to tidy up that confusion. * Normalizing implementation pattern
This commit is contained in:
parent
f886c758bd
commit
4a03b4aaa8
7 changed files with 103 additions and 88 deletions
|
|
@ -2,6 +2,7 @@ class GistTag < LiquidTagBase
|
|||
PARTIAL = "liquids/gist".freeze
|
||||
VALID_LINK_REGEXP =
|
||||
%r{\Ahttps://gist\.github\.com/([a-zA-Z0-9](-?[a-zA-Z0-9]){0,38})/([a-zA-Z0-9]){1,32}(/[a-zA-Z0-9]+)?\Z}
|
||||
REGISTRY_REGEXP = %r{https?://gist.github.com}
|
||||
|
||||
def initialize(_tag_name, link, _parse_context)
|
||||
super
|
||||
|
|
@ -61,4 +62,4 @@ end
|
|||
|
||||
Liquid::Template.register_tag("gist", GistTag)
|
||||
|
||||
UnifiedEmbed.register(GistTag, regexp: %r{https?://gist.github.com})
|
||||
UnifiedEmbed.register(GistTag, regexp: GistTag::REGISTRY_REGEXP)
|
||||
|
|
|
|||
|
|
@ -1,46 +1,10 @@
|
|||
# The purpose of this singleton class is to provide a registry for the
|
||||
# numerous "link/embedded" type liquid tags.
|
||||
#
|
||||
# Each of those liquid tags must self-register their lookup regular
|
||||
# expression.
|
||||
class UnifiedEmbed
|
||||
include Singleton
|
||||
|
||||
def self.current
|
||||
instance
|
||||
end
|
||||
|
||||
# @api public
|
||||
# A namespacing module to help organize the concepts of embedding.
|
||||
module UnifiedEmbed
|
||||
# A convenience method for registering tags as part of the
|
||||
# UnifiedEmbed ecosystem.
|
||||
#
|
||||
# @param klass [Class] the LiquidTag class that we use when we match
|
||||
# the given :regexp
|
||||
# @param regexp [Regexp] the regular expression that when matched
|
||||
# means we use the associated :klass
|
||||
def self.register(klass, regexp:)
|
||||
instance.register(klass, regexp: regexp)
|
||||
end
|
||||
|
||||
# @api public
|
||||
#
|
||||
# @param link [String] the string that includes the URI for the
|
||||
# embed and possibly additional attributes, depending on how
|
||||
# the registered liquid tag parses this string.
|
||||
# @return [Class] a descendant class of LiquidTagBase
|
||||
def self.find_liquid_tag_for(link:)
|
||||
instance.find_liquid_tag_for(link: link)
|
||||
end
|
||||
|
||||
def initialize
|
||||
@registry = []
|
||||
end
|
||||
|
||||
def register(klass, regexp:)
|
||||
@registry << [regexp, klass]
|
||||
end
|
||||
|
||||
def find_liquid_tag_for(link:)
|
||||
link = ActionController::Base.helpers.strip_tags(link).strip if link.include?("href=")
|
||||
_regexp, klass = @registry.detect { |regexp, _tag_class| regexp.match?(link) }
|
||||
klass
|
||||
# @see UnifiedEmbed::Registry
|
||||
def self.register(...)
|
||||
UnifiedEmbed::Registry.register(...)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
48
app/liquid_tags/unified_embed/registry.rb
Normal file
48
app/liquid_tags/unified_embed/registry.rb
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
module UnifiedEmbed
|
||||
# The purpose of this singleton class is to provide a registry for the
|
||||
# numerous "link/embedded" type liquid tags.
|
||||
#
|
||||
# Each of those liquid tags must self-register their lookup regular
|
||||
# expression.
|
||||
class Registry
|
||||
include Singleton
|
||||
|
||||
def self.current
|
||||
instance
|
||||
end
|
||||
|
||||
# @api public
|
||||
#
|
||||
# @param klass [Class] the LiquidTag class that we use when we match
|
||||
# the given :regexp
|
||||
# @param regexp [Regexp] the regular expression that when matched
|
||||
# means we use the associated :klass
|
||||
def self.register(klass, regexp:)
|
||||
instance.register(klass, regexp: regexp)
|
||||
end
|
||||
|
||||
# @api public
|
||||
#
|
||||
# @param link [String] the string that includes the URI for the
|
||||
# embed and possibly additional attributes, depending on how
|
||||
# the registered liquid tag parses this string.
|
||||
# @return [Class] a descendant class of LiquidTagBase
|
||||
def self.find_liquid_tag_for(link:)
|
||||
instance.find_liquid_tag_for(link: link)
|
||||
end
|
||||
|
||||
def initialize
|
||||
@registry = []
|
||||
end
|
||||
|
||||
def register(klass, regexp:)
|
||||
@registry << [regexp, klass]
|
||||
end
|
||||
|
||||
def find_liquid_tag_for(link:)
|
||||
link = ActionController::Base.helpers.strip_tags(link).strip if link.include?("href=")
|
||||
_regexp, klass = @registry.detect { |regexp, _tag_class| regexp.match?(link) }
|
||||
klass
|
||||
end
|
||||
end
|
||||
end
|
||||
44
app/liquid_tags/unified_embed/tag.rb
Normal file
44
app/liquid_tags/unified_embed/tag.rb
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
module UnifiedEmbed
|
||||
# This liquid tag is present to facilitate a unified user experience
|
||||
# for declaring that they want a URL to have "embedded" behavior.
|
||||
#
|
||||
# What do we mean by embedded behavior? A more contextually rich
|
||||
# rendering of the URL, instead of a simple "A-tag".
|
||||
#
|
||||
# @see https://github.com/forem/forem/issues/15099 for details on the
|
||||
# purpose of this class.
|
||||
class Tag < LiquidTagBase
|
||||
# You will not get a UnifiedEmbedTag instance, as we are instead
|
||||
# using this class as a lookup (e.g., Factory pattern?) for the
|
||||
# LiquidTagBase instance that is applicable for the given :link.
|
||||
#
|
||||
# @param tag_name [String] in the UI, this was liquid tag name
|
||||
# (e.g., `{% tag_name link %}`)
|
||||
# @param link [String] the URL and additional options for that
|
||||
# particular service.
|
||||
# @param parse_context [Liquid::ParseContext]
|
||||
#
|
||||
# @return [LiquidTagBase]
|
||||
def self.new(tag_name, link, parse_context)
|
||||
klass = UnifiedEmbed::Registry.find_liquid_tag_for(link: link)
|
||||
|
||||
if klass
|
||||
# Why the __send__? Because a LiquidTagBase class "privatizes"
|
||||
# the `.new` method. And we want to instantiate the specific
|
||||
# liquid tag for the given link.
|
||||
klass.__send__(:new, tag_name, link, parse_context)
|
||||
else
|
||||
# If we don't know how to handle the embed, let's just give the
|
||||
# user an A-tag.
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def render(_context)
|
||||
link, _options = strip_tags(@markup)
|
||||
%(<a href="#{link}">#{link}</a>)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("embed", UnifiedEmbed::Tag)
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
# This liquid tag is present to facilitate a unified user experience
|
||||
# for declaring that they want a URL to have "embedded" behavior.
|
||||
#
|
||||
# What do we mean by embedded behavior? A more contextually rich
|
||||
# rendering of the URL, instead of a simple "A-tag".
|
||||
#
|
||||
# @see https://github.com/forem/forem/issues/15099 for details on the
|
||||
# purpose of this class.
|
||||
class UnifiedEmbedTag < LiquidTagBase
|
||||
# You will not get a UnifiedEmbedTag instance, as we are instead
|
||||
# using this class as a lookup (e.g., Factory pattern?) for the
|
||||
# LiquidTagBase instance that is applicable for the given :link.
|
||||
#
|
||||
# @param tag_name [String] in the UI, this was liquid tag name
|
||||
# (e.g., `{% tag_name link %}`)
|
||||
# @param link [String] the URL and additional options for that
|
||||
# particular service.
|
||||
# @param parse_context [Liquid::ParseContext]
|
||||
#
|
||||
# @return [LiquidTagBase]
|
||||
def self.new(tag_name, link, parse_context)
|
||||
klass = UnifiedEmbed.find_liquid_tag_for(link: link)
|
||||
|
||||
if klass
|
||||
# Why the __send__? Because a LiquidTagBase class "privatizes"
|
||||
# the `.new` method. And we want to instantiate the specific
|
||||
# liquid tag for the given link.
|
||||
klass.__send__(:new, tag_name, link, parse_context)
|
||||
else
|
||||
# If we don't know how to handle the embed, let's just give the
|
||||
# user an A-tag.
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def render(_context)
|
||||
link, _options = strip_tags(@markup)
|
||||
%(<a href="#{link}">#{link}</a>)
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("embed", UnifiedEmbedTag)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe UnifiedEmbed do
|
||||
RSpec.describe UnifiedEmbed::Registry do
|
||||
subject(:unified_embed) { described_class }
|
||||
|
||||
let(:article) { create(:article) }
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe UnifiedEmbedTag, type: :liquid_tag do
|
||||
RSpec.describe UnifiedEmbed::Tag, type: :liquid_tag do
|
||||
it "delegates parsing to the link-matching class" do
|
||||
link = "https://gist.github.com/jeremyf/662585f5c4d22184a6ae133a71bf891a"
|
||||
|
||||
Loading…
Add table
Reference in a new issue