roda-phlex
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
Installation
Install the gem and add to the application's Gemfile by executing:
bundle add roda-phlexIf bundler is not being used to manage dependencies, install the gem by executing:
gem install roda-phlexPhlex Compatibility
- Version 1.x of
roda-phlexis compatible with Phlex 2.0. - For Phlex 1.x compatibility, use version 0.x of this gem, or the
phlex-1branch.
Configuration
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.freezethis 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.freezethis and all nested objects. -
:delegate: Define if or which methods should be delegated to the Roda app:-
true(default): Create a singleappmethod 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".
Usage
Add the plugin to the Roda application:
plugin :phlexUse the phlex method in the view to render a Phlex view:
route do |r|
r.root do
phlex MyView.new
end
endYou 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
endYou 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
endStreaming
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
endYou 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
endReconfiguring in a route
# 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
endContributing
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.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Roda::Phlex project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
Acknowledgements
This gem is based on phlex-sinatra, and extended by the layout handling features in RomanTurner's gist