BartOtten

BartOtten

Seeking your thoughts on Routex 1.2 pre-releases - localize Phoenix with minimal config

This thread once discussed Routex in it’s early form. It has been repurposed to gather feedback and discusses pre-releases.

Currently: pre 1.2.0
Target: localization with auto-detection of already used libs (Cldr, Gettext, Fluent), simplified setup, support for runtime dispatching and auto-plugs&hooks.

Official releases are announced at another thread: Routex - build powerful Phoenix routes: localize, customize, and innovate

Github: GitHub - BartOtten/routex: Build powerful Phoenix routes: localize, customize, and innovate
Main branch documentation: Overview — Routex v1.3.1

Most Liked

BartOtten

BartOtten

After a lot of refining and polishing, the rough edges are now a thing of the past. I’m thrilled to officially release Routex 1.0.0! :tada:

:scroll: Changelog

This marks a major milestone for Routex, solidifying its stability and readiness for production use. It has been quite a journey, shaped by valuable feedback and real-world use cases.

As the decision-making process comes to a close, I’ve also created a fresh thread in the Libs section to continue the conversation:

:thread: The new thread

A huge thank you to everyone who provided feedback—it has played a crucial role in shaping both the design and documentation. Your insights and contributions have made Routex stronger, and I truly appreciate the support.

kip

kip

ex_cldr Core Team

@BartOtten well since Phoenix 1.7 is now out I have to get off my backside and finish up ex_cldr_routes to include localised VerifiedRoutes.

So I’m in for some collaboration as you proposed - and see if we can take your new library and integrate it.

BartOtten

BartOtten

A long time has passed but it was worth it! To celebrate a nice set of improvements, I released Routex 0.3.0-alpha.2.

As Routex was very much alpha, I took the liberty to break a few things for the better. If you used Routex already, check the Changelog where the breaking changes are listed.

Call for help!

I would love to collaborate on this lib! See some comments, PR’s or extensions from community members. The quality of this lib will benefit from multiple eyes. Feel free to contact me by personal message or other means.

Highlights

new! the process dictionary can be used to determine route branch
Routex solely used pattern matching on URL’s to determine which route branch (former scope) to use. Now the process dict key :rtx_branch -when set- overrides the URL matching.

new! extension Route interpolation
A route can be defined with route attribute interpolation. Any route attribute can be used!

live "/#{region}/products/#{language}/:id", ProductLive.Index, :index

new! module Routex.Matchable.
Uniform, better, faster, easier to use and it Just Works™. The functions in this module allow developers unexperienced with Macro’s and/or AST to create simple helper functions, while more experienced AST developers will be happy with the abstractions it provides as.

Matchables are an essential part of Routex. They are used to match run time routes with compile time routes.

This module provides functions to create Matchables, convert them to match pattern AST as well as function heads AST and to check if the routing values of two Matchable records match.

new! Module Routex.Branching
Provides a set of functions to build branched variants of macro’s. It’s interface is still a bit rough but it’s usable enough to build a new version of extension Verified Routes with it.

The renewed Verified Routes extension.
Using Routex.Branching it now also creates branching variants of url/{1,2,3} and path/{2,3} with, of course, configurable names. When the names of Phoenix are used an improved warning is displayed during route compilation.


improved: added the attribute ‘match?’ to the results returned by ‘alternatives/1’
The value is determined by a pattern match, so performance wise we’re good. It does make code clean.

<.link
        :for={alternative <- Routes.alternatives(@url)}
        rel="alternate"
        hreflang={alternative.attrs.language}
        patch={alternative.slug}
      >
        <.button class={ (alternative.match? && "bg-[#FD4F00]") || "" }>
          <%= alternative.attrs.name %>
        </.button>
      </.link>

Example app
Updated to use the latest version.
Example App
Github Example App

BartOtten

BartOtten

Let’s talk about… v1.2.0-rc.0

With version 1.2.0 on the horizon I would like to collect additional feedback before the release is finalized. After all, nothing better than Elixir-community collaboration :wink:

Although the version bump is minor, the release itself is major! The full changelog is linked at the bottom of this post.

Much of the code base has been refactored, new extensions build a bridge between compile time and run time and the most common use case of Routex, localization, has become much easier with the new extension SimpleLocale.

:robot: Simplified Integration / Automation

Routex now streamlines integration with your Phoenix application by extending
its functionality from compile time to runtime.

  • Call functions at runtime using (custom) Routex attributes
  • Inline LiveView Hooks of extensions
  • Inline Plugs of extensions**

:netherlands: Localize your Phoenix app

Routex.Extension.SimpleLocale is included as tech preview.

SimpleLocale was designed to provide a solution for the most common
cases of localization. Featuring automated Plug/LiveView integration, a small locales registry and very customizable locale detection at runtime (think Cldr.Plug.PutLocale on tweaker-steroids)

The registry is based on the official IANA registry. It only includes region and language identifiers (combined: locales) and their respective display names.

The runtime integration is not limited to any package and you can even have multiple locale backends at the same time, using different locales / language / region…

Routex using the buildin mini locale registry for button names and setting Gettext locale.

:books: Docs, docs, docs

A much enhanced Usage Guide for getting up and running in no time.

The revamped Localize Phoenix Guide, so the issue this release began with could be closed


:speaking_head: Speak up!

I hope to collect feedback on these new extensions / features! Let me know what you think as even a small comment might make a major positive impact. After all, this whole release was triggered by…

Localization guide is missing step to content translation (using Gettext)
@KristerV

:see_no_evil_monkey:


Full Changelog

For a detailed changelog with all changes explained in depth:

BartOtten

BartOtten

v1.2.0-rc.1 has been pushed to Hex

Usually the changes within an RC series are minor. This time, not so much.

While tweaking the documentation of SimpleLocale for 1.2.0 release I decided to overhaul before it was too late and the project would be forced to do a breaking change in the next release. So I took it one step further…

Routex lowers the bar of Phoenix localization

I am happy to announce Routex arguably has the most comprehensive localized routes system for Phoenix, the most customizable locale detection and yet the easiest setup due to auto-detection of third-party localization packages.

Localize.Phoenix.Routes: Generate localized routes with ease

At compile time, this extension generates localized routes based on locale tags. These locale tags are automatically derived from your Cldr, Gettext or Fluent setup and can be overriden using the extensions options.

When using a custom configuration, tags are validated using a build-in locale registry based on the authoritive IANA Language Subtag Registry. It can also be used the lookup language and region display names.

Localize.Phoenix.Runtime: Plug and Play (aka: LiveView Hook)

A Plug and LiveView Livecycle hook to update the connection with locale attributes and store them in the session. Comes with sane defaults but is highly customizable, so each locale attribute (:locale, :region, :language) can be take from independent sources.

You can define a clear order of precedence for each attribute. For instance, you might prioritize a route’s :region attributes over the browser’s Accept-Language header but at the same time use the Accept-Language as the main source for :language.

Other

Where Next?

Popular in RFCs Top

felix-starman
I’ve noticed that often when I find myself needing to manually set content-disposition - [MDN] the advice is usually to use URI.encode_ww...
New
wingyplus
Hi, I start working on the fork version of Elixir GRPC. What I’ve done is the past few days: Support Elixir 1.11+ Support OTP 23+ OTP...
New
pzingg
I took a phx.gen.auth application and added support for storing a user’s cookie consent settings. Created a couple of modal dialogs to ha...
New
BartOtten
This lib is now published and has a new topic. Once this topic was about PhxAltRoutes. A lib pioneering localized routes for Phoenix. I...
New
miolini
Hi :waving_hand: I’ve been working on CanvasCraft, a 2D drawing library for Elixir built on top of Skia via Rustler. It provides a decla...
New
zachallaun
Hey gang, I’ve been using Req as my primary client for a project I’ve been working on that interacts with a number of APIs, and I quickl...
New
manuel-rubio
There was some time when I started thinking about giving a boost to Lambdapad, the initiative from @garretsmith in Erlang that I loved wa...
New
KristerV
I got fed up with removing unused aliases manually so made a package for it: GitHub - KristerV/remove_unused_ex: Remove unused aliases an...
New
gilest
Hi all Relatively new to Elixir, but was curious to see how Phoenix might run with a basic importmap configuration. Introducing, phoeni...
New
blubparadox
Hi all. If you’ve looked on Twitter or YouTube you’ve seen the 1 billion row challenge, usually done in Java. I’ve written an Elixir vers...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

We're in Beta

About us Mission Statement