GitPitch Tags for Dev.to
I have been revisiting my previous DEV posts to update content and build a consistent format between each post. Through that process -and as I developed additional ideas for what I want to achieve with my DEV journal- I began to see the need for something to help accomplish two objectives...
- I wanted an extremely simple method to update a single post with more content, preferably through Github.
- I wanted a method to embed a slideshow in a post, but something with fewer steps than using SlideShare or Speakerdeck.
After some quick research, I landed on GitPitch as the perfect option. With a GITPITCH.md markdown file in a GitHub repo, a presentation is instantly available through a GitPitch URL!
Check out this example from GitPitch!
Fortunately, DEV.to had Liquid tags for SlideShare and Speakerdeck but not GitPitch. I thought it was a perfect time and task for my first open source contribution. Given my existing knowledge of Ruby and ERB, it was simple enough to get a grasp of the process without getting tied up with researching the work itself.
I submitted a pull request to DEV.to explaining what I was hoping to achieve. With the approval, DEV.to provided a document to guide the creation of a Liquid tag. I hadn't come across any need for Liquid before and I was happy to learn a little about it through the process. I was on my way once I forked and cloned the DEV.to platform to run locally on my machine while I built the tag.
Let's get started!
I created an RSpec file to keep myself on the right track and meet the pull request requirements.
############################################################################################################# | |
#### Pushed a test file for link validation, tag generation, and embed creation. ############################ | |
############################################################################################################# | |
require "rails_helper" | |
RSpec.describe GitPitchTag, type: :liquid_tag do | |
describe "#link" do | |
let(:valid_links) do | |
[ | |
"https://gitpitch.com/gitpitch/in-60-seconds", | |
"https://gitpitch.com/gitpitch/what-is-gitpitch", | |
"https://gitpitch.com/gitpitch/demo-deck", | |
] | |
end | |
let(:bad_links) do | |
[ | |
"//pastebin.com/raw/b77FrXUA#gist.github.com", | |
"https://gitpitch.com/gitpitch/github.com@evil.com", | |
"https://gitpitch.github.com.evil.com", | |
"https://github.com/string/string/raw/string/file", | |
] | |
end | |
def generate_tag(link) | |
Liquid::Template.register_tag("gitpitch", GitPitchTag) | |
Liquid::Template.parse("{% gitpitch #{link} %}") | |
end | |
def generate_script(link) | |
html = <<~HTML | |
<iframe height="450" src="#{link}" loading="lazy"></iframe> | |
HTML | |
html.tr("\n", " ").delete(" ") | |
end | |
it "rejects invalid gitpitch url" do | |
expect do | |
generate_new_liquid("really_long_invalid_link") | |
end.to raise_error(StandardError) | |
end | |
it "accepts valid gitpitch url" do | |
valid_links.each do |link| | |
liquid = generate_tag(link) | |
expect(liquid.render.tr("\n", " ").delete(" ")).to eq(generate_script(link)) | |
end | |
end | |
end | |
end |
Next I built the tag methods. I used other Liquid tag source code for a little direction, but still found opportunities to write new code and refactor things down to a reasonable minimum.
class GitPitchTag < LiquidTagBase | |
############################################################################################################# | |
#### Defined the partial location for the embed and regex expression for link validation #################### | |
############################################################################################################# | |
PARTIAL = "liquids/gitpitch".freeze | |
URL_REGEXP = /(http|https):\/\/gitpitch.com\/[a-zA-Z0-9\-\/]*/.freeze | |
############################################################################################################# | |
#### Created an initializer for the link and a render method for the embed ################################## | |
############################################################################################################# | |
def initialize(tag_name, link, tokens) | |
super | |
@link = parse_link(link) | |
end | |
def render(_context) | |
ActionController::Base.new.render_to_string( | |
partial: PARTIAL, | |
locals: { | |
link: @link | |
}, | |
) | |
end | |
private | |
############################################################################################################# | |
#### Created private parsing, validation, and error methods ################################################# | |
############################################################################################################# | |
def parse_link(link) | |
stripped_link = ActionController::Base.helpers.strip_tags(link) | |
the_link = stripped_link.split(" ").first | |
raise_error unless valid_link?(the_link) | |
the_link | |
end | |
def valid_link?(link) | |
link_no_space = link.delete(" ") | |
(link_no_space =~ URL_REGEXP)&.zero? | |
end | |
def raise_error | |
raise StandardError, "Invalid GitPitch URL" | |
end | |
end | |
Liquid::Template.register_tag("gitpitch", GitPitchTag) |
I included a partial file to a simple iframe embed of a gitpitch tag. I looked at other partials to determine a reasonably consistent height for the iframe. Checkout the example below from GitPitch!
<% ########################################################################################################## | |
#### Pushed a simple iframe partial for the embed. ########################################################## | |
###########################################################################################################%> | |
<iframe | |
height="450" | |
src="<%= link %>" | |
loading="lazy"> | |
</iframe> |
My last step was an extremely brief addition to the DEV Community Editor Guide! Peak inside the Gist below for usage instructions for the tag or the Editor Guide itself.
<div class="container article" id="editor-help-guide"> | |
<div class="title help-guide-title"> | |
<h1>Editor Guide 🤓</h1> | |
</div> | |
<%# ... %> | |
<% ########################################################################################################## | |
#### Pushed a very brief addition to the Dev Community Editor guide to accompany the feature. ############### | |
###########################################################################################################%> | |
<h3><strong>GitPitch Embed</strong></h3> | |
<p>All you need is the GitPitch link:</p> | |
<code> | |
{% gitpitch https://gitpitch.com/gitpitch/in-60-seconds %} | |
</code> | |
<%# ... %> | |
</div> | |
</div> |
It was a lot of fun to contribute and I can't wait to start using the GitPitch tag! I realize now this fits pretty squarely within how I found software engineering- with a "need it? make it!" mentality.
Top comments (0)