Is it possible to get Middleman to work with Phlex?

I would really like to try out a “component”-based approach with Middleman. Is it possible to get Phlex working? I tried to set it up, but got stuck. These were my steps:

  • include the phlex gem
  • create a demo component in components/hello.rb and an empty class in components.rb
  • require both from the config.rb
  • render the component with = render Components::Hello.new

But then I got a contract violation error for the #render method.

It seems like Middleman’s internal type system kills the interoperability here. Is that correct? Could I simply monkey patch that away for a proof of concept?

Ideally I would like to achive a flat folder structure with all my components in the end:

source/components/
  button.rb
  button.sass
  ...
  menu.js
  menu.rb
  menu.sass

Non-component JS and CSS could still remain in the javascripts/ and stylesheets/ folders. Apart from getting Phlex to work at all, that would also require a fair bit of hackery for the autoloading.

Do you think this is doable?

The following seems to work in a HAML view:

= Components::Hello.new.call.html_safe

The html_safe seems to escape correctly despite it seemingly being applied to the whole component and not just the safe strings. Well, what exactly are “unsafe strings” in a static page anyways? I guess this will not be a security issue.

One immediate drawback of Phlex in Middleman compared to regular views seems to be the missing autoloading. Middleman could use a bit of Zeitwerk.

Now I just need to stick Phlex, JS and CSS all into a single folder and teach middleman to do the right thing for each file type. How hard can it be?

I think I got it. I’ll post a demo repo in the next few days. It’s really hacky though. It uses the old gem 'opal', '~> 0.10.6' trick to make Middleman boot despite Ruby files in the source/directory. I also used weird paths to make the CSS and JS outside their default folders work. I will be so surprised if that works during build.

Also:

  • no hotreloading
  • no compile step (no build FTW then, I guess)