diff --git a/app/liquid_tags/soundcloud_tag.rb b/app/liquid_tags/soundcloud_tag.rb
new file mode 100644
index 000000000..ce37bac5b
--- /dev/null
+++ b/app/liquid_tags/soundcloud_tag.rb
@@ -0,0 +1,46 @@
+class SoundcloudTag < LiquidTagBase
+ def initialize(tag_name, link, tokens)
+ super
+ @link = parse_link(link)
+ @height = 166
+ end
+
+ def render(_context)
+ # src = build_src
+ html = <<-HTML
+
+ HTML
+ finalize_html(html)
+ end
+
+ private
+
+ def parse_link(link)
+ stripped_link = sanitize_link(link)
+ raise_error unless valid_link?(stripped_link)
+ stripped_link
+ end
+
+ def sanitize_link(link)
+ link = ActionController::Base.helpers.strip_tags(link)
+ link = ActionController::Base.helpers.sanitize(link)
+ link.tr(" ", "")
+ end
+
+ def valid_link?(link)
+ link.include?("soundcloud.com")
+ end
+
+ def raise_error
+ raise StandardError, "Invalid Soundcloud URL"
+ end
+end
+
+Liquid::Template.register_tag("soundcloud", SoundcloudTag)
diff --git a/app/views/pages/_editor_guide_text.html.erb b/app/views/pages/_editor_guide_text.html.erb
index 2be5abbc6..4598b01ac 100644
--- a/app/views/pages/_editor_guide_text.html.erb
+++ b/app/views/pages/_editor_guide_text.html.erb
@@ -144,6 +144,10 @@
{% speakerdeck 7e9f8c0fa0c949bd8025457181913fd0 %}
+
Soundcloud Embed
+ Just enter the full URL of the Soundcloud track you are trying to embed.
+ {% soundcloud https://soundcloud.com/user-261265215/dev-to-review-episode-1 %}
+
Parsing Liquid Tags as a Code Example
To parse Liquid tags as code, simply wrap it with a single backtick or triple backticks.
`{% mytag %}{{ site.SOMETHING }}{% endmytag %}`
diff --git a/spec/liquid_tags/soundcloud_tag_spec.rb b/spec/liquid_tags/soundcloud_tag_spec.rb
new file mode 100644
index 000000000..8ed5a8816
--- /dev/null
+++ b/spec/liquid_tags/soundcloud_tag_spec.rb
@@ -0,0 +1,43 @@
+require "rails_helper"
+require "nokogiri"
+
+RSpec.describe SoundcloudTag, type: :liquid_template do
+ describe "#link" do
+ let(:soundcloud_link) { "https://soundcloud.com/user-261265215/dev-to-review-episode-2" }
+ let(:evil_string) { "" }
+ let(:url_segment) { "https://w.soundcloud.com/player/?url" }
+
+ def generate_new_liquid(link)
+ Liquid::Template.register_tag("soundcloud", SoundcloudTag)
+ Liquid::Template.parse("{% soundcloud #{link} %}")
+ end
+
+ def extract_iframe_src(rendered_iframe)
+ parsed_iframe = Nokogiri.HTML(rendered_iframe)
+ iframe_src = parsed_iframe.xpath("//iframe/@src")
+ CGI::parse(iframe_src[0].value)
+ end
+
+ it "accepts soundcloud link" do
+ liquid = generate_new_liquid(soundcloud_link)
+ rendered_soundcloud_iframe = liquid.render
+ Approvals.verify(rendered_soundcloud_iframe, name: "soundcloud_liquid_tag", format: :html)
+ end
+
+ it "rejects invalid soundcloud link" do
+ expect do
+ generate_new_liquid("invalid_soundcloud_link")
+ end.to raise_error(StandardError)
+ end
+
+ it "strips script input" do
+ allow(ActionController::Base.helpers).to receive(:strip_tags).and_return(evil_string)
+
+ liquid = generate_new_liquid(evil_string)
+ rendered_soundcloud_iframe = liquid.render
+ iframe_src = extract_iframe_src(rendered_soundcloud_iframe)
+
+ expect(iframe_src[url_segment]).not_to include("