# Walter [![Build Status](https://travis-ci.com/actmd/walter.svg?branch=master)](https://travis-ci.com/actmd/walter)

Product tours like a badass.

Walter White icon by Icons8

Walter makes it easy to show guided tours to users of your Rails application. When Walter shows a tour, it keeps track of whether the user has completed it (so it doesn't get shown again) or dismissed it for later (so it reappears in a future user session). * Define tour content with simple YAML files, in any/many languages. * Organize tours by controller and action. * Trigger tours automatically on page load or manually via JavaScript method. * Built with the [Shepherd JS](https://shepherdjs.dev/) library. Plays nicely with Turbolinks. * Ships with two basic CSS themes (default & dark) — or write your own * Show video/html content in your ## Requirements * Walter needs to know the current user to track tour views, e.g. `current_user` from Devise. * Walter is tested on Rails 5.2, 6.0, and 6.1 ## Installation Add `walter` to your Gemfile: ``` gem 'walter' ``` Install the gem and run the installer: ``` $ bundle install $ rails generate walter:install $ rails db:migrate ``` Install the JavaScript dependencies: ``` $ yarn add js-cookie@^2.2.0 shepherd.js@^6.0.0-beta ``` Require `walter` in `app/assets/javascripts/application.js` ``` //= require walter ``` Require a CSS theme in `app/assets/stylesheets/application.scss` ``` *= require walter/theme-default ``` Walter provides the following themes: - `theme-default` - `theme-dark` Update `config/walter.yml` if you choose a different theme: ``` defaults: &defaults :tour_options: '{ defaultStepOptions: { classes: "theme-dark" } }' ``` You can also [write your own Shepherd theme](https://shepherdjs.dev/docs/tutorial-03-styling.html) based on Shepherd's [default CSS](https://github.com/shipshapecode/shepherd/releases/download/v6.0.0-beta.1/shepherd.css). Tell Walter where to insert its generated JavaScript in `app/views/layouts/application.html.erb`, just before the closing `body` tag: ```erb <%= walter_tour %> ``` ## Defining your tours Define your tours in the `app/tours` directory corresponding to the views defined in your application. Its directory structure mirrors your application's controllers, and the tour files mirror your actions/views. (As of version 2.4.0, Walter respects controllers organized into modules.) ``` app/ └── tours/ ├── admin/ │ └── articles/ │ └── edit.en.yml ├── blog/ │ ├── show.en.yml │ └── show.es.yml └── articles/ ├── index.en.yml ├── index.es.yml ├── show.en.yml └── show.es.yml ``` For example, per above, when a Spanish-speaking user visits `/articles/`, they'll see the tours defined by `config/tours/articles/index.es.yml`. (Note: You must specify a locale in the filename, even if you're only supporting one language.) ### Tour content Within a tour file, each tour is composed of a series of **steps**. A step may have a `title` and must have `text`. You may attach a step to a particular element on the page, and place the callout in a particular position. In this example, we define a tour called "intro" with 3 steps: ```yaml intro: steps: 1: text: "Welcome to your dashboard! This is where we'll highlight key information to manage your day." 2: title: "Events" text: "If you're participating in any events today, we'll show that here." attachTo: element: ".dashboard-events" placement: "right" 3: title: "Search" text: "You can find anything else by using the search bar." attachTo: element: ".navbar-primary form" placement: "bottom" ``` Walter takes care of which buttons should appear with each step: * "Later" and "Continue" buttons on the first step * "Exit", "Back" and "Continue" buttons on intermediate steps * "Done" button on the last step When you specify an `attachTo` element, use the `placement` option to choose where the callout should appear relative to that element: * `bottom` / `bottom center` * `bottom left` * `bottom right` * `center` / `middle` / `middle center` * `left` / `middle left` * `right` / `middle right` * `top` / `top center` * `top left` * `top right` Walter tries to be helpful when your tour steps attach to page elements that are missing: * If your first step is attached to a particular element, and that element is not present on the page, the tour won't start. ([#28](https://github.com/actmd/walter/issues/28)) * If your tour has an intermediate step attached to a missing element, Walter will skip that step and automatically show the next. ([#6](https://github.com/actmd/walter/issues/6)) ### Automatic vs. manual tours By default, Walter will automatically start a tour that the current user hasn't seen yet. You can instead define a tour to be triggered manually using the `trigger` option: ```yml walkthrough: trigger: "manual" steps: 1: text: "This walkthrough will show you how to..." ``` This tour will not start automatically; instead, use the `Walter.startTour` method with the tour name: ``` ``` ...or if you happen to use jQuery: ``` ``` ### Testing your tours Walter loads tour definitions once when you start your server. Restart your server to see tour changes. If you'd like to run JavaScript integrations tests without the Walter tours getting in the way, clear the Walter configuration in your test helper, e.g. ``` Rails.application.configure do config.walter.tours = {} end ```