{"id":13462981,"url":"https://github.com/glebm/rails_email_preview","last_synced_at":"2025-04-10T17:15:58.621Z","repository":{"id":2343939,"uuid":"3306375","full_name":"glebm/rails_email_preview","owner":"glebm","description":"Preview and edit app mailer templates in Rails.","archived":false,"fork":false,"pushed_at":"2025-03-08T02:54:57.000Z","size":1542,"stargazers_count":567,"open_issues_count":7,"forks_count":68,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-04-03T09:04:38.971Z","etag":null,"topics":["email-preview","mailer-previews","rails","rails-engine","ruby"],"latest_commit_sha":null,"homepage":"http://glebm.github.io/rails_email_preview","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/glebm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"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":"2012-01-30T16:11:31.000Z","updated_at":"2025-03-08T20:46:32.000Z","dependencies_parsed_at":"2024-09-22T00:01:07.980Z","dependency_job_id":null,"html_url":"https://github.com/glebm/rails_email_preview","commit_stats":{"total_commits":383,"total_committers":26,"mean_commits":14.73076923076923,"dds":"0.12271540469973885","last_synced_commit":"a446fc651c09979aa7d40b56e2afc68c22e6f074"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glebm%2Frails_email_preview","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glebm%2Frails_email_preview/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glebm%2Frails_email_preview/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glebm%2Frails_email_preview/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/glebm","download_url":"https://codeload.github.com/glebm/rails_email_preview/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248261917,"owners_count":21074225,"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","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":["email-preview","mailer-previews","rails","rails-engine","ruby"],"created_at":"2024-07-31T13:00:43.277Z","updated_at":"2025-04-10T17:15:58.489Z","avatar_url":"https://github.com/glebm.png","language":"Ruby","funding_links":[],"categories":["Communication","Ruby"],"sub_categories":["E-Mail Preview"],"readme":"# Rails Email Preview [![Build Status][badge-ci]][ci] [![Test Coverage][coverage-badge]][coverage] [![Code Climate][codeclimate-badge]][codeclimate] [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/glebm/rails_email_preview?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nPreview email in the browser with this Rails engine. Compatible with Rails 6.1+.\n\nAn email review:\n\n![screenshot][rep-show-screenshot]\n\nThe list of all email previews:\n\n![screenshot][rep-nav-screenshot]\n\nREP comes with two themes: a simple standalone theme, and a theme that uses [Bootstrap 3][rep-show-default-screenshot].\n\n## Installation\n\nAdd [![Gem Version][gem-badge]][gem] to Gemfile:\n\n```ruby\ngem 'rails_email_preview', '~\u003e 2.2.3'\n```\n\nAdd an initializer and the routes:\n\n```console\n$ rails g rails_email_preview:install\n```\n\nGenerate preview classes and method stubs in app/mailer_previews/\n\n```console\n$ rails g rails_email_preview:update_previews\n```\n\n## Usage\n\nThe last generator above will add a stub for each of your emails, then you populate the stubs with mock data:\n\n```ruby\n# app/mailer_previews/user_mailer_preview.rb:\nclass UserMailerPreview\n  # preview methods should return Mail objects, e.g.:\n  def invitation\n    UserMailer.invitation mock_user('Alice'), mock_user('Bob')\n  end\n\n  def welcome\n    UserMailer.welcome mock_user\n  end\n\n  private\n  # You can put all your mock helpers in a module\n  # or you can use your factories / fabricators, just make sure you are not creating anything\n  def mock_user(name = 'Bill Gates')\n    fake_id User.new(name: name, email: \"user#{rand 100}@test.com\")\n  end\n\n  def fake_id(obj)\n    # overrides the method on just this object\n    obj.define_singleton_method(:id) { 123 + rand(100) }\n    obj\n  end\nend\n```\n\n### Parameters as instance variables\n\nAll parameters in the search query will be available to the preview class as instance variables.\nFor example, if URL to mailer preview looks like:\n\n/emails/user_mailer_preview-welcome?**user_id=1**\n\nThe method `welcome` in `UserMailerPreview` have a `@user_id` instance variable defined:\n\n```ruby\nclass UserMailerPreview\n  def welcome\n    user = @user_id ? User.find(@user_id) : mock_user\n    UserMailer.welcome(user)\n  end\nend\n```\n\nNow you can preview or send the welcome email to a specific user.\n\n### Routing\n\nYou can access REP urls like this:\n\n```ruby\n# engine root:\nrails_email_preview.rep_root_url\n# list of emails (same as root):\nrails_email_preview.rep_emails_url\n# email show:\nrails_email_preview.rep_email_url('user_mailer-welcome')\n```\n\n### Sending Emails\n\nYou can send emails via REP. This is especially useful when testing with limited clients (Blackberry, Outlook, etc.).\nThis will use the environment's mailer settings, but the handler will `perform_deliveries`.\nUncomment this line in the initializer to disable sending test emails:\n\n```ruby\nconfig.enable_send_email = false\n```\n\n### Editing Emails\n\nEmails can be stored in the database and edited in the browser.\nREP works with [Comfortable Mexican Sofa CMS](https://github.com/comfy/comfortable-mexican-sofa) to achieve this -- see the [CMS Guide](https://github.com/glebm/rails_email_preview/wiki/Edit-Emails-with-Comfortable-Mexican-Sofa) to learn more.\n\n[![screenshot](https://raw.github.com/glebm/rails_email_preview/master/doc/img/rep-edit-sofa.png)](https://github.com/glebm/rails_email_preview/wiki/Edit-Emails-with-Comfortable-Mexican-Sofa)\n\n### CSS inlining\n\nFor CSS inlining, REP supports [Roadie](https://github.com/Mange/roadie) and\n[Premailer](https://github.com/alexdunae/premailer).\nBoth of these automatically translate CSS rules into inline styles and turn\nrelative URLs into absolute ones.\n\nRoadie additionally extracts styles that cannot be inlined into a separate\n`\u003cstyle\u003e` tag that is supported by some email clients. For this reason I\nrecommend Roadie over Premailer.\n\nUnlike Premailer, Roadie does **not** automatically generate a plain text\nversion for HTML emails, but you can use another gem for this, such as\n[plain-david](https://github.com/lucaspiller/plain-david).\n\n#### Roadie\n\nTo integrate Roadie with your Rails app, use [roadie-rails](https://github.com/Mange/roadie-rails).\nTo integrate roadie-rails with REP, uncomment the relevant option in [the initializer](https://github.com/glebm/rails_email_preview/blob/master/config/initializers/rails_email_preview.rb). *initializer is generated during `rails g rails_email_preview:install`*\n\n#### Premailer\n\nTo integrate Premailer with your Rails app you can use either [actionmailer_inline_css](https://github.com/ndbroadbent/actionmailer_inline_css) or [premailer-rails](https://github.com/fphilipe/premailer-rails).\nTo integrate either with REP, uncomment the relevant options in [the initializer](https://github.com/glebm/rails_email_preview/blob/master/config/initializers/rails_email_preview.rb). *initializer is generated during `rails g rails_email_preview:install`*\n\n### I18n\n\nREP expects emails to use current `I18n.locale`:\n\n```ruby\n# current locale\nAccountMailer.some_notification.deliver\n# different locale\nI18n.with_locale('es') do\n  InviteMailer.send_invites.deliver\nend\n```\n\nIf you are using `Resque::Mailer` or `Devise::Async`, you can automatically remember `I18n.locale` when the mail job is scheduled\n[with this initializer](https://gist.github.com/glebm/5725347).\n\nWhen linking to REP pages you can pass `email_locale` to set the locale for rendering:\n\n```ruby\n# will render email in Spanish:\nrails_email_preview.root_url(email_locale: 'es')\n```\n\nREP displays too many locales? Make sure to set `config.i18n.available_locales`, since it defaults to *all* locales in Rails.\n\nUser interface is available in English, German (Danke, @baschtl), and Russian.\nYou can set the language in `config.to_prepare` section of the initializer, default is English.\n\n```ruby\n# config/initializers/rails_email_preview.rb\nRailsEmailPreview.locale = :de\n```\n\n### Views\n\nBy default REP views will render inside its own layout.\n\nTo render all REP views inside your app layout, first set the layout to use in the initializer:\n\n```ruby\nRails.application.config.to_prepare do\n  # Use admin layout with REP (this will also make app routes accessible within REP):\n  RailsEmailPreview.layout = 'admin'\nend\n```\n\nThen, import REP styles into your `application.css.scss`:\n\n```scss\n@import \"rails_email_preview/application\";\n```\n\nAlternatively, if you are using Bootstrap 3, `@import \"rails_email_preview/bootstrap3\"`, and add the following\nto the initializer:\n\n```ruby\nconfig.style.merge!(\n    btn_active_class_modifier: 'active',\n    btn_danger_class:          'btn btn-danger',\n    btn_default_class:         'btn btn-default',\n    btn_group_class:           'btn-group btn-group-sm',\n    btn_primary_class:         'btn btn-primary',\n    form_control_class:        'form-control',\n    list_group_class:          'list-group',\n    list_group_item_class:     'list-group-item',\n    row_class:                 'row',\n)\n```\n\nYou can also override any individual view by placing a file with the same path in your project's `app/views`,\ne.g. `app/views/rails_email_preview/emails/index.html.slim`.\n\n#### Hooks\n\nYou can add content around or replacing REP UI elements by registering view hooks in the initializer:\n\n```ruby\n# Pass position (before, after, or replace) and render arguments:\nRailsEmailPreview.view_hooks.add_render :list, :before, partial: 'shared/hello'\n\n# Pass hook id and position (before, after, or replace):\nRailsEmailPreview.view_hooks.add :headers_content, :after do |mail:, preview:|\n  raw \"\u003cdt\u003eID\u003c/dt\u003e\u003cdd\u003e#{h mail.header['X-APP-EMAIL-ID']}\u003c/dd\u003e\"\nend\n```\n\nAll of the available hooks can be found [here](/lib/rails_email_preview/view_hooks.rb#L10).\n\n### Authentication \u0026 authorization\n\nYou can specify the parent controller for REP controller, and it will inherit all the before filters.\nNote that this must be placed before any other references to REP application controller in the initializer (and before `layout=` call):\n\n```ruby\nRailsEmailPreview.parent_controller = 'Admin::ApplicationController' # default: '::ApplicationController'\n```\n\nAlternatively, to have custom rules just for REP you can:\n\n```ruby\nRails.application.config.to_prepare do\n  RailsEmailPreview::ApplicationController.module_eval do\n    before_action :check_rep_permissions\n\n    private\n    def check_rep_permissions\n       render status: 403 unless current_user \u0026\u0026 can_manage_emails?(current_user)\n    end\n  end\nend\n```\n\n## Development\n\nRun the tests:\n\n```console\n$ rspec\n```\n\nStart a development web server on [localhost:9292](http://localhost:9292):\n\n```console\n$ rake dev\n```\n\nThis project rocks and uses MIT-LICENSE.\n\n[rep-nav-screenshot]: https://raw.github.com/glebm/rails_email_preview/master/doc/img/rep-nav.png \"Email List Screenshot\"\n[rep-show-screenshot]: https://raw.github.com/glebm/rails_email_preview/master/doc/img/rep-show.png \"Show Email Screenshot\"\n[rep-show-default-screenshot]: https://raw.github.com/glebm/rails_email_preview/master/doc/img/rep-show-default.png \"Show Email Screenshot (default styles)\"\n[ci]: https://github.com/glebm/rails_email_preview/actions/workflows/tests.yml\n[badge-ci]: https://github.com/glebm/rails_email_preview/actions/workflows/tests.yml/badge.svg\n[gem]: https://rubygems.org/gems/rails_email_preview\n[gem-badge]: http://img.shields.io/gem/v/rails_email_preview.svg\n[codeclimate]: https://codeclimate.com/github/glebm/rails_email_preview/maintainability\n[codeclimate-badge]: https://api.codeclimate.com/v1/badges/b2b4b63c3f63e316b1e4/maintainability\n[coverage]: https://codeclimate.com/github/glebm/rails_email_preview/test_coverage\n[coverage-badge]: https://api.codeclimate.com/v1/badges/b2b4b63c3f63e316b1e4/test_coverage\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglebm%2Frails_email_preview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglebm%2Frails_email_preview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglebm%2Frails_email_preview/lists"}