Phlex Turbo Layouts

Turbo Layouts in Phlex

One thing I really like about Phlex is how easy it is to group concerns into one place. Consider this Turbo Pagemorphs example. The view has a section in it with a bunch of turbo_ methods.

class View::Post < View::Base
  # Includes the turbo_stream_from method
  include Phlex::Rails::Helpers::TurboStreamFrom

  def initialize(post:)
    @post = post
  end

  # All of our Turbo Stream behavior is configured from one place.
  def turbo_refresh_method = "replace"
  def turbo_refresh_scroll = "preserve"
  def turbo_streams
    turbo_stream_from @post.comments
  end

  def view_template
    h1 { @post.title }
    main(class: "prose"){
      safe render @post.body, type: :md
    }
    div(id: "comments") do
      comments.each do |comment|
        div(class: "comment") do
          p { comment.body }
        end
      end
    end
  end
end

The base layout then implements those methods in the head and body tags.

class View::Base < View::Component
  # Default to `nil` so we're not morphing all pages
  def turbo_refresh_method = nil
  # Default to `nil` so we're not scrolling to the top of the page
  def turbo_refresh_scroll = nil

  # Put all subscriptions here in the subclass.
  def turbo_streams = nil

  def around_template
    head do
      # Other meta tags
      meta(name: "turbo-pageload", content: turbo_refresh_method)
      meta(name: "turbo-refresh-scroll", content: turbo_refresh_scroll)
      # More meta tags...
    end
    # Renders the body ...
    body do
      yield
      turbo_streams
    end
    # Whatever else ...
  end
end

When the layout renders, it uses the methods from the subclass to set the values. If none are set, it defaults to the nil values set in the layout class.

I cover this in the Phlex on Rails course, and even more advanced techniques for organizing view concerns like Turbo, OpenGraph, and more by class composition.

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

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

Pre-order the video course for $379 $249