forked from remoteoss/swoosh_gallery
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
60ce96b
commit 60fa960
Showing
5 changed files
with
130 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,87 @@ | ||
defmodule Swoosh.Gallery do | ||
@moduledoc ~S""" | ||
Swoosh.Gallery is a module used to map a preview to a path in order to later | ||
be exposed through Plug or generate docs with `mix swoosh.gen.gallery` task. | ||
Swoosh.Gallery is a library to preview and display your Swoosh mailers to everyone, | ||
either by exposing the previews on your application's router or publishing it on | ||
your favorite static host solution. | ||
## Examples | ||
## Getting Started | ||
You will a gallery module to organize all your previews, and implement the expected | ||
callbacks on your mailer modules: | ||
defmodule MyApp.SwooshGallery do | ||
defmodule MyApp.Mailer.Gallery do | ||
use Swoosh.Gallery | ||
preview("/welcome", MyApp.Emails.Welcome) | ||
preview("/welcome", MyApp.Mailer.WelcomeMailer) | ||
end | ||
defmodule MyApp.Mailer.WelcomeMailer do | ||
# the expected Swoosh / Phoenix.Swoosh code that you already have to deliver emails | ||
use Phoenix.Swoosh, view: SampleWeb.WelcomeMailerView, layout: {MyApp.LayoutView, :email} | ||
def welcome(user) do | ||
new() | ||
|> from("[email protected]") | ||
|> to({user.name, user.email}) | ||
|> subject("Welcome to Sample App") | ||
|> render_body("welcome.html", user: user) | ||
end | ||
# `preview/0` function that builds your email using fixture data | ||
def preview do | ||
welcome(%{email: "[email protected]", name: "Test User!"}) | ||
end | ||
# `preview_details/0` with some useful metadata about your mailer | ||
def preview_details do | ||
[ | ||
title: "Welcome to MyApp!", | ||
description: "First email to welcome users into the platform" | ||
] | ||
end | ||
end | ||
Then in your router: | ||
Then in your router, you can mount your Gallery to expose it to the web: | ||
forward "/gallery", MyApp.Mailer.Gallery | ||
Or, you can generate static web pages with all the previews from your gallery: | ||
mix swoosh.gallery.html --gallery MyApp.Mailer.Gallery --path "_build/emails" | ||
### Generating preview data | ||
forward "/gallery", MyApp.SwooshGallery | ||
Previews should be built using in memory fixture data and we do **not recommend** that you | ||
reuse your application's code to query for existing data or generate files during runtime. The | ||
`preview/0` can be invoked multiple times as you navigate through your gallery on your browser | ||
when mounting it on the router or when using the `swoosh.gallery.html` task to generate the static | ||
pages. | ||
Or, you can generate HTML pages from it: | ||
defmodule MyApp.Mailer.SendContractEmail do | ||
def send_contract(user, blob) do | ||
contract = | ||
Swoosh.Attachment.new({:data, blob}, filename: "contract.pdf", content_type: "application/pdf") | ||
new() | ||
|> to({user.name, user.email}) | ||
|> subject("Here is your Contract") | ||
|> attachment(contract) | ||
|> render_body(:contract, user: user) | ||
end | ||
# Bad - invokes application code to query data and generate the PDF contents | ||
def preview do | ||
user = MyApp.Users.find_user("[email protected]") | ||
{:ok, blob} = MyApp.Contracts.build_contract(user) | ||
build(user, blob) | ||
end | ||
mix swoosh.gallery.html --gallery MyApp.SwooshGallery --path "_build/emails" | ||
# Good - uses in memory structs and existing fixtures | ||
def preview do | ||
blob = File.read!("#{Application.app_dir(:tiger, "my_app")}/fixtures/sample.pdf") | ||
build(%User{}, blob) | ||
end | ||
end | ||
""" | ||
|
||
defmacro __using__(_options) do | ||
|
@@ -54,8 +118,14 @@ defmodule Swoosh.Gallery do | |
## Examples | ||
preview("/welcome", MyApp.Emails.Welcome) | ||
defmodule MyApp.Mailer.Gallery do | ||
use Swoosh.Gallery | ||
preview "/welcome", MyApp.Emails.Welcome | ||
preview "/account-confirmed", MyApp.Emails.AccountConfirmed | ||
preview "/password-reset", MyApp.Emails.PasswordReset | ||
end | ||
""" | ||
@spec preview(String.t(), module()) :: no_return() | ||
defmacro preview(path, module) do | ||
|
@@ -74,14 +144,20 @@ defmodule Swoosh.Gallery do | |
end | ||
|
||
@doc """ | ||
Defines a scope in which previews can be nested. Each group needs a path and a `:title` | ||
option. | ||
Defines a scope in which previews can be nested when rendered on your gallery. | ||
Each group needs a path and a `:title` option. | ||
## Example | ||
group "/onboarding", title: "Onboarding Emails" do | ||
preview "/welcome", MyApp.Emails.Welcome | ||
preview "/account-confirmed", MyApp.Emails.AccountConfirmed | ||
defmodule MyApp.Mailer.Gallery do | ||
use Swoosh.Gallery | ||
group "/onboarding", title: "Onboarding Emails" do | ||
preview "/welcome", MyApp.Emails.Welcome | ||
preview "/account-confirmed", MyApp.Emails.AccountConfirmed | ||
end | ||
preview "/password-reset", MyApp.Emails.PasswordReset | ||
end | ||
## Options | ||
|
@@ -111,19 +187,17 @@ defmodule Swoosh.Gallery do | |
end | ||
end | ||
|
||
@doc ~S""" | ||
Evaluates a preview. It loads the results of email_mfa into the email property. | ||
""" | ||
# Evaluates a preview. It loads the results of email_mfa into the email property. | ||
@doc false | ||
@spec eval_preview(%{:email_mfa => {module(), atom(), list()}}) :: map() | ||
def eval_preview(%{email: _email} = preview), do: preview | ||
|
||
def eval_preview(%{email_mfa: {module, fun, opts}} = preview) do | ||
Map.put(preview, :email, apply(module, fun, opts)) | ||
end | ||
|
||
@doc ~S""" | ||
Evaluates a preview and reads the attachment at a given index position. | ||
""" | ||
# Evaluates a preview and reads the attachment at a given index position. | ||
@doc false | ||
@spec read_email_attachment_at(%{email_mfa: {atom, atom, list}}, integer()) :: | ||
{:error, :invalid_attachment | :not_found} | ||
| {:ok, %{content_type: String.t(), data: any}} | ||
|
@@ -177,6 +251,7 @@ defmodule Swoosh.Gallery do | |
raise ArgumentError, "router paths must be strings, got: #{inspect(path)}" | ||
end | ||
|
||
@doc false | ||
def build_preview_path(nil, path), do: path | ||
def build_preview_path(group, path), do: "#{group}.#{path}" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters