Current section
Files
Jump to
Current section
Files
lib/still/compiler/template_helpers/link.ex
defmodule Still.Compiler.TemplateHelpers.Link do
@moduledoc """
Renders an anchor HTML tag.
"""
alias Still.Compiler.TemplateHelpers.ContentTag
alias Still.Compiler.TemplateHelpers.UrlFor
alias Still.SourceFile
@doc """
Uses `Still.Compiler.TemplateHelpers.ContentTag` to render an anchor tag.
Requires a `:to` option, the target URL. If this is a relative path, the
website's base URL is prepended. If it is an absolute path the `target:
"_blank"` and `rel: "noopener noreferrer"` options are added to be passed to
`Still.Compiler.TemplateHelpers.ContentTag` `render` function.
If there is a `do` block, it uses the current file preprocessor to render
`markup`. Note that this is on demand, outside
`Still.Compiler.CompilationStage`.
"""
def render(env, opts, do: markup) do
preprocessor = env[:preprocessor]
%{content: content} =
preprocessor.render(%SourceFile{
content: markup,
input_file: env[:input_file],
extension: env[:extension],
metadata: env |> Enum.into(%{})
})
render(env, content, opts)
end
def render(_env, text, opts) do
{url, opts} = pop_url(opts)
ContentTag.render("a", text, [{:href, url} | opts])
end
defp pop_url(opts) do
{to, opts} = Keyword.pop!(opts, :to)
case URI.parse(to) do
%URI{host: nil, scheme: nil, path: path} when not is_nil(path) ->
{UrlFor.render(to), opts}
%URI{scheme: scheme} when scheme in ["http", "https"] ->
opts = add_absolute_path_opts(opts)
{to, opts}
_ ->
{to, opts}
end
end
defp add_absolute_path_opts(opts) do
opts
|> Keyword.put_new(:target, "_blank")
|> Keyword.put_new(:rel, "noopener noreferrer")
end
end