PhlexML

Build content pages with Phlex

I’ve been playing around with an idea I’m calling “PhlexML” in Rails and Sitepress where I can build content pages in Phlex that look like this:

PageView(
  title: "This is a page"
){
  h1 { @title }
  erb <<~ERB
    <p>
      Why would somebody want to put
      ERB in their Phlex view? Nobody knows
    </p>
  ERB
  div(class: "prose prose-md"){
    markdown <<~MD
      * This
      * could
      * be
      * cool
    MD
  }
}

This is perfectly valid Ruby code inspired by Phlex kits. It might look like a lot, so let’s take a closer look at how this view works.

Frontmatter as the initializer

Frontmatter is a way to add metadata to a page made popular by Jekyll. When you create a markdown file, it might look like this:

---
title: This is a page
layout: page
---

* This
* could
* be
* cool

Phlex wouldn’t need that since you invoke the layout by its constant function and pass the data into the page view via the initializer.

PageView(
  title: "This is a page"
)

Mix content blocks & components

Next is the content. I chose a crazier example that mixes different template types to better illustrate the point.

# This is Phlex
h1 { @title }

# Passes the string into the `erb` method to process.
erb <<~ERB
  <p>
    Why would somebody want to put
    ERB in their Phlex view? Nobody knows
  </p>
ERB

# Phlex div block
div(class: "prose prose-md"){
  # Pass markdown into the `markdown` method to process.
  markdown <<~MD
    * This
    * could
    * be
    * cool
  MD
}

Throwing Erb in there might be overkill, but maybe not if prototyping and you want to see what a copy and pasted snippet of HTML looks like on a page before converting it to Phlex.

Markdown is actually quite useful for prose blocks in a page.

Rails integration

I created a proof-of-concept gist on Github Rails integration that works, but I didn’t spend a lot of time making sure it’s compatible with Phlex 2.x or look at edge cases.

But why!?

I’ve found when I want to build landing pages for websites, I’m most productive when I can drop Phlex components into views and mix in blocks of markdown for prose.

LandingPageView(
  title: "Phlex on Rails"
){
  Hero {
    it.title { "Create beautiful UIs in Rails with Phlex" }
    it.content {
      markdown <<~MD
        You'll learn:

        * Tame Erb, Haml, and Slim views in existing Rails apps with Phlex components
        * Learn how to use only Phlex components to build Rails apps without Erb
        * Understand how components clean up architecture, improve reusability, simplify testing, and increase velocity
        * Watch videos as soon as they're recorded and published
        * Access to all course videos, source code, and text when it's finished
        * Lifetime access to updates and new content
      MD

      Button(href: "/phlex#invest") { "Pre-order"}
    }
  }

  Section {
    HStack {
      it.title { "Meet your instructor"}
      image_tag "brad.jpg"
    }
  }
}

It becomes much easier to build pages with blocks of content that lean heavily on components while mixing less structured content, like blocks of Markdown.

Limitations

The biggest limitation of this approach is the views can’t be inherited from other views since there’s no class declaration in PhlexML. I don’t think that’s much of a limitation though since it would be easy to move the view into a class and extract out the bits that are common across multiple pages.

Do you want to learn Phlex 💪 and enjoy these code examples?

Support Beautiful Ruby by pre-ordering the Phlex on Rails video course.

Order the Phlex on Rails video course for $379 $289