{"id":16189512,"url":"https://github.com/benpickles/phlex-sinatra","last_synced_at":"2025-10-19T12:09:03.043Z","repository":{"id":153361373,"uuid":"629136390","full_name":"benpickles/phlex-sinatra","owner":"benpickles","description":"A Phlex adapter for Sinatra","archived":false,"fork":false,"pushed_at":"2025-02-23T10:27:50.000Z","size":39,"stargazers_count":7,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-28T08:15:24.588Z","etag":null,"topics":["phlex","ruby","sinatra"],"latest_commit_sha":null,"homepage":"https://www.benpickles.com/articles/92-phlex-sinatra","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benpickles.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-17T17:39:28.000Z","updated_at":"2025-06-21T22:49:27.000Z","dependencies_parsed_at":"2025-02-23T11:21:58.297Z","dependency_job_id":"441681d7-69fa-4fd6-aa04-4ebe18425bb2","html_url":"https://github.com/benpickles/phlex-sinatra","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/benpickles/phlex-sinatra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benpickles%2Fphlex-sinatra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benpickles%2Fphlex-sinatra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benpickles%2Fphlex-sinatra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benpickles%2Fphlex-sinatra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benpickles","download_url":"https://codeload.github.com/benpickles/phlex-sinatra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benpickles%2Fphlex-sinatra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275658682,"owners_count":25504776,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["phlex","ruby","sinatra"],"created_at":"2024-10-10T07:35:44.697Z","updated_at":"2025-09-17T20:31:35.613Z","avatar_url":"https://github.com/benpickles.png","language":"Ruby","readme":"# phlex-sinatra\n\n[Phlex](https://github.com/phlex-ruby/phlex) already works with Sinatra (and everything else) but its normal usage leaves you without access to Sinatra's standard helper methods. This extension lets you use Sinatra's `url()` helper method from within a Phlex view (along with the rest of the helper methods available in a Sinatra action).\n\n## Installation\n\nAdd phlex-sinatra to your application's `Gemfile` and run `bundle install`.\n\n```ruby\ngem 'phlex-sinatra'\n```\n\nThen require it in your app:\n\n```ruby\nrequire 'phlex-sinatra'\n```\n\n## Usage\n\nUse the `phlex` helper method to render a Phlex view and pass an _instance_ of the Phlex view (instead of using `.call` to get its output). For a classic-style Sinatra app it'll Just Work™:\n\n```ruby\nget '/foo' do\n  phlex MyView.new\nend\n```\n\nFor a modular app the extension must be explicitly registered:\n\n```ruby\nclass MyApp \u003c Sinatra::Base\n  helpers Phlex::Sinatra\n\n  get '/foo' do\n    phlex MyView.new\n  end\nend\n```\n\nYou can now use Sinatra's `url()` helper method directly and its other methods (`params`, `request`, etc) via the `helpers` proxy:\n\n```ruby\nclass MyView \u003c Phlex::HTML\n  def view_template\n    h1 { 'Phlex / Sinatra integration' }\n    p {\n      a(href: url('/foo', false)) { 'link to foo' }\n    }\n    pre { helpers.params.inspect }\n  end\nend\n```\n\nYou can also pass an alternative content type – which defaults to `:html` (or `:svg` for a `Phlex::SVG` instance):\n\n```ruby\nget '/foo' do\n  phlex MyView.new, content_type: :xml\nend\n```\n\n## Layout\n\nIf your entire view layer uses Phlex then layout will be a part of your component structure but maybe you've got an existing non-Phlex layout or you don't want to use Phlex for _everything_, in which case standard Sinatra layouts are supported.\n\nPass `layout: true` to wrap the Phlex output with Sinatra's default layout -- a file named \"layout.erb\" in the configured views directory (ERB is the default) -- or pass a symbol to specify the file:\n\n```ruby\nget '/foo' do\n  # This Phlex view will be wrapped by `views/my_layout.erb`.\n  phlex MyView.new, layout: :my_layout\nend\n```\n\nOther [Sinatra templating languages](https://sinatrarb.com/intro.html#available-template-languages) can be specified via the `layout_engine` keyword:\n\n```ruby\nget '/foo' do\n  # This Phlex view will be wrapped by `views/layout.haml`.\n  phlex MyView.new, layout: true, layout_engine: :haml\nend\n```\n\n## Using Phlex in other templates\n\nIt's also possible to call `phlex` from within other views, for instance an ERB template:\n\n```erb\n\u003c%= phlex MyView.new %\u003e\n```\n\nA `layout` can also be passed:\n\n```erb\n\u003c%= phlex MyView.new, layout: :wrapper %\u003e\n```\n\n## Streaming\n\nStreaming a Phlex view can be enabled by passing `stream: true` which will cause Phlex to automatically write to the response after the closing `\u003c/head\u003e` and buffer the remaining content:\n\n```ruby\nget '/foo' do\n  phlex MyView.new, stream: true\nend\n```\n\nEven with no further intervention this small change means that the browser will receive the complete `\u003chead\u003e` as quickly as possible and can start fetching and processing its external resources while waiting for the rest of the page to download.\n\nYou can also manually flush the contents of the buffer at any point using Phlex's `#flush` method:\n\n```ruby\nclass Layout \u003c Phlex::HTML\n  def view_template(\u0026block)\n    doctype\n    html {\n      head {\n        # All the usual stuff: links to external stylesheets and JavaScript etc.\n      }\n      # Phlex will automatically flush to the response at this point which will\n      # benefit all pages that opt in to streaming.\n      body {\n        # Standard site header and navigation.\n        render Header.new\n\n        yield_content(\u0026block)\n      }\n    }\n  end\nend\n\nclass MyView \u003c Phlex::HTML\n  def view_template\n    render Layout.new {\n      # Knowing that this page can take a while to generate we can choose to\n      # flush here so the browser can render the site header while downloading\n      # the rest of the page - which should help minimise the First Contentful\n      # Paint metric.\n      flush\n\n      # The rest of the big long page...\n    }\n  end\nend\n```\n\n## Why do I need Sinatra's `url()` helper?\n\nIt might not seem obvious at first why you'd use `url()` at all given that you mostly just pass the string you want to output and then probably `false` so the scheme/host isn't included.\n\nThere are a couple of reasons:\n\n1. **Linking to a full URL**\n\n   Sometimes you need to link to a page on the site using its full URL – for instance within a feed or for an `og:image` social media preview image link.\n\n2. **Awareness that the app is being served from a subdirectory**\n\n   This isn't something you encounter very often in a standard Sinatra app but you hit it quite quickly if you're using [Parklife](https://github.com/benpickles/parklife) to generate a static build hosted on GitHub Pages – which is exactly what prompted me to write this integration.\n\n   In this case by using the `url()` helper you won’t have to change anything when switching between serving the app from `/` in development and hosting it at `/my-repository/` in production – internal links to other pages/stylesheets/etc will always be correct regardless.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at \u003chttps://github.com/benpickles/phlex-sinatra\u003e. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/benpickles/phlex-sinatra/blob/main/CODE_OF_CONDUCT.md).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the phlex-sinatra project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/benpickles/phlex-sinatra/blob/main/CODE_OF_CONDUCT.md).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenpickles%2Fphlex-sinatra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenpickles%2Fphlex-sinatra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenpickles%2Fphlex-sinatra/lists"}