Introduction
This video introduces Sitepress, a file-based content management system for Ruby that lets you manage content as files in your application.
What is Sitepress?
It’s a site generator for blogs, marketing pages, support content, or any content. Content lives as files that’s tracked by git, which makes it easier to manage content between environments, generate content with LLMs, and gives developers full control over integrating content it various parts of the website.
Embed in Rails
I created Sitepress because I was frustrated at how difficult it was to embed static site generatrors inside of Rails like Jekyll & Middleman.
Run stand-alone
Sitepress doesn’t only run in Rails. It can also be run stand-alone as its own web server or it can compile out static web pages that can be uploaded to a web server or S3-compatibile object store.
Sitepress is used in production
I’ve deployed Sitepress to production at Fly.io, Poll Everywhere, this website, TerminalWire, and more.
It’s served up billions and billions of pages for marketing sites, blogs, community docs websites, support content, and more.
Features
Sitepress has all the features you’d expect from any other site generator.
Frontmatter
Add metadata to the top of your content pages so it’s all in one place, like this page:
---
title: Introduction
order: 1
layout: video
status: unlocked
video:
key: sitepress/overview/introduction
---
This video introduces Sitepress, a file-based content management system for Ruby that lets you manage content as files in your application.
Then access that data from layouts & templates.
Query content
Want to list out all the video pages and their subpages to build a menu in a Sitepress site?
Automate it like this.
<nav class="flex flex-col gap-2">
<h3 class="font-semibold">Videos</h3>
<ul>
<% Sitepress.site.glob("vidoes/*.html.*").each do %>
<li>
<%= link_to_page it %>
<% if it.children.any? %>
<ul>
<% it.children.each do %>
<li><%= link_to_page it %></li>
<% end %>
</ul>
<% end %>
</li>
<% end %>
</ul>
</nav>
This loops through all the HTML pages in a videos directory and renders a link to each page. If there’s subpages, those get picked up too. If you add a new video, the navigation picks it up and it’s always up to date.
Sitepress makes it possible to programmatically glob and traverse content in a site.
Page models
Encapsulate pages behind models to make them easier to work with.
<h3 class="font-semibold">Videos</h3>
<ul>
<% VideoPage.all.each do %>
<video
src="<%= it.video.url %>"
width="<%= it.video.width %>"
height="<%= it.video.height %>"
controls
></video>
<% if it.video.premium? %>
<p>Unlock this video to see more details.</p>
<% end %>
<% end %>
</ul>
Page models are Plain ‘ol Ruby objects that encapsulate page data and provide methods for accessing and manipulating that data.
Templating & components
Sitepress uses Rails rendering, which means you can use Rails’ built-in templating system to render your pages. This allows you to use all the features of Rails’ templating system, such as partials, layouts, and helpers.
<%= render_layout "application" do %>
<main>
<%= yield %>
</main>
<hr>
<h3 class="font-semibold">Videos</h3>
<div class="grid grid-cols-3">
<% VideoPage.all.each do %>
<%= render partial: "video_player", locals: { video: it.video } %>
<% end %>
</div>
<% end %>
You can also use it to render components with Phlex or ViewComponent.
<div class="grid grid-cols-3">
<% VideoPage.all.each do
render VideoPlayer.new(video: it.video)
end %>
</div>
Custom markdown
Markdown should be easy to customize for applications, and it is with Sitepress! Here’s an example of what it looks like to inject an affiliate link into markdown content.
# ./app/markdown/application_markdown.rb
class ApplicationMarkdown < MarkdownRails::Renderer::Rails
# Code
AMAZON_STORE_ID = "rocketship083-20"
# This is called when a link is encountered in the markdown content
def link(link, title, content)
# The URI is wrapped in a builder, which makes modifications easier.
url = URI.build(link)
case url.uri.host
when "www.amazon.com"
url.query tag: AMAZON_STORE_ID
end
# HTML is rendered and emitted back into the HTML buffer.
content_tag :a, href: url.to_s, title: do
content
end
end
end
What can you do with it?
Sitepress is a toolkit for building file-based content management systems in Ruby.
