Skip to content

Commit

Permalink
Support Phoenix 1.6 and Phoenix 1.7
Browse files Browse the repository at this point in the history
  • Loading branch information
kipcole9 committed Dec 26, 2022
1 parent 9d07a8f commit e934f0c
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 120 deletions.
3 changes: 1 addition & 2 deletions config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ import Config

config :logger, level: :warning

config :ex_cldr_routes, MyAppWeb.Endpoint,
secret_key_base: "kjoy3o1zeidquwy1398juxzldjlksahdk3"
config :ex_cldr_routes, MyAppWeb.Endpoint, secret_key_base: "kjoy3o1zeidquwy1398juxzldjlksahdk3"
74 changes: 41 additions & 33 deletions lib/cldr/route.ex
Original file line number Diff line number Diff line change
Expand Up @@ -254,15 +254,15 @@ defmodule Cldr.Route do
@doc false
def confirm_backend_has_gettext!(backend, %Cldr.Config{gettext: nil}) do
raise ArgumentError,
"""
The Cldr backend #{inspect(backend)} does not have a Gettext
module configured.
"""
The Cldr backend #{inspect(backend)} does not have a Gettext
module configured.
A Gettext module must be configured in order to define localized
routes. In addition, translations must be provided for the Gettext
backend under the "routes" domain (ie in a file "routes.pot" for
each configured Gettext locale).
"""
A Gettext module must be configured in order to define localized
routes. In addition, translations must be provided for the Gettext
backend under the "routes" domain (ie in a file "routes.pot" for
each configured Gettext locale).
"""
end

def confirm_backend_has_gettext!(_backend, %Cldr.Config{} = _config) do
Expand All @@ -278,15 +278,21 @@ defmodule Cldr.Route do
defmacro __before_compile__(env) do
alias Cldr.Route.LocalizedHelpers
routes = env.module |> Module.get_attribute(:phoenix_routes) |> Enum.reverse()
forwards = env.module |> Module.get_attribute(:phoenix_forwards)
localized_routes = Cldr.Route.routes(routes)
forwards = env.module |> Module.get_attribute(:phoenix_forwards)

# Remove bookkeeping data in :private
Module.delete_attribute(env.module, :phoenix_routes)
Module.register_attribute(env.module, :phoenix_routes, [])
Module.put_attribute(env.module, :phoenix_routes, Cldr.Route.delete_original_path(routes))

routes_with_exprs = Enum.map(routes, &{&1, Phoenix.Router.Route.exprs(&1, forwards)})
routes_with_exprs =
if function_exported?(Phoenix.Router.Route, :exprs, 2) do
Enum.map(routes, &{&1, apply(Phoenix.Router.Route, :exprs, [&1, forwards])})
else
Enum.map(routes, &{&1, apply(Phoenix.Router.Route, :exprs, [&1])})
end

helpers_moduledoc = Module.get_attribute(env.module, :helpers_moduledoc)
LocalizedHelpers.define(env, routes_with_exprs, docs: helpers_moduledoc)

Expand Down Expand Up @@ -429,7 +435,7 @@ defmodule Cldr.Route do

# Rewrite nested resources; guard against infinite recursion
defmacro localize(locale, {:resources, _, [path, controller, [do: {fun, _, _}] = nested]})
when fun != :localize do
when fun != :localize do
nested = localize_nested_resources(locale, nested)

quote do
Expand All @@ -442,7 +448,8 @@ defmodule Cldr.Route do
end

# Do the actual translations
defmacro localize(cldr_locale_name, {verb, meta, [path | args]}) when verb in @localizable_verbs do
defmacro localize(cldr_locale_name, {verb, meta, [path | args]})
when verb in @localizable_verbs do
cldr_backend = Module.get_attribute(__CALLER__.module, :_cldr_backend)
do_localize(:private, cldr_locale_name, cldr_backend, {verb, meta, [path | args]})
end
Expand All @@ -453,10 +460,10 @@ defmodule Cldr.Route do
args = Enum.map_join(args, ", ", &inspect/1)

raise ArgumentError,
"""
Invalid route for localization: #{verb} #{inspect(path)}, #{inspect(args)}
Allowed localizable routes are #{inspect(@localizable_verbs)}
"""
"""
Invalid route for localization: #{verb} #{inspect(path)}, #{inspect(args)}
Allowed localizable routes are #{inspect(@localizable_verbs)}
"""
end

defp do_localize(field, cldr_locale_name, cldr_backend, {verb, meta, [path | args]} = route) do
Expand Down Expand Up @@ -490,7 +497,7 @@ defmodule Cldr.Route do
end

defp localize_nested_resources(locale, nested) do
Macro.postwalk nested, fn
Macro.postwalk(nested, fn
{:resources, _, [_path, _meta, _args, [do: {:resources, _, _}]]} = resources ->
quote do
localize unquote(locale) do
Expand All @@ -507,27 +514,27 @@ defmodule Cldr.Route do

{:resources, _, _} = route ->
quote do
localize unquote(locale), unquote(route)
localize(unquote(locale), unquote(route))
end

other ->
other
end
end)
end

defp locales_from_unique_gettext_locales(cldr_backend) do
cldr_backend.known_locale_names()
|> Enum.map(&cldr_backend.validate_locale/1)
|> Enum.map(&elem(&1, 1))
|> Enum.uniq_by(&(&1.gettext_locale_name))
|> Enum.uniq_by(& &1.gettext_locale_name)
|> Enum.reject(&is_nil/1)
|> Enum.map(&(&1.cldr_locale_name))
|> Enum.map(& &1.cldr_locale_name)
end

# Interpolates the locale, language and territory
# into he path by splicing the AST
defp interpolate(path, locale) do
Macro.prewalk path, fn
Macro.prewalk(path, fn
{{:., _, [Kernel, :to_string]}, _, [{:locale, _, _}]} ->
to_string(locale.cldr_locale_name) |> String.downcase()

Expand All @@ -539,7 +546,7 @@ defmodule Cldr.Route do

other ->
other
end
end)
end

# Since we are doing com[ile-time translation of the
Expand All @@ -564,7 +571,7 @@ defmodule Cldr.Route do
end

defp combine_string_segments({:<>, _, [a, b]}) do
[combine_string_segments(a), combine_string_segments(b)]
[combine_string_segments(a), combine_string_segments(b)]
end

defp combine_string_segments([a | rest]) do
Expand All @@ -573,12 +580,12 @@ defmodule Cldr.Route do

defp combine_string_segments(ast) do
raise ArgumentError,
"""
The path arugment to a localized route must be a binary that
can be resolved at compile time. Found:
"""
The path arugment to a localized route must be a binary that
can be resolved at compile time. Found:
#{Macro.to_string(ast)}
"""
#{Macro.to_string(ast)}
"""
end

# Localise the helper name for the a verb (except resources)
Expand Down Expand Up @@ -785,8 +792,9 @@ defmodule Cldr.Route do

# When the routes match except for locale
defp group_locales_by_path_helper_verb([
%{path: path, helper: helper, verb: verb} = first,
%{path: path, helper: helper, verb: verb} = second | rest]) do
%{path: path, helper: helper, verb: verb} = first,
%{path: path, helper: helper, verb: verb} = second | rest
]) do
locales = Enum.uniq([locale_from_args(second) | first.metadata.locales]) |> Enum.sort()
metadata = Map.put(first.metadata, :locales, locales)
group_locales_by_path_helper_verb([%{first | metadata: metadata} | rest])
Expand Down Expand Up @@ -855,7 +863,7 @@ defmodule Cldr.Route do
end

defp escape_interpolation(path) do
Macro.prewalk path, fn
Macro.prewalk(path, fn
{{:., _, [Kernel, :to_string]}, _, [{:locale, _, _}]} ->
~S"#{locale}"

Expand All @@ -867,6 +875,6 @@ defmodule Cldr.Route do

other ->
other
end
end)
end
end
31 changes: 17 additions & 14 deletions lib/cldr/routes/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ defmodule Cldr.Route.LocalizedHelpers do
code =
quote do
@moduledoc unquote(docs) &&
"""
Module with localized helpers generated from #{inspect(unquote(env.module))}.
"""
"""
Module with localized helpers generated from #{inspect(unquote(env.module))}.
"""

alias Cldr.Route.LocalizedHelpers

Expand Down Expand Up @@ -351,7 +351,7 @@ defmodule Cldr.Route.LocalizedHelpers do
"""
@spec hreflang_links(%{LocalizedHelpers.locale_name() => LocalizedHelpers.url()}) ::
Phoenix.HTML.safe()
Phoenix.HTML.safe()

def hreflang_links(url_map) do
Cldr.Route.LocalizedHelpers.hreflang_links(url_map)
Expand All @@ -366,11 +366,12 @@ defmodule Cldr.Route.LocalizedHelpers do
for {helper, routes_by_locale} <- helper_by_locale(routes),
{vars, locales} <- routes_by_locale do
if locales == [] do
quiet_vars = Enum.map(vars, fn var ->
quote do
_ = unquote(var)
end
end)
quiet_vars =
Enum.map(vars, fn var ->
quote do
_ = unquote(var)
end
end)

quote generated: true, location: :keep do
def unquote(:"#{helper}_links")(conn_or_endpoint, plug_opts, unquote_splicing(vars)) do
Expand All @@ -379,15 +380,15 @@ defmodule Cldr.Route.LocalizedHelpers do
end
end
else
quote generated: true, location: :keep do
quote generated: true, location: :keep do
def unquote(:"#{helper}_links")(conn_or_endpoint, plug_opts, unquote_splicing(vars)) do
for locale <- unquote(Macro.escape(locales)) do
Cldr.with_locale locale, fn ->
Cldr.with_locale(locale, fn ->
{
Map.fetch!(locale, :requested_locale_name),
unquote(:"#{helper}_url")(conn_or_endpoint, plug_opts, unquote_splicing(vars))
}
end
end)
end
|> Map.new()
end
Expand All @@ -413,9 +414,10 @@ defmodule Cldr.Route.LocalizedHelpers do
end

defp routes_by_locale(routes) do
Enum.group_by(routes,
Enum.group_by(
routes,
fn {_route, exprs} -> elem(:lists.unzip(exprs.binding), 1) end,
fn {route, _exprs} -> route.private[:cldr_locale] end
fn {route, _exprs} -> route.private[:cldr_locale] end
)
|> Enum.map(fn
{vars, [nil]} -> {vars, []}
Expand Down Expand Up @@ -535,6 +537,7 @@ defmodule Cldr.Route.LocalizedHelpers do

@doc false
def strip_locale(helper, locale)

def strip_locale(helper, %Cldr.LanguageTag{} = locale) do
locale_name = locale.gettext_locale_name
strip_locale(helper, locale_name)
Expand Down
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ defmodule CldrRoutes.MixProject do
[
{:ex_cldr, "~> 2.32"},
{:phoenix, "~> 1.7-rc", override: true},
# {:phoenix, "~> 1.6", override: true},
{:phoenix_live_view, "~> 0.18", optional: true},
{:jason, "~> 1.0"},
{:gettext, "~> 0.19"},
Expand Down
4 changes: 2 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%{
"castore": {:hex, :castore, "0.1.18", "deb5b9ab02400561b6f5708f3e7660fc35ca2d51bfc6a940d2f513f89c2975fc", [:mix], [], "hexpm", "61bbaf6452b782ef80b33cdb45701afbcf0a918a45ebe7e73f1130d661e66a06"},
"castore": {:hex, :castore, "0.1.20", "62a0126cbb7cb3e259257827b9190f88316eb7aa3fdac01fd6f2dfd64e7f46e9", [:mix], [], "hexpm", "a020b7650529c986c454a4035b6b13a328e288466986307bea3aadb4c95ac98a"},
"cldr_utils": {:hex, :cldr_utils, "2.19.1", "5a7bcd2f2fd432c548e494e850bba8a9e838f1b10202f682ea1d9809d74eff31", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "fbd10f79363e70f3d893ab21e195f444ca87c2c80120b5911761491da4489620"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"dialyxir": {:hex, :dialyxir, "1.2.0", "58344b3e87c2e7095304c81a9ae65cb68b613e28340690dfe1a5597fd08dec37", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "61072136427a851674cab81762be4dbeae7679f85b1272b6d25c3a839aff8463"},
Expand All @@ -19,7 +19,7 @@
"phoenix_live_view": {:hex, :phoenix_live_view, "0.18.3", "2e3d009422addf8b15c3dccc65ce53baccbe26f7cfd21d264680b5867789a9c1", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c8845177a866e017dcb7083365393c8f00ab061b8b6b2bda575891079dce81b2"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"},
"phoenix_template": {:hex, :phoenix_template, "1.0.0", "c57bc5044f25f007dc86ab21895688c098a9f846a8dda6bc40e2d0ddc146e38f", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "1b066f99a26fd22064c12b2600a9a6e56700f591bf7b20b418054ea38b4d4357"},
"phoenix_view": {:hex, :phoenix_view, "1.1.2", "1b82764a065fb41051637872c7bd07ed2fdb6f5c3bd89684d4dca6e10115c95a", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "7ae90ad27b09091266f6adbb61e1d2516a7c3d7062c6789d46a7554ec40f3a56"},
"phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"},
"plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"},
"plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"},
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
Expand Down
4 changes: 1 addition & 3 deletions mix/myapp_router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@ defmodule MyApp.Router do
# Specific set of locales
localize [:en, :fr] do
resources "/comments", PageController, except: [:delete]
get "/pages/:page", PageController, :edit, assigns: %{key: :value}
end

# Test all verbs
# Test all other verbs
localize do
get "/pages/:page", PageController, :show
patch "/pages/:page", PageController, :update
delete "/pages/:page", PageController, :delete
post "/pages/:page", PageController, :create
Expand Down
Loading

0 comments on commit e934f0c

Please sign in to comment.