You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
4.4 KiB

# frozen_string_literal: true
require_relative "models"
1 year ago
require "roda"
class App < Roda
opts[:check_dynamic_arity] = false
opts[:check_arity] = :warn
plugin :default_headers,
"Content-Type" => "text/html",
# "Strict-Transport-Security" => "max-age=16070400;", # Uncomment if only allowing https:// access
"X-Frame-Options" => "deny",
"X-Content-Type-Options" => "nosniff",
"X-XSS-Protection" => "1; mode=block"
plugin :content_security_policy do |csp|
csp.default_src :none
# csp.style_src :self, "https://cdn.jsdelivr.net"
csp.form_action :self
csp.script_src :self
csp.connect_src :self
csp.base_uri :none
csp.frame_ancestors :none
end
# css_opts = {cache: false, style: :compressed}
# :nocov:
# if ENV["RACK_ENV"] == 'development'
# css_opts.merge!(source_map_embed: true, source_map_contents: true, source_map_file: ".")
# end
plugin :render_coverage if defined?(SimpleCov)
# :nocov:
plugin :route_csrf
plugin :flash
# plugin :assets, css: "app.scss", css_opts: css_opts, timestamp_paths: true
# plugin :render, escape: true, layout: "./layout", :template_opts=>{chain_appends: !defined?(SimpleCov), freeze: true, skip_compiled_encoding_detection: true}
1 year ago
plugin :render, engine: :phlex
# plugin :public
plugin :Integer_matcher_max
plugin :typecast_params_sized_integers, sizes: [64], default_size: 64
plugin :hash_branch_view_subdir
logger = if ENV["RACK_ENV"] == "test"
Class.new{def write(_) end}.new
else
$stderr
end
plugin :common_logger, logger
plugin :not_found do
@page_title = "File Not Found"
view(content: "")
end
if ENV["RACK_ENV"] == "development"
plugin :exception_page
class RodaRequest
def assets
exception_page_assets
super
end
end
else
def self.freeze
Sequel::Model.freeze_descendents
DB.freeze
super
end
end
plugin :error_handler do |e|
case e
when Roda::RodaPlugins::RouteCsrf::InvalidToken
@page_title = "Invalid Security Token"
response.status = 400
view(content: "<p>An invalid security token was submitted with this request, and this request could not be processed.</p>")
else
$stderr.print "#{e.class}: #{e.message}\n"
$stderr.puts e.backtrace
next exception_page(e, assets: true) if ENV["RACK_ENV"] == "development"
@page_title = "Internal Server Error"
view(content: "")
end
end
plugin :sessions,
key: "_App.session",
#cookie_options: {secure: ENV['RACK_ENV'] != 'test'}, # Uncomment if only allowing https:// access
secret: ENV.send((ENV["RACK_ENV"] == "development" ? :[] : :delete), "APP_SESSION_SECRET")
# if Unreloader.autoload?
# plugin :autoload_hash_branches
# autoload_hash_branch_dir("./routes")
# end
# Unreloader.autoload("routes", delete_hook: proc{|f| hash_branch(File.basename(f).delete_suffix(".rb"))}){}
1 year ago
route do |r|
# r.public
# r.assets
check_csrf!
1 year ago
r.root do
@page_title = "Foo"
1 year ago
# render("hello", locals: {name: "Alice"})
view("hello", locals: {name: "Bob"})
1 year ago
end
end
end
require "tilt/template"
require "phlex"
module Tilt
class PhlexTemplate < Template
def prepare
end
1 year ago
# I have no idea how this works - it's just copied pretty much blindly from here:
#
# https://github.com/phlex-ruby/phlex-rails/blob/main/lib/phlex/rails/layout.rb#L18
def evaluate(scope, locals, &block)
p scope
p locals
1 year ago
klass = Class.new(Phlex::HTML)
klass.class_eval(data, __FILE__, __LINE__)
component = klass.new(**locals)
component.call do |yielded|
output = yield
component.unsafe_raw(output)
end
1 year ago
end
1 year ago
# Not sure if this is better...?
# def precompiled_preamble(*) = "klass = Class.new(Phlex::HTML) do"
# def precompiled_template(*) = data
# def precompiled_postamble(locals) = <<~RUBY
# end
# component = klass.new(**locals)
# component.call do |yielded|
# output = yield
# component.unsafe_raw(output)
# end
# RUBY
1 year ago
end
end
Tilt.register(Tilt::PhlexTemplate, "phlex")