It's Easy to Build: Custom docs project | Part 3 - ERB templating
Hello there, welcome to part 3 of my series to build a custom docs project. Since I'm a kind of DRY person, you should see part 1 of this series to see the introduction and problem statement of this project. You can also find Part 2 of this series here(part 2 is optional).
In this tutorial, we'll learn about what ERB templating is and how we can inject the processed markdown code and inject it into the HTML file.
From our part 1 of series, we saw that our index.html
didn't have a valid HTML structure like <head>
, <body>
tags were not present. Also, we can't deploy this file to production as there are no Meta tags or SEO tags. We'll solve this issue in this tutorial.
Getting Started
What is ERB?
ERB stands for eRuby or Embedded RuBy and has a .erb
file extension.
It is a templating system that embeds Ruby into a text document. It is often used to embed Ruby code in an HTML document. -- Wikipedia
In other words, we can write ruby code in our files(text, HTML, among others), and this way, we can bring programming features(like variables, loops, etc.) in our regular files.
All the ruby code in ERB files are in this format: <%= "Hello" %>
, i.e. between the <%= %>
. The =
sign shows that you want to evaluate code + SHOW this as output. If you use <% "Hello" %>
, this will evaluate the code but doesn't show anything as output. We use <% %>
for looping or flow control. See below for an example.
Why is this useful?
You can add ruby code dynamically to the files. I can explain it better in a form of an example. Say you want to write <p>
tag with I'm just a P tag
5 times. In normal HTML you would do something like this:
<!-- index.html -->
<div class="container">
<p>I'm just a P tag</p>
<p>I'm just a P tag</p>
<p>I'm just a P tag</p>
<p>I'm just a P tag</p>
<p>I'm just a P tag</p>
</div>
But with ERB, you can use the DRY principle for the above.
<!-- index.html.erb -->
<div class="container">
<% 5.times do %>
<%= "<p>I'm just a P tag</p>" %>
<% end %>
</div>
The above code will do the same, but it respects the DRY principle. Also, see the difference between <% %>
and <%= %>
.
Revision
In part 1 of the series, we only did 1 task: Convert our markdown to HTML, then inject this HTML to index.html
. It looked something like this:
So like I said, we can't deploy this to production. So let's make it fancier.
Codebase
Let's start writing the code:
-
Create a new file named
template.html.erb
:$ touch template.html.erb
-
The
template.html.erb
file will be like our template, we'll add all our static content here + variables for dynamic content:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Docs Project</title> <!-- Other Meta tags --> </head> <body> <div class="container"> <%= body_content %> </div> </body> </html>
-
In the above code, everything is like regular HTML, but we also injected a
<%= body_content %>
ERB code. This is where we'll insert all our HTML code generated from our markdown. -
From part 1, we have this in our
config.rb
file:require 'redcarpet' hello_md_text_file = File.open('./hello.md', 'r') index_html_file = File.open('./index.html', 'w+') md_renderer_options = {} md_extensions = {} md_renderer = Redcarpet::Render::HTML.new(md_renderer_options) markdown = Redcarpet::Markdown.new(md_renderer, md_extensions) md_text = hello_md_text_file.read md_to_html_text = markdown.render(md_text) index_html_file.puts md_to_html_text hello_md_text_file.close index_html_file.close
- In short, what above code does it, It reads the Markdown file, converts that markdown to HTML, then injects this HTML in
index.html
file.
- In short, what above code does it, It reads the Markdown file, converts that markdown to HTML, then injects this HTML in
-
Now, let's modify our
config.rb
file, see the comments:require 'redcarpet' hello_md_text_file = File.open('./hello.md', 'r') index_html_file = File.open('./index.html', 'w+') ## Import the template file ## We only give it READ permission template_file = File.open('./template.html.erb', 'r') md_renderer = Redcarpet::Render::HTML.new(md_renderer_options) markdown = Redcarpet::Markdown.new(md_renderer, md_extensions) md_text = hello_md_text_file.read md_to_html_text = markdown.render(md_text) ## Now let's read the contents of template file template_content = template_file.read ## This variable will be injected body_content = md_to_html_text ## Create a new instance of ERB with the template_content erb_renderer = ERB.new(template_content) ## Now, parse the ERB template, and replace ## body_content with the HTML generated code final_html_output = erb_renderer.result() ## Finally, inject all the HTML code in `index.html` file index_html_file.puts final_html_output ## Close all files hello_md_text_file.close index_html_file.close template_file.close
- The above code is simple; everything is explained in the code comments above, and to summarize:
- First, we import and read our template file and save it in our variable
template_content
- We then Initialize a new instance of ERB with the
template_content
- Then we parse this ERB instance. This part will replace all our variables in
template.html.erb
with appropriate content. - We save all the above parsing in
final_html_output
variable. - Then finally, we inject
final_html_output
content into ourindex.html
file.
-
Running the script:
- Run the script by using this command:
$ ruby config.rb
- Now, in the
index.html
file, you'll see all your template + markdown to HTML converted code.
- Run the script by using this command:
-
You can now upload this generated
index.html
file to production. This will have valid HTML structure, Meta tags and SEO tags that you mention intemplate.html.erb
file.
Summary and conclusion
Let's take a quick look at what we learned today:
- First of all, I introduced myself, so don't forget to connect with me on Twitter or elsewhere.
- Since I'm a DRY person, I referred to my part 1 article where you can see the introduction and problem statement.
- Then we got the introduction to ERB and how it's templating works with a cute example.
- We then created our template file with a variable that makes it dynamic.
- We then wrote our ruby code logic to solve our problem, i.e., replace the variable dynamically to inject our converted HTML code. Then place this HTML to our
index.html
file. - Finally, we took a quick look at this very summary...
That's it and let there be the end. 🙏