Slide 1

Slide 1 text

Phlex HTML in Pure Ruby (whaaat?) Bradley Schaefer / @[email protected]

Slide 2

Slide 2 text

Expectations • This talk is for Web Developers • You are familiar with Ruby • My presentation skills could use some work

Slide 3

Slide 3 text

What is the purpose of this talk? Adventure! Exploration! Wonder! Fun! Excitement! Joy!

Slide 4

Slide 4 text

What is the purpose of this talk? * maybe to convince you to start using phlex for everything Adventure! Exploration! Wonder! Fun! Excitement! Joy!

Slide 5

Slide 5 text

How are you writing HTML templates today? ERB (Embedded RuBy) Ruby Toys -- <%= @name %>

<%= @name %> (<%= @code %>)

<%= @desc %>

    <% @features.each do |f| %>
  • <%= f %>
  • <% end %>

<% if @cost < 10 %> Only <%= @cost %>!!! <% else %> Call for a price, today! <% end %>

Slide 6

Slide 6 text

How are you writing HTML templates today? ERB (Embedded RuBy) Haml (HTML Abstraction Markup Language) Ruby Toys -- <%= @name %>

<%= @name %> (<%= @code %>)

<%= @desc %>

    <% @features.each do |f| %>
  • <%= f %>
  • <% end %>

<% if @cost < 10 %> Only <%= @cost %>!!! <% else %> Call for a price, today! <% end %>

%html %head %title Ruby Toys -- #{@name} %body %h1 #{@name} (#{@code}) %p= @desc %ul - @features.each do |f| %li %b= f %p - if @cost < 10 %b Only #{@cost}!!! - else Call for a price, today!

Slide 7

Slide 7 text

How are you writing HTML templates today? ERB (Embedded RuBy) Liquid (Jekyll) Ruby Toys -- <%= @name %>

<%= @name %> (<%= @code %>)

<%= @desc %>

    <% @features.each do |f| %>
  • <%= f %>
  • <% end %>

<% if @cost < 10 %> Only <%= @cost %>!!! <% else %> Call for a price, today! <% end %>

Ruby Toys -- {{ name }}

{{ name }} ({{ code }})

{{ desc }}

    {% for f in features %}
  • {{ f }}
  • {% endfor %}

{% if cost < 10 %} Only {{ cost }}!!! {% else %} Call for a price, today! {% endif %}

Slide 8

Slide 8 text

🔥Hot Take🔥

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Just. look at it… Haml (HTML Abstraction Markup Language) %html %head %title Ruby Toys -- #{@name} %body %h1 #{@name} (#{@code}) %p= @desc %ul - @features.each do |f| %li %b= f %p - if @cost < 10 %b Only #{@cost}!!! - else Call for a price, today!

Slide 11

Slide 11 text

Something even better! https://phlex.fun

Slide 12

Slide 12 text

Phlex is Ruby ERB (Embedded RuBy) Phlex Ruby Toys -- <%= @name %>

<%= @name %> (<%= @code %>)

<%= @desc %>

    <% @features.each do |f| %>
  • <%= f %>
  • <% end %>

<% if @cost < 10 %> Only <%= @cost %>!!! <% else %> Call for a price, today! <% end %>

class ExamplePage < Phlex::HTML def template html do head { title { "Ruby Toys -- #{@name}" } } body do h1 { "#{@name} (#{@code})" } p { @desc } ul do @features.each do |f| li { b { f } } end end p do if @cost < 10 b { "Only #{@cost}!!!" } else "Call for a price, today!" end end end end end end

Slide 13

Slide 13 text

🧐 Is this actually better? class ExamplePage < Phlex::HTML def template html do head { title { "Ruby Toys -- #{@name}" } } body do h1 { "#{@name} (#{@code})" } p { @desc } ul do @features.each do |f| li { b { f } } end end p do if @cost < 10 b { "Only #{@cost}!!!" } else "Call for a price, today!" end end end end end end

Slide 14

Slide 14 text

🧐 Also, I cheated a little bit class ExamplePage < Phlex::HTML def template html do head { title { "Ruby Toys -- #{@name}" } } body do h1 { "#{@name} (#{@code})" } p { @desc } ul do @features.each do |f| li { b { f } } end end p do if @cost < 10 b { "Only #{@cost}!!!" } else "Call for a price, today!" end end end end end end

Slide 15

Slide 15 text

👍 good old-fashioned Ruby class ExamplePage < Phlex::HTML def initialize def template html do head { title { "Ruby Toys -- #{@name}" } } body do h1 { "#{@name} (#{@code})" } p { @desc } ul do @features.each do |f| li { b { f } } end end p do if @cost < 10 b { "Only #{@cost}!!!" } else "Call for a price, today!" end end end end end end def initialize(name:, code:, desc:, features:, cost:) @name = name @code = code @desc = desc @features = features @cost = cost end

Slide 16

Slide 16 text

It’s Fast • 12x faster than Rails ERB partials • 5.5x faster than ViewComponents • 84x faster than dry-view https://github.com/KonnorRogers/view-layer-benchmarks

Slide 17

Slide 17 text

It’s Fast

Slide 18

Slide 18 text

Slides are hard. Who wants to do some live coding?

Slide 19

Slide 19 text

That’s great, but in Rails? https://www.phlex.fun/rails/

Slide 20

Slide 20 text

What does that get you? Layouts Component Generator yield / content_for Helpers Controller Generator View Generator ApplicationView ApplicationComponent

Slide 21

Slide 21 text

What a Controller looks like class ArticlesController < ApplicationController layout -> { ApplicationLayout } def index # explicit rendering is required render Articles::IndexView.new( articles: Article.all.load_async ) end def show render Articles::ShowView.new( article: Article.find(params[:id]) ) end end

Slide 22

Slide 22 text

What’s in an ApplicationComponent? class ApplicationComponent < Phlex::HTML def h1 = super(class: "text-3xl font-semibold my-5") def h2 = super(class: "text-2xl font-semibold mt-10 mb-5") def a(**attributes) super( class: "font-bold text-red-600 underline underline-offset-4", **attributes ) end end

Slide 23

Slide 23 text

Migrating Existing Views https://www.phlexing.fun

Slide 24

Slide 24 text

Yes, it works with

Slide 25

Slide 25 text

Advanced Examples ⚡ Feel the POWER ⚡

Slide 26

Slide 26 text

Phlex Documentation (built in Phlex) https://github.com/joeldrapper/phlex.fun/ https://phlex.fun

Slide 27

Slide 27 text

Phlex Documentation (built in Phlex)

Slide 28

Slide 28 text

Slides are hard. To the editor!

Slide 29

Slide 29 text

Custom Tags & Attributes class JiraTaskList < Phlex::HTML register_element :ac_task_list, tag: "ac:task-list" register_element :ac_task, tag: "ac:task" register_element :ac_task_status, tag: "ac:task-status" register_element :ac_task_body, tag: "ac:task-body" register_element :ac_placeholder, tag: "ac:placeholder" def template ac_task_list do ac_task do ac_task_status { "incomplete" } ac_task_body do ac_placeholder(**{:"ac:type" => "mention"}) do "@mention example. This placeholder will automatically search " + "for a user to mention in the page when the user begins typing." end end end end end end

Slide 30

Slide 30 text

Reasons to NOT use Phlex • You never want to test views • You hate Ruby • You don’t write HTML • You don’t care about rendering performance

Slide 31

Slide 31 text

But, seriously Phlex is Fun! Try it out!

Slide 32

Slide 32 text

Phlex HTML in Pure Ruby (whaaat?) Bradley Schaefer / @[email protected] https://github.com/soulcutter/phlex-talk