-
-
Save 1gor/8974885fa518c609406e710cdaf9b9db to your computer and use it in GitHub Desktop.
A plugin for Roda for using Phlex as the rendering library of choice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Roda | |
module RodaPlugins | |
module Phlex | |
def self.configure(app, opts) | |
app.opts[:class_name] = app.name | |
app.opts[:phlex] = opts | |
end | |
module InstanceMethods | |
# Render a component with the default layout. | |
# You can change out the layout per render basis, so you are not trapped | |
# With the configurations. You may also send options to the layouts themselves. | |
def phlex_on(component, layout: opts[:phlex][:layout], layout_options: {}) | |
title = layout_options[:title] || opts[:class_name] | |
layout.new(component, title: title).call | |
end | |
def phlex_layout | |
opts[:phlex][:layout] | |
end | |
def phlex_add_to_head(head) | |
current_head = opts[:phlex][:layout].current_head | |
if head.kind_of?(Array) | |
current_head.concat(head) | |
else | |
current_head << head | |
end | |
end | |
end | |
end | |
register_plugin :phlex, Phlex | |
end | |
end | |
# Example Roda App | |
require 'roda' | |
class App < Roda | |
# Load Custom Plugins | |
Dir["roda_plugins/*"].each do |route_file| | |
require_relative route_file | |
end | |
# Pass a reference to the default layout | |
plugin :phlex, layout: Shared::Layout::Homepage | |
# Configure Default Layout | |
Dir["allocs/shared/layouts"].each do |layouts| | |
require_relative layouts | |
end | |
route do |r| | |
r.root do | |
phlex_on( | |
Shared::Pages::Hello.new(Struct.new(:first_name).new('bob')), | |
layout_options: {title: "Phlex Test"} | |
) | |
end | |
r.get "hello" do | |
phlex_on( | |
Shared::Pages::Hello.new(User::DataModel.first), | |
layout_options: {title: "User Hello"} | |
) | |
end | |
r.on 'admin do | |
authorize_admin! | |
r.get 'dashboard' do | |
phlex_layout(Shared::Layout::AdminHome) | |
phlex_on( | |
Admin::Pages::Dashboard.new(Admin::DataModel.first), | |
layout_options: {title: "User Admin"} | |
) | |
end | |
end | |
end | |
end | |
## Layout Example | |
module Shared | |
module Layout | |
class Homepage < Phlex::HTML | |
attr_accessor :current_head | |
class Empty < Phlex::HTML | |
def template | |
"" | |
end | |
end | |
def initialize(component, title:) | |
@title = title | |
@current_head = [] | |
@component = component || Empty.new | |
end | |
def template | |
html do | |
head do | |
meta(charset: "UTF-8") | |
meta("http-equiv" => "UTF-8", :content => "IE=edge") | |
meta( | |
name: "viewport", | |
content: "width=device-width, initial-scale=1.0" | |
) | |
render vite_javascript_tag("application") | |
render vite_client_tag | |
compose_head | |
title { @title } | |
end | |
body { render @component } | |
end | |
end | |
private | |
def compose_head | |
current_head.each { |el| render el } if !current_head.empty? | |
end | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment