An image_url/2 macro that builds image URLs in templates and checks their
options at compile time.
In an app that serves its own images with image_pipe, name the
ImagePipe instance:
# lib/my_app_web.ex, in html_helpers
use ImagePipe.URL.Helpers, instance: MyApp.Images<img src={image_url("cat.jpg", group: [resize: [width: 400, height: 300, fit: :cover]])} />
<img src={image_url(@photo.path, group: [resize: [width: @width]], output: [format: :webp])} />In an app that builds URLs for an image service running elsewhere, give a function that returns the URL configuration. The helper calls this function for every URL, so build the configuration once when the app starts and return the stored copy:
# lib/my_app/image_urls.ex
defmodule MyApp.ImageURLs do
def put_config do
config =
ImagePipe.URL.config(
base_url: "https://images.example.com",
keys: [System.fetch_env!("IMAGE_PIPE_SIGNING_KEY")]
)
:persistent_term.put(__MODULE__, config)
end
def config, do: :persistent_term.get(__MODULE__)
end
# lib/my_app/application.ex, in start/2, before the endpoint starts
MyApp.ImageURLs.put_config()
# lib/my_app_web.ex, in html_helpers
use ImagePipe.URL.Helpers, config: {MyApp.ImageURLs, :config, []}Calling put_config/0 again replaces the stored configuration without a
restart. Signing URLs and rotating keys
gives the order for rotating a key.
Options
:instance- the:nameof anImagePipeinstance. Each URL uses the instance's URL settings fromImagePipe.url_config/2: its base URL, signing keys, source encryption settings, and the presets, request defaults, and watermark settings it checks options against. Building a URL raisesArgumentErrorwhen the instance isn't running. Needs theimage_pipepackage.:mount- with:instance, one of the instance's:mounts, whose URL options the URLs use instead of the instance's own.:config-{module, function, args}, called for each URL, that returns anImagePipe.URL.Config. Use it in place of:instance.:on_invalid-:warn(the default) or:raise. See Checks when the page renders.
The configuration is read each time a URL is built, so signing keys stay
out of the compiled code. Without :instance or :config, URLs use
ImagePipe.URL.config([]): no base URL, signing, or encryption.
Summary
Functions
Builds the URL for source with the options of ImagePipe.URL.
Functions
Builds the URL for source with the options of ImagePipe.URL.
image_url("cat.jpg",
new: [filename: "cat"],
group: [resize: [width: 400, height: 300, fit: :cover]],
group: [blur: 2],
output: [format: :webp]
)
# "/w=400/h=300/fit=cover/-/blur=2/format=webp/filename=cat/src/cat.jpg"new: takes the request controls of ImagePipe.URL.new/2, each group:
the options of one ImagePipe.URL.group/2 call, in order, and output:
the options of ImagePipe.URL.output/2. new: applies first wherever it
is in the call. The option names must be written out in the call, and a
list that isn't fails to compile. Use ImagePipe.URL for options built at
runtime. Values can be variables or assigns.
Checks at compile time
Each option name and value written out in the call is checked when the
module compiles. A list value, such as gradient: or jpeg_options:, is
checked only when all of it is written out, except resize:, whose
options are checked one by one. A mistake is a compiler warning at the
call site:
warning: image_url: invalid_value at {:group, 0, :fit}: invalid value for :fit option: expected one of [:contain, :cover, :stretch, :auto], got: :fillWith mix compile --warnings-as-errors, a mistake fails the build. Values
that are variables are checked when the page renders. How the options
combine depends on the server's presets and request defaults, so how the
options combine is checked at render, with :instance or a configuration
that has :validate_against.
Checks when the page renders
The URL is built with ImagePipe.URL.url_with_issues/3, so an error in
the options or the source never raises. The URL includes it, the server
rejects the URL with 400, and the browser shows a broken image. Each
error is logged at :warning, and each warning, such as a mistake the
builder repaired or an option that has no effect, at :debug. The log
names the call's file and line, the reason, and the option, not the source
or values:
[warning] image_url (lib/my_app_web/controllers/page_html/home.html.heex:3): invalid_value at {:group, 0, :fit}These messages come from the ImagePipe.URL.Helpers module, so Logger's
module levels control them. To turn them off in production, set
Logger.put_module_level(ImagePipe.URL.Helpers, :none) when the app
starts.
With on_invalid: :raise, an error raises ArgumentError instead. To
raise only in tests, read the setting from the app's configuration:
# config/test.exs
config :my_app, :image_url_on_invalid, :raise
# lib/my_app_web.ex, in html_helpers
use ImagePipe.URL.Helpers,
instance: MyApp.Images,
on_invalid: Application.compile_env(:my_app, :image_url_on_invalid, :warn)