A Roda plugin that adds some convenience rendering
Phlex views.
Especially accessing application methods from the view.
- API documentation is available at https://www.rubydoc.info/gems/roda-phlex
Install the gem and add to the application's Gemfile by executing:
bundle add roda-phlex
If bundler is not being used to manage dependencies, install the gem by executing:
gem install roda-phlex
plugin :phlex
takes the following options:
:layout
(Phlex::SGML
): Specifies the layout class to be used for rendering views. This class should be a Phlex layout class that defines how the views are structured and rendered.:layout_opts
(Object
): Options that are passed to the layout class when it is instantiated. These options can be used to customize the behavior of the layout. Usually, this is aHash
. To avoid external changes effecting subsequent requests, you should.freeze
this and all nested objects.:layout_handler
(#call
): A custom handler for creating layout instances. This proc receives three arguments: the layout class, the layout options, and the object to be rendered. By default, it runslayout.new(obj, **layout_opts)
, which instantiates the layout class with the provided view object and options as keyword arguments.:context
(Hash
): The context that is passed to the rendering call. (default:{}
) To avoid external changes effecting subsequent requests, you should.freeze
this and all nested objects.:delegate
: Define if or which methods should be delegated to the Roda app:true
(default): Create a singleapp
method that delegates to the Roda app.false
: Do not create any delegate methods.Array<Symbol,String>
: Delegate the named methods to the Roda app.
:delegate_on
: Class or module to define delegation methods on. Defaults to::Phlex::SGML
.- Use this option to limit delegation methods to a application specific class or module (like "ApplicationView") to avoid polluting the global namespace.
:delegate_name
: The name of the method that delegates to the Roda app. Defaults to"app"
.
Add the plugin to the Roda application:
plugin :phlex
Use the phlex
method in the view to render a Phlex view:
route do |r|
r.root do
phlex MyView.new
end
end
You can use all application methods in the view:
plugin :sinatra_helpers
plugin :phlex, delegate: [:url]
class MyView < Phlex::View
def view_template
h1 { 'Phlex / Roda request params integration' }
p {
a(href: url("/path", true)) { "link" }
}
pre { app.request.params.inspect }
end
end
You can also pass an alternative content type (automatically sets image/svg+xml
for a Phlex::SVG
instance):
route do |r|
r.get '/foo' do
phlex MyView.new, content_type: "application/xml"
end
end
Streaming a Phlex view can be enabled by passing stream: true
which will cause Phlex to automatically write
to the response after the closing </head>
and buffer the remaining content.
The Roda :stream
plugin must be enabled for this to work.
plugin :streaming
get '/foo' do
phlex MyView.new, stream: true
end
You can also manually flush the contents of the buffer at any point using Phlex's #flush
method:
class Layout < Phlex::HTML
def view_template(&block)
doctype
html {
head {
# All the usual stuff: links to external stylesheets and JavaScript etc.
}
# Phlex will automatically flush to the response at this point which will
# benefit all pages that opt in to streaming.
body {
# Standard site header and navigation.
render Header.new
yield
}
}
end
end
class MyView < Phlex::HTML
def view_template
render Layout.new {
# Knowing that this page can take a while to generate we can choose to
# flush here so the browser can render the site header while downloading
# the rest of the page - which should help minimise the First Contentful
# Paint metric.
flush
# The rest of the big long page...
}
end
end
# Define a default layout and layout options for the whole application
plugin :phlex, layout: MyLayout, layout_opts: { title: "My App".freeze }.freeze
route do |r|
r.on "posts" do
# redefine the layout and layout options for this route tree
set_phlex_layout MyPostLayout
set_phlex_layout_opts phlex_layout_opts.merge(title: "#{phlex_layout_opts[:title]} - Posts")
r.get 'new' do
# Redefine the layout and layout options for this route
phlex_layout_opts[:title] << " - Create new post"
phlex MyView.new
end
end
end
Bug reports and pull requests are welcome on GitHub at https://github.com/fnordfish/roda-phlex. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the Roda::Phlex project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
This gem is based on phlex-sinatra, and extended by the layout handling features in RomanTurner's gist