37 | All the mailers are available under the Mailers namespace.
38 |
39 |
40 |
--------------------------------------------------------------------------------
/content/v1.3/mailers/share-code.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Share Code
3 | order: 50
4 | aliases:
5 | - "/mailers/share-code"
6 | ---
7 |
8 | ## Prepare
9 |
10 | In our settings (`lib/bookshelf.rb`), there is code block that allows to share the code for **all the mailers** of our application.
11 | When a mailer includes the `Hanami::Mailer` module, that block code is yielded within the context of that class.
12 | This is heavily inspired by Ruby Module and its `included` hook.
13 |
14 | Imagine we want to set a default sender for all the mailers.
15 | Instead of specifying it for each mailer, we can use a DRY approach.
16 |
17 | We create a module:
18 |
19 | ```ruby
20 | # lib/mailers/default_sender.rb
21 | module Mailers
22 | module DefaultSender
23 | def self.included(mailer)
24 | mailer.class_eval do
25 | from 'sender@bookshelf.org'
26 | end
27 | end
28 | end
29 | end
30 | ```
31 |
32 | Then we include in all the mailers of our application, via `prepare`.
33 |
34 | ```ruby
35 | # lib/bookshelf.rb
36 | # ...
37 |
38 | Hanami.configure do
39 | # ...
40 | mailer do
41 | root 'lib/bookshelf/mailers'
42 |
43 | # See https://guides.hanamirb.org/mailers/delivery
44 | delivery :test
45 |
46 | prepare do
47 | include Mailers::DefaultSender
48 | end
49 | end
50 | end
51 | ```
52 |
53 |
54 | Code included via prepare is available for ALL the mailers of an application.
55 |
56 |
57 |
--------------------------------------------------------------------------------
/content/v1.3/mailers/testing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Testing
3 | order: 60
4 | aliases:
5 | - "/mailers/testing"
6 | ---
7 |
8 | During development and testing we don't want to accidentally send emails to the real world.
9 | The [delivery method](/mailers/delivery) for these two envs is set to `:test`.
10 |
11 | In order to assert that a mailer sent a message, we can look at `Hanami::Mailer.deliveries`.
12 | It's an array of messages that the framework pretended to deliver during a test.
13 | Please make sure to **clear** them in testing setup.
14 |
15 | ```ruby
16 | # spec/bookshelf/mailers/welcome_spec.rb
17 | RSpec.describe Mailers::Welcome do
18 | before { Hanami::Mailer.deliveries.clear }
19 |
20 | let(:user) { ... }
21 |
22 | it "delivers welcome email" do
23 | Mailers::Welcome.deliver(user: user)
24 | mail = Hanami::Mailer.deliveries.last
25 |
26 | expect(mail.to).to eq([user.email])
27 | expect(mail.body.encoded).to eq("Hello, #{ user.name }")
28 | end
29 | end
30 | ```
31 |
--------------------------------------------------------------------------------
/content/v1.3/migrations/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Migrations
3 | order: 110
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v1.3/models/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Models
3 | order: 70
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v1.3/models/use-your-own-orm.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Use Your Own ORM
3 | order: 30
4 | aliases:
5 | - "/models/use-your-own-orm"
6 | ---
7 |
8 | Hanami components are decoupled from each other.
9 | This level of separation allows you to use the ORM (data layer) of your choice.
10 |
11 | Here's how to do it:
12 |
13 | 1. Edit your `Gemfile`:
14 | - Remove `hanami-model`.
15 | - Add the gem(s) for your ORM.
16 | 2. Run `bundle install`.
17 | 3. Remove folders that are no longer needed:
18 | - Remove `lib/project_name/entities/` and `lib/projectname/repositories/`
19 | - Remove `spec/project_name/entities/` and `spec/project_name/repositories/`.
20 | 5. Edit `config/environment.rb`:
21 | - Remove `require 'hanami/model'`
22 | - Remove `require_relative '../lib/projectname'`
23 | - Remove `model` block in `Hanami.configure`
24 | 6. Edit `Rakefile`:
25 | - Remove `require 'hanami/rake_tasks'`.
26 |
27 | In general, `lib/project_name/` is a good place to put code that's used across
28 | apps, so we don't recommend getting rid of it entirely. That's also where
29 | Hanami's mailers live. We recommend that you put your new ORM code into that
30 | folder, but you're free to put it elsewhere, and get rid of `lib/` entirely, if
31 | you choose.
32 |
33 | Please be aware that if `hanami-model` is removed from the project features like [database commands](/command-line/database) and [migrations](/migrations/overview) won't be available.
34 |
35 | ## Hanami + ROM 4.0
36 |
37 | If you want to use latest [rom](https://rom-rb.org) version without hanami-model you can use [this repository](https://github.com/solnic/hanami-bookshelf-rom/) as a tutorial for this:
38 |
39 | https://github.com/solnic/hanami-bookshelf-rom/
40 |
--------------------------------------------------------------------------------
/content/v1.3/projects/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Projects
3 | order: 30
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v1.3/projects/code-reloading.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Code Reloading"
3 | order: 10
4 | aliases:
5 | - "/projects/code-reloading"
6 | ---
7 |
8 | _Code reloading_ allows us to edit code and see the changes with a browser refresh, without needing to stop and restart the [server](/command-line/applications).
9 |
10 | ## Development Environment
11 |
12 | This is a development-only feature.
13 | Hanami uses `shotgun` Ruby gem to reload the code as-needed.
14 | New generated projects have this entry in their `Gemfile`:
15 |
16 | ```ruby
17 | group :development do
18 | # Code reloading
19 | # See: https://guides.hanamirb.org/projects/code-reloading
20 | gem 'shotgun'
21 | end
22 | ```
23 |
24 | Unfortunately, `shotgun` requires that the current environment supports `fork(2)`.
25 | JRuby and Windows don't support it.
26 | If this is your case, `shotgun` is not compatible with your development environment, then you can remove that entry from the `Gemfile` or start the server with the `--no-code-reloading` argument.
27 |
28 | ## Other Environments
29 |
30 | Hanami doesn't implement _code reloading_ in its core.
31 |
32 | The framework doesn't know about this feature, it just uses Ruby to load the code and execute it. It's `shotgun` that makes _code reloading_ possible, by wrapping Hanami projects' code.
33 |
34 | Because `shotgun` is only enabled in development, all the other environments don't have this _code reloading_ feature.
35 | By excluding this feature from the core of the framework, we make sure that Hanami projects don't mess with Ruby's code loading mechanisms in production.
36 |
37 | In other words, once the code is loaded in production, it isn't changed anymore.
38 |
--------------------------------------------------------------------------------
/content/v1.3/projects/initializers.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Initializers
3 | order: 40
4 | aliases:
5 | - "/projects/initializers"
6 | ---
7 |
8 | A project can **optionally** have one or more custom initializers.
9 |
10 |
11 | Initializers are optional
12 |
13 |
14 | An initializer is a Ruby file used to setup third-party libraries or some other aspect of the code.
15 |
16 | They are run as the **last** thing after the dependencies, the framework and the project code are loaded, but **before** the server or the console is started.
17 |
18 | For instance, if we want to setup [Bugsnag](https://bugsnag.com) for our project we can do:
19 |
20 | ```ruby
21 | # config/initializers/bugsnag.rb
22 | require 'bugsnag'
23 |
24 | Bugsnag.configure do |config|
25 | config.api_key = ENV['BUGSNAG_API_KEY']
26 | end
27 | ```
28 |
29 |
30 | Project initializers must be added under config/initializers.
31 |
32 |
33 |
34 | Initializers are executed in alphabetical order.
35 |
36 |
--------------------------------------------------------------------------------
/content/v1.3/projects/rack-middleware.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Rack Middleware
3 | order: 50
4 | aliases:
5 | - "/projects/rack-middleware"
6 | ---
7 |
8 | Hanami exposes a project level [Rack middleware stack](http://www.rubydoc.info/github/rack/rack/master/file/SPEC) to be configured like this:
9 |
10 | ```ruby
11 | # config/environment.rb
12 | Hanami.configure do
13 | middleware.use MyRackMiddleware
14 | end
15 | ```
16 |
17 | It's worth noticing that this is equivalent to add a middleware in `config.ru` file.
18 | The only difference is that third-party plugins can hook into `Hanami.configure` to inject their own middleware.
19 |
--------------------------------------------------------------------------------
/content/v1.3/projects/selectively-boot-apps.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Selectively boot apps
3 | order: 80
4 | aliases:
5 | - "/projects/selectively-boot-apps"
6 | ---
7 |
8 | With Hanami you can build your project by following the [Monolith-First](/architecture/overview/#monolith-first) principle.
9 | As you add more code to the project, you can grow it organically, by splitting the project into several Hanami apps.
10 |
11 | A real world Hanami project could have **dozens of Hanami apps in the same project** (for example, `web` for the front-end, `admin` for the administration, `api` for a JSON API, etc...)
12 | You might want to deploy them to different servers, even though they're all a part of the same project.
13 | For example, most of the servers could be used for the `web` app (for customers on the site), a couple could be used for an `api` (perhaps for customers using mobile apps), and you could have a single server running and `admin` application, since it'll likely get less traffic than the other two.
14 |
15 | We support this, with _selective booting_:
16 |
17 | ```ruby
18 | # config/environment.rb
19 | # ...
20 | Hanami.configure do
21 | if Hanami.app?(:web)
22 | require_relative '../apps/web/application'
23 | mount Web::Application, at: '/'
24 | end
25 |
26 | if Hanami.app?(:api)
27 | require_relative '../apps/api/application'
28 | mount Api::Application, at: '/api'
29 | end
30 |
31 | if Hanami.app?(:admin)
32 | require_relative '../apps/admin/application'
33 | mount Admin::Application, at: '/admin'
34 | end
35 | end
36 | ```
37 |
38 | You can declare which apps to use with the `HANAMI_APPS` environment variable.
39 | You can provide a single app, or several apps (joined with commas):
40 |
41 | ```shell
42 | $ HANAMI_APPS=web,api bundle exec hanami server
43 | ```
44 |
45 | This would start only the `web` and `api` applications.
46 |
--------------------------------------------------------------------------------
/content/v1.3/repositories/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Repositories
3 | order: 80
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v1.3/routing/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Routing
3 | order: 40
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v1.3/upgrade-notes/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Upgrade Notes
3 | order: 170
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v1.3/upgrade-notes/v070.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: v0.7.0
3 | order: 20
4 | aliases:
5 | - "/upgrade-notes/v070"
6 | ---
7 |
8 | * Rename all the gems in your `Gemfile` from `lotus` to `hanami`
9 |
10 | * Rename `.lotusrc` into `.hanamirc`
11 |
12 | * Find and replace in project: `lotus` => `hanami`
13 |
14 | * Find and replace in project: `Lotus` => `Hanami`
15 |
16 | * Find and replace in project: `LOTUS` => `HANAMI`
17 |
18 | * Rename the environment variable on your server from `LOTUS_ENV` to `HANAMI_ENV`
19 |
20 | **If you have any problem, don't hesitate to look for help in our [forum](http://discourse.hanamirb.org).**
21 |
--------------------------------------------------------------------------------
/content/v1.3/upgrade-notes/v110.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: v1.1.0
3 | order: 60
4 | aliases:
5 | - "/upgrade-notes/v110"
6 | ---
7 |
8 | * Edit `Gemfile`, by changing Hanami version: `gem 'hanami', '~> 1.1'`
9 |
10 | * Edit `Gemfile`, by changing Hanami Model version: `gem 'hanami-model', '~> 1.1'`
11 |
12 | * Run `bundle update hanami hanami-model`
13 |
14 | **If you have any problem, don't hesitate to look for help in our [forum](http://discourse.hanamirb.org).**
15 |
--------------------------------------------------------------------------------
/content/v1.3/upgrade-notes/v120.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: v1.2.0
3 | order: 70
4 | aliases:
5 | - "/upgrade-notes/v120"
6 | ---
7 |
8 | * Edit `Gemfile`, by changing Hanami version: `gem 'hanami', '~> 1.2'`
9 |
10 | * Edit `Gemfile`, by changing Hanami Model version: `gem 'hanami-model', '~> 1.2'`
11 |
12 | * Run `bundle update hanami hanami-model`
13 |
14 | **If you have any problem, don't hesitate to look for help in our [forum](http://discourse.hanamirb.org).**
15 |
--------------------------------------------------------------------------------
/content/v1.3/upgrade-notes/v130.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: v1.3.0
3 | order: 80
4 | aliases:
5 | - "/upgrade-notes/v130"
6 | ---
7 |
8 | * Edit `Gemfile`, by changing Hanami version: `gem 'hanami', '~> 1.3'`
9 |
10 | * Edit `Gemfile`, by changing Hanami Model version: `gem 'hanami-model', '~> 1.3'`
11 |
12 | * [DEPRECATION] Remove `force_ssl` from `apps/*/application.rb` in favor of web server rules (e.g. NGINX) or `rack-ssl-enforcer`.
13 |
14 | ```ruby
15 | # config/environment.rb
16 | require "rack/ssl-enforcer"
17 |
18 | Hanami.configure do
19 | # ...
20 | middleware.use Rack::SslEnforcer
21 | end
22 | ```
23 |
24 | * [DEPRECATION] Remove `body_parsers` from `apps/*/application.rb` in favor of a new Hanami middleware:
25 |
26 | ```ruby
27 | # config/environment.rb
28 | require "hanami/middleware/body_parser"
29 |
30 | Hanami.configure do
31 | # ...
32 | middleware.use Hanami::Middleware::BodyParser, :json
33 | end
34 | ```
35 |
36 | * [DEPRECATION] Remove usage of `parsed_request_body` from actions. Parsed body is accessible via `params`.
37 |
38 | * [DEPRECATION] Convert `Hanami::Utils::String` usage of instance methods to class methods (e.g. `Hanami::Utils::String.new("hanami").titleize` to `Hanami::Utils::String.titleize("hanami")`)
39 |
40 | * [DEPRECATION] Convert `Hanami::Utils::Hash` usage of instance methods to class methods (e.g. `Hanami::Utils::Hash.new("a" => 1).symbolize` to `Hanami::Utils::Hash.symbolize("a" => 1)`)
41 |
42 | * Run `bundle update hanami hanami-model`
43 |
44 | **If you have any problem, don't hesitate to look for help in our [forum](http://discourse.hanamirb.org).**
45 |
--------------------------------------------------------------------------------
/content/v1.3/validations/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Validations
3 | order: 120
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v1.3/validations/overview.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Overview
3 | order: 10
4 | aliases:
5 | - "/validations/overview"
6 | ---
7 |
8 | `Hanami::Validations` is a mixin that, once included by an object, adds lightweight set of validations to it.
9 |
10 | It works with input hashes and lets us to define a set of validation rules **for each** key/value pair. These rules are wrapped by lambdas (or special DSL) that check the input for a specific key to determine if it's valid or not. To do that, we translate business requirements into predicates that are chained together with Ruby _faux boolean logic_ operators (eg. `&` or `|`).
11 |
12 | Think of a signup form. We need to ensure data integrity for the `name` field with the following rules. It is required, it has to be: filled **and** a string **and** its size must be greater than 3 chars, but lesser than 64. Here’s the code, **read it aloud** and notice how it perfectly expresses our needs for `name`.
13 |
14 | ```ruby
15 | class Signup
16 | include Hanami::Validations
17 |
18 | validations do
19 | required(:name) { filled? & str? & size?(3..64) }
20 | end
21 | end
22 |
23 | result = Signup.new(name: "Luca").validate
24 | result.success? # => true
25 | ```
26 |
27 | There is more that `Hanami::Validations` can do: **type safety**, **composition**, **complex data structures**, **built-in and custom predicates**.
28 |
--------------------------------------------------------------------------------
/content/v1.3/views/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Views
3 | order: 60
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v1.3/views/custom-error-pages.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Custom Error Pages
3 | order: 60
4 | aliases:
5 | - "/views/custom-error-pages"
6 | ---
7 |
8 | When an unsuccessful request is returned, there are some special pages that a Hanami application presents to users.
9 | These pages have a generic graphic and some basic information like the [HTTP status code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) and the message.
10 |
11 | Hanami allows us to customize them on a per-application basis.
12 | We just need to create a template with the corresponding HTTP code as the filename (e.g. `apps/web/templates/500.html.erb`).
13 | From then on, all 500 errors (Internal Server Error) will be presented using that template (like for an exception that is not rescued).
14 |
15 |
16 | A template for a custom error page MUST be named after the HTTP code that it targets.
17 | Example: 500.html.erb for Internal Server Error (500).
18 |
19 |
20 |
21 | A template for a custom error page MUST be placed under the templates directory of the application.
22 |
23 |
--------------------------------------------------------------------------------
/content/v1.3/views/share-code.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Share Code
3 | order: 70
4 | aliases:
5 | - "/views/share-code"
6 | ---
7 |
8 | ## Prepare
9 |
10 | In our settings (`apps/web/application.rb`), there is a code block that allows to share the code for **all the views** of our application.
11 | When a view includes the `Web::View` module, that block code is yielded within the context of that class.
12 | This is heavily inspired by Ruby Module and its `included` hook.
13 |
14 | Imagine we have an application that only renders JSON.
15 | For each view we should specify the handled format. This can be tedious to do by hand, but we can easily DRY our code.
16 |
17 | We craft a module in `apps/web/views/accept_json.rb`.
18 |
19 | ```ruby
20 | # apps/web/views/accept_json.rb
21 | module Web
22 | module Views
23 | module AcceptJson
24 | def self.included(view)
25 | view.class_eval do
26 | format :json
27 | end
28 | end
29 | end
30 | end
31 | end
32 | ```
33 |
34 | Then we can load the file and include the module in **all** the views of our application, using view.prepare.
35 |
36 | ```ruby
37 | # apps/web/application.rb
38 | require_relative './views/accept_json'
39 |
40 | module Web
41 | class Application < Hanami::Application
42 | configure do
43 | # ...
44 | view.prepare do
45 | include Web::Views::AcceptJson
46 | end
47 | end
48 | end
49 | end
50 | ```
51 |
52 |
53 | Code included via prepare is available for ALL the views of an application.
54 |
55 |
--------------------------------------------------------------------------------
/content/v2.0/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | version: v2.0
3 | ---
4 |
--------------------------------------------------------------------------------
/content/v2.0/actions/404-response.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.0/actions/404-response.png
--------------------------------------------------------------------------------
/content/v2.0/actions/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Actions
3 | order: 50
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.0/actions/default-error-response.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.0/actions/default-error-response.png
--------------------------------------------------------------------------------
/content/v2.0/actions/overview.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Overview
3 | order: 10
4 | aliases:
5 | - "/actions/overview"
6 | ---
7 |
8 | ## Actions
9 |
10 | In a Hanami application, actions are responsible for handling HTTP requests. Actions decide what HTTP response your application returns for a given request - its status, body, headers, whether to issue a redirect, and so on.
11 |
12 | Every action in your Hanami application is an individual class. Actions define a `#handle` method which takes two arguments: `request`, an object representing the incoming request, and `response`, an object representing the outgoing response.
13 |
14 | Modifying the response object allows you to control how your application responds to a request.
15 |
16 | ```ruby
17 | # app/actions/home/show.rb
18 |
19 | module Bookshelf
20 | module Actions
21 | module Home
22 | class Show < Bookshelf::Action
23 | def handle(request, response)
24 | name = request.params[:name]
25 |
26 | response.body = "Welcome to Bookshelf #{name}!"
27 | end
28 | end
29 | end
30 | end
31 | end
32 | ```
33 |
34 | As the code above suggests, the `request` object provides access to the parameters associated with the incoming request through a `#params` method.
35 |
36 | Let's start by taking a look at action [parameters](/v2.0/actions/parameters/).
37 |
--------------------------------------------------------------------------------
/content/v2.0/app/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: App
3 | order: 20
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.0/app/code-reloading.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Code reloading
3 | order: 90
4 | ---
5 |
6 | Hanami offers fast code reloading in development via the [hanami-reloader](https://github.com/hanami/reloader) gem.
7 |
8 | When you run `hanami server` in development, `guard` watches the file system for code edits and restarts the Hanami server when changes occur.
9 |
10 | Which directories are watched can be configured in the `Guardfile` of your project.
11 |
12 | ```ruby
13 | # Guardfile
14 |
15 | group :server do
16 | guard "puma", port: ENV["HANAMI_PORT"] || 2300 do
17 | watch(%r{config/*})
18 | watch(%r{lib/*})
19 | watch(%r{app/*})
20 | watch(%r{slices/*})
21 | end
22 | end
23 | ```
24 |
25 | Hanami takes an "outside the framework" approach to code reloading. This has several advantages:
26 |
27 | - file system watching is delegated to `guard`.
28 | - Hanami internals are free from code reloading awareness.
29 | - if the hanami-reloader gem is not present (which is true in production), code reloading logic is eliminated.
30 |
31 | Thanks to [Zeitwerk](/v2.0/app/autoloading/) and [lazy loading](/v2.0/app/booting/), code reloading is also very fast.
32 |
33 | ### Reloading in the console
34 |
35 | If you have an existing console session and make a code change, you can use your updated code via the `reload` helper:
36 |
37 | ```ruby
38 | bundle exec hanami console
39 |
40 | bookshelf[development]> reload
41 | Reloading...
42 | ```
43 |
--------------------------------------------------------------------------------
/content/v2.0/cli-commands/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: CLI commands
3 | order: 15
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.0/introduction/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | order: 10
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.0/introduction/hello-from-hanami.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.0/introduction/hello-from-hanami.png
--------------------------------------------------------------------------------
/content/v2.0/logger/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Logger
3 | order: 80
4 | ---
5 |
6 | TBD
7 |
--------------------------------------------------------------------------------
/content/v2.0/routing/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Routing
3 | order: 40
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.0/views/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Views
3 | order: 90
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.0/views/planned_for_2_1.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Planned for 2.1
3 | order: 10
4 | ---
5 |
6 | Hanami 2.0 does not yet include integrated view rendering. This is planned for the upcoming 2.1 release.
7 |
8 | In the meantime, Hanami 2.0 is well suited for JSON APIs or manual templating with the view engine of your choice through [manually setting `response.body`](/v2.0/actions/request-and-response/#response) in actions.
9 |
--------------------------------------------------------------------------------
/content/v2.1/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | version: v2.1
3 | ---
4 |
--------------------------------------------------------------------------------
/content/v2.1/actions/404-response.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.1/actions/404-response.png
--------------------------------------------------------------------------------
/content/v2.1/actions/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Actions
3 | order: 50
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.1/actions/default-error-response.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.1/actions/default-error-response.png
--------------------------------------------------------------------------------
/content/v2.1/actions/overview.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Overview
3 | order: 10
4 | aliases:
5 | - "/actions/overview"
6 | ---
7 |
8 | ## Actions
9 |
10 | In a Hanami application, actions are responsible for handling HTTP requests. Actions decide what HTTP response your application returns for a given request - its status, body, headers, whether to issue a redirect, and so on.
11 |
12 | Every action in your Hanami application is an individual class. Actions define a `#handle` method which takes two arguments: `request`, an object representing the incoming request, and `response`, an object representing the outgoing response.
13 |
14 | Modifying the response object allows you to control how your application responds to a request.
15 |
16 | ```ruby
17 | # app/actions/home/show.rb
18 |
19 | module Bookshelf
20 | module Actions
21 | module Home
22 | class Show < Bookshelf::Action
23 | def handle(request, response)
24 | name = request.params[:name]
25 |
26 | response.body = "Welcome to Bookshelf #{name}!"
27 | end
28 | end
29 | end
30 | end
31 | end
32 | ```
33 |
34 | As the code above suggests, the `request` object provides access to the parameters associated with the incoming request through a `#params` method.
35 |
36 | Let's start by taking a look at action [parameters](/v2.1/actions/parameters/).
37 |
--------------------------------------------------------------------------------
/content/v2.1/actions/rendering-views.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Rendering views
3 | order: 35
4 | ---
5 |
6 | Hanami actions are designed to work seamlessly with Hanami views, with features like automatic view rendering and support for a context object that gives views access to details like the current request.
7 |
8 | To learn more, see [Rendering from actions](/v2.1/views/rendering-from-actions/).
9 |
--------------------------------------------------------------------------------
/content/v2.1/app/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: App
3 | order: 20
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.1/app/code-reloading.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Code reloading
3 | order: 90
4 | aliases:
5 | - "/app/code-reloading"
6 | ---
7 |
8 | Hanami offers fast code reloading in development via the [hanami-reloader](https://github.com/hanami/reloader) gem.
9 |
10 | When you run `hanami server` in development, `guard` watches the file system for code edits and restarts the Hanami server when changes occur.
11 |
12 | Which directories are watched can be configured in the `Guardfile` of your project.
13 |
14 | ```ruby
15 | # Guardfile
16 |
17 | group :server do
18 | guard "puma", port: ENV["HANAMI_PORT"] || 2300 do
19 | watch(%r{config/*})
20 | watch(%r{lib/*})
21 | watch(%r{app/*})
22 | watch(%r{slices/*})
23 | end
24 | end
25 | ```
26 |
27 | Hanami takes an "outside the framework" approach to code reloading. This has several advantages:
28 |
29 | - file system watching is delegated to `guard`.
30 | - Hanami internals are free from code reloading awareness.
31 | - if the hanami-reloader gem is not present (which is true in production), code reloading logic is eliminated.
32 |
33 | Thanks to [Zeitwerk](/v2.1/app/autoloading/) and [lazy loading](/v2.1/app/booting/), code reloading is also very fast.
34 |
35 | ### Reloading in the console
36 |
37 | If you have an existing console session and make a code change, you can use your updated code via the `reload` helper:
38 |
39 | ```ruby
40 | bundle exec hanami console
41 |
42 | bookshelf[development]> reload
43 | Reloading...
44 | ```
45 |
--------------------------------------------------------------------------------
/content/v2.1/assets/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Assets
3 | order: 140
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.1/assets/customization.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Customization
3 | order: 30
4 | aliases:
5 | - "/assets/customization"
6 | ---
7 |
8 | To customize your assets compilation, update `config/assets.js` to match the following:
9 |
10 | ```js
11 | import * as assets from "hanami-assets";
12 |
13 | await assets.run({
14 | esbuildOptionsFn: (args, esbuildOptions) => {
15 | // Add to esbuildOptions here. Use `args.watch` as a condition for different options for
16 | // compile vs watch.
17 |
18 | return esbuildOptions;
19 | }
20 | });
21 | ```
22 |
23 | Inside `esbuildOptionsFn`, update `esbuildOptions` to set your own [esbuild options](https://esbuild.github.io/api/) for asset compilation. By the time this function runs, hanami-assets has set its own necessary options on `esbuildOptions`.
24 |
25 | If you want to apply different options when compiling assets (for production) versus watching assets (for development), use `args.watch` as a conditional.
26 |
27 | ```js
28 | await assets.run({
29 | esbuildOptionsFn: (args, esbuildOptions) => {
30 | if (args.watch) {
31 | // watch mode (development) options here
32 | } else {
33 | // compile mode (production) options here
34 | }
35 |
36 | return esbuildOptions;
37 | }
38 | });
39 | ```
40 |
41 | ## Slice asset customization
42 |
43 | You can customise asset compilation for an individual slice by creating a `config/assets.js` within the slice directory. This will be used in preference to the config file at the top level.
44 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: CLI commands
3 | order: 15
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/assets.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Assets
3 | order: 100
4 | ---
5 |
6 | ## hanami assets compile
7 |
8 | Compiles the app's [assets](/v2.1/actions/overview) into bundles for use in production:
9 |
10 | ```shell
11 | $ bundle exec hanami assets compile
12 | [bookshelf]
13 | [bookshelf] public/assets/app-SQ36TYM4.js 53b
14 | [bookshelf] public/assets/app-KUHJPSX7.css 45b
15 | [bookshelf] public/assets/app-KUHJPSX7.css.map 93b
16 | [bookshelf] public/assets/app-SQ36TYM4.js.map 93b
17 | [bookshelf]
18 | [bookshelf] ⚡ Done in 3ms
19 | ```
20 |
21 | ## hanami assets watch
22 |
23 | Watches for changes to your assets and compiles the relevant files immediately. This is a long-running command, and is run by [hanami dev](/v2.1/commands/dev) by default.
24 |
25 | ```shell
26 | $ bundle exec hanami assets watch
27 | [bookshelf] [watch] build finished, watching for changes...
28 | [bookshelf] [watch] build started (change: "app/assets/js/app.js")
29 | [bookshelf] [watch] build finished
30 | [bookshelf] [watch] build started (change: "app/assets/css/app.css")
31 | [bookshelf] [watch] build finished
32 | ```
33 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/commands.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Commands
3 | order: 10
4 | ---
5 |
6 | Hanami provides a command line interface with helpful commands for generating a new application, starting a console, starting a development server, displaying routes and more.
7 |
8 | ## Gem commands
9 |
10 | After an initial install via `gem install hanami`, hanami offers two commands:
11 |
12 | ```shell
13 | $ hanami --help
14 |
15 | Commands:
16 | hanami new APP # Generate a new Hanami app
17 | hanami version # Hanami version
18 | ```
19 |
20 | ## App commands
21 |
22 | When executed from within a Hanami app, hanami offers a different set of commands.
23 |
24 | These commands can be listed using the `--help` flag.
25 |
26 | ```shell
27 | $ bundle exec hanami --help
28 | Commands:
29 | hanami assets [SUBCOMMAND]
30 | hanami console # Start app console (REPL)
31 | hanami dev # Start the application in development mode
32 | hanami generate [SUBCOMMAND]
33 | hanami install # Install Hanami third-party plugins
34 | hanami middleware # Print app Rack middleware stack
35 | hanami routes # Print app routes
36 | hanami server # Start Hanami app server
37 | hanami version # Print Hanami app version
38 | ```
39 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/console.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Console
3 | order: 40
4 | ---
5 |
6 | ## hanami console
7 |
8 | Starts the Hanami console (REPL).
9 |
10 | ```shell
11 | $ bundle exec hanami console
12 |
13 | bookshelf[development]>
14 | ```
15 |
16 | This command accepts an `engine` argument that can start the console using IRB or Pry.
17 |
18 | ```shell
19 | $ bundle exec hanami console --engine=irb # (the default)
20 | $ bundle exec hanami console --engine=pry
21 | ```
22 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/dev.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Dev
3 | order: 60
4 | ---
5 |
6 | ## hanami dev
7 |
8 | Starts Hanami application in development mode.
9 |
10 | ```shell
11 | $ bundle exec hanami dev
12 | ```
13 |
14 | ### Procfile.dev
15 |
16 | Starting from Hanami 2.1, new apps have a `Procfile.dev`, where developers can manage the processes that should be managed by `hanami dev`.
17 |
18 | Those are the default contents:
19 |
20 | ```shell
21 | web: bundle exec hanami server
22 | assets: bundle exec hanami assets watch
23 | ```
24 |
25 | ### bin/dev
26 |
27 | By default Hanami 2.1+, installs the `foreman` Ruby gem to run the `Procfile.dev`.
28 |
29 | In case you want use a different process manager, edit application's `bin/dev`.
30 |
31 | Example that uses [shoreman](https://github.com/chrismytton/shoreman), instead of `foreman`:
32 |
33 | ```shell
34 | #!/usr/bin/env sh
35 | shoreman Procfile.dev
36 | ```
37 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/generate.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Generate
3 | order: 90
4 | ---
5 |
6 | ## hanami generate
7 |
8 | Hanami 2.1 provides a few generators:
9 |
10 | ```shell
11 | $ bundle exec hanami generate --help
12 | Commands:
13 | hanami generate action NAME
14 | hanami generate part NAME
15 | hanami generate slice NAME
16 | hanami generate view NAME
17 | ```
18 |
19 | ### hanami generate action
20 |
21 | Generates an [action](/v2.1/actions/overview):
22 |
23 | ```shell
24 | $ bundle exec hanami generate action books.show
25 | ```
26 |
27 | Use the `--help` option to access all accepted options:
28 |
29 | ```shell
30 | $ bundle exec hanami generate action --help
31 | ```
32 |
33 | ### hanami generate part
34 |
35 | Generates a view [part](/v2.1/views/parts/):
36 |
37 | ```shell
38 | $ bundle exec hanami generate part book
39 | ```
40 |
41 | Use the `--help` option to access all accepted options:
42 |
43 | ```shell
44 | $ bundle exec hanami generate part --help
45 | ```
46 |
47 | ### hanami generate slice
48 |
49 | Generates a [slice](/v2.1/app/slices/):
50 |
51 | ```shell
52 | $ bundle exec hanami generate slice admin
53 | ```
54 |
55 | Use the `--help` option to access all accepted options:
56 |
57 | ```shell
58 | $ bundle exec hanami generate slice --help
59 | ```
60 |
61 | ### hanami generate view
62 |
63 | Generates a [view](/v2.1/views/overview/):
64 |
65 | ```shell
66 | $ bundle exec hanami generate view books.create
67 | ```
68 |
69 | Use the `--help` option to access all accepted options:
70 |
71 | ```shell
72 | $ bundle exec hanami generate view --help
73 | ```
74 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/install.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Install
3 | order: 30
4 | ---
5 |
6 | ## hanami install
7 |
8 | This command installs third-party dependencies (Ruby gems, NPM packages) and setups additional Hanami gems that provide code reloading, rspec, integrations.
9 |
10 |
11 | This command is executed automatically by hanami new. In case you'll run into third-party dependency problems, execute it.
12 |
13 |
14 | ```shell
15 | $ bundle exec hanami install
16 | ```
17 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/middleware.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Middleware
3 | order: 80
4 | ---
5 |
6 | ## hanami middleware
7 |
8 | Displays the Rack middleware stack as currently configured.
9 |
10 | ```shell
11 | $ bundle exec hanami middleware
12 |
13 | / Dry::Monitor::Rack::Middleware (instance)
14 | / Rack::Session::Cookie
15 | / Hanami::Middleware::BodyParser
16 | ```
17 |
18 | This command accepts a `--with-arguments` option that will include initialization arguments:
19 |
20 | ```shell
21 | $ bundle exec hanami middleware --with-arguments
22 |
23 | / Dry::Monitor::Rack::Middleware (instance) args: []
24 | / Rack::Session::Cookie args: [{:key=>"my_app.session", :secret=>"secret", :expire_after=>31536000}]
25 | / Hanami::Middleware::BodyParser args: [:json]
26 | ```
27 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/new.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: New
3 | order: 20
4 | ---
5 |
6 | ## hanami new
7 |
8 | Generates a Hanami application with the given APP name, in a new directory from the current location.
9 |
10 | ```shell
11 | $ hanami new bookshelf # generates a new Bookshelf application in ./bookshelf
12 | $ hanami new my_app # generates a new MyApp application in ./my_app
13 | ```
14 |
15 | On the application generation, Hanami performs gem bundling, NPM bundling, and general application setup.
16 |
17 | ### Using Hanami HEAD
18 |
19 | In case you're interested to debug a Hanami issue, you can generate an application that uses the HEAD version of Hanami, directly from the `main` branches of the GitHub repositories.
20 |
21 | ```shell
22 | $ hanami new bookshelf --head
23 | ```
24 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/routes.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Routes
3 | order: 70
4 | ---
5 |
6 | ## hanami routes
7 |
8 | Displays your application's routes.
9 |
10 | ```shell
11 | $ bundle exec hanami routes
12 |
13 | GET / home.index as :root
14 | GET /books books.index
15 | GET /books/:id books.show
16 | POST /books books.create
17 | ```
18 |
19 | By default, routes are displayed in "human friendly" format. Routes can be inspected in csv format via the format option:
20 |
21 | ```shell
22 | $ bundle exec hanami routes --format=csv
23 |
24 | METHOD,PATH,TO,AS,CONSTRAINTS
25 | GET,/,home.index,:root,""
26 | GET,/books,books.index,"",""
27 | GET,/books/:id,books.show,"",""
28 | POST,/books,books.create,"",""
29 | ```
30 |
--------------------------------------------------------------------------------
/content/v2.1/cli-commands/version.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Version
3 | order: 110
4 | ---
5 |
6 | ## hanami version
7 |
8 | Prints the version of the Hanami version used by the application:
9 |
10 | ```shell
11 | $ bundle exec hanami version
12 | v2.1.0
13 | ```
14 |
--------------------------------------------------------------------------------
/content/v2.1/helpers/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Helpers
3 | order: 130
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.1/helpers/overview.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Overview
3 | order: 10
4 | ---
5 |
6 | Hanami provides a range of standard helpers for you to use in your views.
7 |
8 | You can read more about where helpers fit within your views in the [view helpers guide](/v2.1/views/helpers/).
9 |
10 | To learn more about Hanami's standard helpers, read the sections within this guide.
11 |
--------------------------------------------------------------------------------
/content/v2.1/introduction/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | order: 10
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.1/introduction/hanami-welcome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.1/introduction/hanami-welcome.png
--------------------------------------------------------------------------------
/content/v2.1/logger/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Logger
3 | order: 80
4 | ---
5 |
6 | TBD
7 |
--------------------------------------------------------------------------------
/content/v2.1/routing/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Routing
3 | order: 40
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.1/upgrade-notes/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Upgrade notes
3 | order: 170
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.1/views/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Views
3 | order: 75
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.1/views/configuration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Configuration
3 | order: 100
4 | ---
5 |
6 | Forthcoming.
7 |
--------------------------------------------------------------------------------
/content/v2.1/views/rendering-errors.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Rendering errors
3 | order: 90
4 | ---
5 |
6 | When running your app in production mode, error views will be rendered for any uncaught exceptions. This allows you to present a helpful error screen to your users while also hiding any technical details of the error.
7 |
8 | These error views are static HTML only. You can find them in your app's `public/` directory, at `404.html` and `500.html`.
9 |
10 | You can customize these views however you wish, though you should be mindful to keep their content static and self-contained to the HTML file as much as possible.
11 |
12 | ## Customizing error views
13 |
14 | You can enable or disable these error views using the `config.render_errors` app setting. This defaults to `true` when your app is in production mode, and `false` for all other modes.
15 |
16 | To configure which error views show for which exceptions, use the `config.render_error_responses` setting. This is a hash that maps string representations of Ruby exception classes to the symbolized form (downcased, underscored) of [Rack's list of HTTP error names](https://github.com/rack/rack/blob/f6c583adb0e863e524bacedaf594602964e01078/lib/rack/utils.rb#L469-L538). These names are then mapped to the equivalent status codes and used to locate the HTML files in `public/`.
17 |
18 | ```ruby
19 | # config/app.rb
20 |
21 | module Bookshelf
22 | class App < Hanami::App
23 | config.render_error_responses.merge!(
24 | "ROM::TupleCountMismatchError" => :not_found
25 | )
26 | end
27 | end
28 | ```
29 |
--------------------------------------------------------------------------------
/content/v2.1/views/welcome-to-bookshelf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.1/views/welcome-to-bookshelf.png
--------------------------------------------------------------------------------
/content/v2.1/views/working-with-dependencies.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Working with dependencies
3 | order: 10
4 | ---
5 |
6 | Hanami views are designed to work with dependencies from across your app. Using dependencies is how your view can retrieve the values it needs to include in its template.
7 |
8 | To include dependencies, use the Deps mixin:
9 |
10 | ```ruby
11 | # app/views/books/show.rb
12 |
13 | module Bookshelf
14 | module Views
15 | module Books
16 | class Show < Bookshelf::View
17 | include Deps["repositories.book_repo"]
18 |
19 | expose :book do |id:|
20 | book_repo.get!(id)
21 | end
22 | end
23 | end
24 | end
25 | end
26 | ```
27 |
28 | From here, you can use these dependencies within your [exposures](/v2.1/views/input-and-exposures/).
29 |
--------------------------------------------------------------------------------
/content/v2.2/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | version: v2.2
3 | ---
4 |
--------------------------------------------------------------------------------
/content/v2.2/actions/404-response.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.2/actions/404-response.png
--------------------------------------------------------------------------------
/content/v2.2/actions/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Actions
3 | order: 50
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/actions/default-error-response.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.2/actions/default-error-response.png
--------------------------------------------------------------------------------
/content/v2.2/actions/overview.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Overview
3 | order: 10
4 | ---
5 |
6 | ## Actions
7 |
8 | In a Hanami application, actions are responsible for handling HTTP requests. Actions decide what HTTP response your application returns for a given request - its status, body, headers, whether to issue a redirect, and so on.
9 |
10 | Every action in your Hanami application is an individual class. Actions define a `#handle` method which takes two arguments: `request`, an object representing the incoming request, and `response`, an object representing the outgoing response.
11 |
12 | Modifying the response object allows you to control how your application responds to a request.
13 |
14 | ```ruby
15 | # app/actions/home/show.rb
16 |
17 | module Bookshelf
18 | module Actions
19 | module Home
20 | class Show < Bookshelf::Action
21 | def handle(request, response)
22 | name = request.params[:name]
23 |
24 | response.body = "Welcome to Bookshelf #{name}!"
25 | end
26 | end
27 | end
28 | end
29 | end
30 | ```
31 |
32 | As the code above suggests, the `request` object provides access to the parameters associated with the incoming request through a `#params` method.
33 |
34 | Let's start by taking a look at action [parameters](/v2.2/actions/parameters/).
35 |
--------------------------------------------------------------------------------
/content/v2.2/actions/rendering-views.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Rendering views
3 | order: 35
4 | ---
5 |
6 | Hanami actions are designed to work seamlessly with Hanami views, with features like automatic view rendering and support for a context object that gives views access to details like the current request.
7 |
8 | To learn more, see [Rendering from actions](/v2.2/views/rendering-from-actions/).
9 |
--------------------------------------------------------------------------------
/content/v2.2/app/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: App
3 | order: 20
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/app/code-reloading.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Code reloading
3 | order: 90
4 | ---
5 |
6 | Hanami offers fast code reloading in development via the [hanami-reloader](https://github.com/hanami/reloader) gem.
7 |
8 | When you run `hanami server` in development, `guard` watches the file system for code edits and restarts the Hanami server when changes occur.
9 |
10 | Which directories are watched can be configured in the `Guardfile` of your project.
11 |
12 | ```ruby
13 | # Guardfile
14 |
15 | group :server do
16 | guard "puma", port: ENV["HANAMI_PORT"] || 2300 do
17 | watch(%r{config/*})
18 | watch(%r{lib/*})
19 | watch(%r{app/*})
20 | watch(%r{slices/*})
21 | end
22 | end
23 | ```
24 |
25 | Hanami takes an "outside the framework" approach to code reloading. This has several advantages:
26 |
27 | - file system watching is delegated to `guard`.
28 | - Hanami internals are free from code reloading awareness.
29 | - if the hanami-reloader gem is not present (which is true in production), code reloading logic is eliminated.
30 |
31 | Thanks to [Zeitwerk](/v2.2/app/autoloading/) and [lazy loading](/v2.2/app/booting/), code reloading is also very fast.
32 |
33 | ### Reloading in the console
34 |
35 | If you have an existing console session and make a code change, you can use your updated code via the `reload` helper:
36 |
37 | ```ruby
38 | bundle exec hanami console
39 |
40 | bookshelf[development]> reload
41 | Reloading...
42 | ```
43 |
--------------------------------------------------------------------------------
/content/v2.2/assets/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Assets
3 | order: 140
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/assets/customization.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Customization
3 | order: 30
4 | ---
5 |
6 | To customize your assets compilation, update `config/assets.js` to match the following:
7 |
8 | ```js
9 | import * as assets from "hanami-assets";
10 |
11 | await assets.run({
12 | esbuildOptionsFn: (args, esbuildOptions) => {
13 | // Add to esbuildOptions here. Use `args.watch` as a condition for different options for
14 | // compile vs watch.
15 |
16 | return esbuildOptions;
17 | }
18 | });
19 | ```
20 |
21 | Inside `esbuildOptionsFn`, update `esbuildOptions` to set your own [esbuild options](https://esbuild.github.io/api/) for asset compilation. By the time this function runs, hanami-assets has set its own necessary options on `esbuildOptions`.
22 |
23 | If you want to apply different options when compiling assets (for production) versus watching assets (for development), use `args.watch` as a conditional.
24 |
25 | ```js
26 | await assets.run({
27 | esbuildOptionsFn: (args, esbuildOptions) => {
28 | if (args.watch) {
29 | // watch mode (development) options here
30 | } else {
31 | // compile mode (production) options here
32 | }
33 |
34 | return esbuildOptions;
35 | }
36 | });
37 | ```
38 |
39 | ## Slice asset customization
40 |
41 | You can customise asset compilation for an individual slice by creating a `config/assets.js` within the slice directory. This will be used in preference to the config file at the top level.
42 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: CLI commands
3 | order: 15
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/assets.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Assets
3 | order: 110
4 | ---
5 |
6 | ## hanami assets compile
7 |
8 | Compiles the app's [assets](/v2.2/actions/overview) into bundles for use in production:
9 |
10 | ```shell
11 | $ bundle exec hanami assets compile
12 | [bookshelf]
13 | [bookshelf] public/assets/app-SQ36TYM4.js 53b
14 | [bookshelf] public/assets/app-KUHJPSX7.css 45b
15 | [bookshelf] public/assets/app-KUHJPSX7.css.map 93b
16 | [bookshelf] public/assets/app-SQ36TYM4.js.map 93b
17 | [bookshelf]
18 | [bookshelf] ⚡ Done in 3ms
19 | ```
20 |
21 | ## hanami assets watch
22 |
23 | Watches for changes to your assets and compiles the relevant files immediately. This is a long-running command, and is run by [hanami dev](/v2.2/commands/dev) by default.
24 |
25 | ```shell
26 | $ bundle exec hanami assets watch
27 | [bookshelf] [watch] build finished, watching for changes...
28 | [bookshelf] [watch] build started (change: "app/assets/js/app.js")
29 | [bookshelf] [watch] build finished
30 | [bookshelf] [watch] build started (change: "app/assets/css/app.css")
31 | [bookshelf] [watch] build finished
32 | ```
33 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/commands.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Commands
3 | order: 10
4 | ---
5 |
6 | Hanami provides a command line interface with helpful commands for generating a new application, starting a console, starting a development server, displaying routes and more.
7 |
8 | ## Gem commands
9 |
10 | After an initial install via `gem install hanami`, hanami offers two commands:
11 |
12 | ```shell
13 | $ hanami --help
14 |
15 | Commands:
16 | hanami new APP # Generate a new Hanami app
17 | hanami version # Hanami version
18 | ```
19 |
20 | ## App commands
21 |
22 | When executed from within a Hanami app, hanami offers a different set of commands.
23 |
24 | These commands can be listed using the `--help` flag.
25 |
26 | ```shell
27 | $ bundle exec hanami --help
28 | Commands:
29 | hanami assets [SUBCOMMAND]
30 | hanami console # Start app console (REPL)
31 | hanami db [SUBCOMMAND]
32 | hanami dev # Start the application in development mode
33 | hanami generate [SUBCOMMAND]
34 | hanami install # Install Hanami third-party plugins
35 | hanami middleware # Print app Rack middleware stack
36 | hanami routes # Print app routes
37 | hanami server # Start Hanami app server
38 | hanami version # Print Hanami app version
39 | ```
40 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/console.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Console
3 | order: 40
4 | ---
5 |
6 | ## hanami console
7 |
8 | Starts the Hanami console (REPL).
9 |
10 | ```shell
11 | $ bundle exec hanami console
12 |
13 | bookshelf[development]>
14 | ```
15 |
16 | This command accepts an `engine` argument that can start the console using IRB or Pry.
17 |
18 | ```shell
19 | $ bundle exec hanami console --engine=irb # (the default)
20 | $ bundle exec hanami console --engine=pry
21 | ```
22 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/dev.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Dev
3 | order: 60
4 | ---
5 |
6 | ## hanami dev
7 |
8 | Starts Hanami application in development mode.
9 |
10 | ```shell
11 | $ bundle exec hanami dev
12 | ```
13 |
14 | ### Procfile.dev
15 |
16 | Starting from Hanami 2.1, new apps have a `Procfile.dev`, where developers can manage the processes that should be managed by `hanami dev`.
17 |
18 | Those are the default contents:
19 |
20 | ```shell
21 | web: bundle exec hanami server
22 | assets: bundle exec hanami assets watch
23 | ```
24 |
25 | ### bin/dev
26 |
27 | By default Hanami 2.1+, installs the `foreman` Ruby gem to run the `Procfile.dev`.
28 |
29 | In case you want use a different process manager, edit application's `bin/dev`.
30 |
31 | Example that uses [shoreman](https://github.com/chrismytton/shoreman), instead of `foreman`:
32 |
33 | ```shell
34 | #!/usr/bin/env sh
35 | shoreman Procfile.dev
36 | ```
37 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/install.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Install
3 | order: 30
4 | ---
5 |
6 | ## hanami install
7 |
8 | This command installs third-party dependencies (Ruby gems, NPM packages) and setups additional Hanami gems that provide code reloading, rspec, integrations.
9 |
10 |
11 | This command is executed automatically by hanami new. In case you'll run into third-party dependency problems, execute it.
12 |
13 |
14 | ```shell
15 | $ bundle exec hanami install
16 | ```
17 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/middleware.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Middleware
3 | order: 100
4 | ---
5 |
6 | ## hanami middleware
7 |
8 | Displays the Rack middleware stack as currently configured.
9 |
10 | ```shell
11 | $ bundle exec hanami middleware
12 |
13 | / Dry::Monitor::Rack::Middleware (instance)
14 | / Rack::Session::Cookie
15 | / Hanami::Middleware::BodyParser
16 | ```
17 |
18 | This command accepts a `--with-arguments` option that will include initialization arguments:
19 |
20 | ```shell
21 | $ bundle exec hanami middleware --with-arguments
22 |
23 | / Dry::Monitor::Rack::Middleware (instance) args: []
24 | / Rack::Session::Cookie args: [{:key=>"my_app.session", :secret=>"secret", :expire_after=>31536000}]
25 | / Hanami::Middleware::BodyParser args: [:json]
26 | ```
27 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/new.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: New
3 | order: 20
4 | ---
5 |
6 | ## hanami new
7 |
8 | Generates a Hanami application with the given APP name, in a new directory from the current location.
9 |
10 | ```shell
11 | $ hanami new bookshelf # generates a new Bookshelf application in ./bookshelf
12 | $ hanami new my_app # generates a new MyApp application in ./my_app
13 | ```
14 |
15 | On the application generation, Hanami performs gem bundling, NPM bundling, and general application setup.
16 |
17 | ### Using Hanami HEAD
18 |
19 | In case you're interested to debug a Hanami issue, you can generate an application that uses the HEAD version of Hanami, directly from the `main` branches of the GitHub repositories.
20 |
21 | ```shell
22 | $ hanami new bookshelf --head
23 | ```
24 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/routes.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Routes
3 | order: 90
4 | ---
5 |
6 | ## hanami routes
7 |
8 | Displays your application's routes.
9 |
10 | ```shell
11 | $ bundle exec hanami routes
12 |
13 | GET / home.index as :root
14 | GET /books books.index
15 | GET /books/:id books.show
16 | POST /books books.create
17 | ```
18 |
19 | By default, routes are displayed in "human friendly" format. Routes can be inspected in csv format via the format option:
20 |
21 | ```shell
22 | $ bundle exec hanami routes --format=csv
23 |
24 | METHOD,PATH,TO,AS,CONSTRAINTS
25 | GET,/,home.index,:root,""
26 | GET,/books,books.index,"",""
27 | GET,/books/:id,books.show,"",""
28 | POST,/books,books.create,"",""
29 | ```
30 |
--------------------------------------------------------------------------------
/content/v2.2/cli-commands/version.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Version
3 | order: 120
4 | ---
5 |
6 | ## hanami version
7 |
8 | Prints the version of the Hanami version used by the application:
9 |
10 | ```shell
11 | $ bundle exec hanami version
12 | v2.2.0
13 | ```
14 |
--------------------------------------------------------------------------------
/content/v2.2/database/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Database
3 | order: 30
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/helpers/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Helpers
3 | order: 130
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/helpers/overview.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Overview
3 | order: 10
4 | ---
5 |
6 | Hanami provides a range of standard helpers for you to use in your views.
7 |
8 | You can read more about where helpers fit within your views in the [view helpers guide](/v2.2/views/helpers/).
9 |
10 | To learn more about Hanami's standard helpers, read the sections within this guide.
11 |
--------------------------------------------------------------------------------
/content/v2.2/introduction/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | order: 10
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/introduction/hanami-welcome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.2/introduction/hanami-welcome.png
--------------------------------------------------------------------------------
/content/v2.2/logger/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Logger
3 | order: 80
4 | ---
5 |
6 | TBD
7 |
--------------------------------------------------------------------------------
/content/v2.2/operations/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Operations
3 | order: 70
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/routing/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Routing
3 | order: 40
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/upgrade-notes/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Upgrade notes
3 | order: 170
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/views/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Views
3 | order: 75
4 | ---
5 |
--------------------------------------------------------------------------------
/content/v2.2/views/configuration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Configuration
3 | order: 100
4 | ---
5 |
6 | Forthcoming.
7 |
--------------------------------------------------------------------------------
/content/v2.2/views/rendering-errors.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Rendering errors
3 | order: 90
4 | ---
5 |
6 | When running your app in production mode, error views will be rendered for any uncaught exceptions. This allows you to present a helpful error screen to your users while also hiding any technical details of the error.
7 |
8 | These error views are static HTML only. You can find them in your app's `public/` directory, at `404.html` and `500.html`.
9 |
10 | You can customize these views however you wish, though you should be mindful to keep their content static and self-contained to the HTML file as much as possible.
11 |
12 | ## Customizing error views
13 |
14 | You can enable or disable these error views using the `config.render_errors` app setting. This defaults to `true` when your app is in production mode, and `false` for all other modes.
15 |
16 | To configure which error views show for which exceptions, use the `config.render_error_responses` setting. This is a hash that maps string representations of Ruby exception classes to the symbolized form (downcased, underscored) of [Rack's list of HTTP error names](https://github.com/rack/rack/blob/f6c583adb0e863e524bacedaf594602964e01078/lib/rack/utils.rb#L469-L538). These names are then mapped to the equivalent status codes and used to locate the HTML files in `public/`.
17 |
18 | ```ruby
19 | # config/app.rb
20 |
21 | module Bookshelf
22 | class App < Hanami::App
23 | config.render_error_responses.merge!(
24 | "ROM::TupleCountMismatchError" => :not_found
25 | )
26 | end
27 | end
28 | ```
29 |
--------------------------------------------------------------------------------
/content/v2.2/views/welcome-to-bookshelf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/content/v2.2/views/welcome-to-bookshelf.png
--------------------------------------------------------------------------------
/content/v2.2/views/working-with-dependencies.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Working with dependencies
3 | order: 10
4 | ---
5 |
6 | Hanami views are designed to work with dependencies from across your app. Using dependencies is how your view can retrieve the values it needs to include in its template.
7 |
8 | To include dependencies, use the Deps mixin:
9 |
10 | ```ruby
11 | # app/views/books/show.rb
12 |
13 | module Bookshelf
14 | module Views
15 | module Books
16 | class Show < Bookshelf::View
17 | include Deps["repos.book_repo"]
18 |
19 | expose :book do |id:|
20 | book_repo.get!(id)
21 | end
22 | end
23 | end
24 | end
25 | end
26 | ```
27 |
28 | From here, you can use these dependencies within your [exposures](/v2.2/views/input-and-exposures/).
29 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build.environment]
2 | HUGO_VERSION = "v0.92.2"
3 |
--------------------------------------------------------------------------------
/themes/hanami/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 YOUR_NAME_HERE
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/themes/hanami/archetypes/default.md:
--------------------------------------------------------------------------------
1 | +++
2 | +++
3 |
--------------------------------------------------------------------------------
/themes/hanami/layouts/404.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanami/guides/3266c204d76adb5b112e43a789ec5b83bf3105c8/themes/hanami/layouts/404.html
--------------------------------------------------------------------------------
/themes/hanami/layouts/_default/baseof.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{- partial "head.html" . -}}
4 |