Hi @BartOtten , here’s some feedback since you are looking for one:
Is this library is a drop-in replacement to Phoenix Routes? Routing — Phoenix v1.6.6 in which case aspect such as security (like token decoding, cross browser validation, etc.)
What is the intended usage of the library? Why would people consider using AltRoutes rather than the standard Phoenix Routes? it’s not clear to me, right now it seems AltRoutes looks like a smaller codegen of standard Phoenix Route.
1 - I see PhxMultiLangRoutes as more descriptive of what the library does. PhxLocalizedRoutes could also be an idea.
2 - Would :short differ from :slug in many cases? If not, having one key less could be desirable. Even in europe/eu case, if the slug is europe, I would find it much more intuitively that the helper uses it as well (europe_product_index_path).
4 - A far alley, maybe even out of the scope of the library, could be the support of different domains/subdomains:
My idea was regarding sites that run each localized version on different subdomains entirely. So, the french version on fr.example.com, the english/default on example.com etc, thus the path helpers/router macros will need to generate the paths differently and I suppose it would also involve different endpoint/router for each locale. Again, a very var away alley
Changelog (pushed so far, refactoring in progress)
- renamed lib
- restructured config
- less dynamic, more compiled; the config is extended with generated values during compilation time.
- use native :assigns for the scopes
- simplified Plug
- fixed compilation issues
- removed (dev) helper function clutter
- added assigned_values(key or list of keys)
Afaik this can be done by pointing all subdomains to the same location (with all routes) and use a SetLocale plug (see README) to steer people to the correct localized route.
I have a conversation with @kip from ex_cldr to streamline/align libs and efforts.
add option to get flattened config with composite keys
use dedicated loc_scope_helper
add loc_scope_helper to assigns during config compilation
BROKE A FEW THINGS, so use commit 8d2c608208af06e2edd75a0c45f4022f967193e9 to a checkout a working example
Next stop: Add example how to list all alternative routes on a page.
I had this working but the syntax was evil. Will probably add a loc_link macro or patch the native Phoenix link, live_redirect, etc
# the original route is wrapped in `PhxLocalizedRoutes.Helpers.loc_route` which receives a scope config (opts).
<%= for {slug, opts} <- ExampleWeb.LocalizedRoutes.local_scopes!(flat: true) do %>
<span>
<%= live_redirect " [#{slug}] ", to: PhxLocalizedRoutes.Helpers.loc_route(Routes.product_index_path(@socket, :index), opts) %>
</span>
<% end %>
Update
Using live_redirect and a (macro set) query parameter seemed to work well; but broke as soon as a user navigated to another LiveView.
A new LiveView route leads to a new proces, so the assigned loc_scope_helper was gone
Private info is only merged into the Socket on initial connected mount. So navigating between routes does not update it.
The fallback session value on mount was not updated as there was no Conn to do so.
So the example above has become:
<%= for {slug, opts} <- ExampleWeb.LocalizedRoutes.local_scopes do %>
<span>
<%= link " [#{slug}] ", to: PhxLocalizedRoutes.Helpers.loc_route(Routes.product_index_path(@socket, :index), opts) %>
</span>
<% end %>
Refactored configuration as :global and :locals kept bothering me. Now the scopes are simply nested maps, starting with slug ‘/’ to keep the native route.
Added some extra inline explanation in the example app.
CLDR had it’s release of CLDR Route which was inspired by this lib-in-progress. There is overlap in purpose, yet enough difference in features to continue this lib. Will make a comparison table some day to help users making the choice what fits best for their purpose.
Due to the better documentation and function naming skills of @kip, I have merged back some improvements. So thanks Kip for part of this update!
alias original helper module as OriginalRoutes
improved docs
improved function naming
:assigns => :assign (to keep :assign_new as option for the future)