Open dunivlorraine opened 1 week ago
Yes, we absolutely want this. It's not high priority because there's an easy workaround: You can look up the current URL in the session, then dynamically display content based on that URL.
Here's a quick example to get you started:
class MyPage(rio.Component):
def build(self) -> rio.Component:
# Get a dynamic value from the current URL, such as the ID of a user
#
# The current URL is available in the session, as an instance of
# `yarl.URL`. Yarls considers the first part to be `/`. The second part
# will be `user`, so we're interested in the third part, i.e. index `2`.
try:
user_id = self.session.active_page_url.parts[2]
# Fallback, in case the current URL is `/user` without an ID
except IndexError:
return rio.Text("No user selected")
# Build the page, displaying information about the user ID. In a serious
# app you'd probably want to fetch this information from a database.
# (Always perform slow operations like database access OUTSIDE of
# build!)
return rio.Text(f"Hello, #{user_id}!")**
Great, that's good to know! I'll use this workaround in the meantime.
Hi! So I've tried this method and found out that that could not work: a real use-case page is when a route acts as a way to display both a list of records, and details of a record, and that we should navigate from the list to the details of a record using the session.navigate_to
method.
Here's an example:
/todos
-> list all todos
/todos/id
-> display the todo details with that ID
In the todos_page.py
build:
try:
todo_id = self.session.active_page_url.parts[2]
# Fallback, in case the current URL is without an ID
except IndexError:
return self.display_list()
return self.display_details(todo_id)
self.display_list()
returns a list of cards representing todo records. Each card has the following props:
on_press=lambda: self.session.navigate_to(f"/todos/{self.id}")
If we click on a card, we won't switch to the details view, as the page build
function won't be called again when we use the session.navigate_to
function.
I could use another page to do it (/todos/details/id
), but it's not really a best practices.
Also, we can't develop routes that are based on dynamic ones outside the page that has the slot.
Here's an example:
/todos/:id/create
Here, it's not possible to handle the "create" logic outside the todos_page.py
, which means that we should handle every possible routes after the dynamic slot in the same page.
It's a bit unusual to use the same page to do two things. Usually you'd have something like/items
and /item/<id>
. If you want to use the same page for both, you can always force a refresh using await self.force_refresh()
. Alaternatively, use the @rio.event.on_page_change
to get notified when you need to display something else
IMHO, plural names is the most common way of using dynamic routes, there are many websites who chose to do that (here, Github for issues) for several reasons:
Although, singular naming is also used, it mainly depends of the context, and I understand that plural vs singular naming is a developer choice rather a rule. And this implies that all the logic for these sub-pages must be handled inside the same page.
I understand that rio-ui is in development and is young, so I'll stick to that for now, I just think that the workaround is not really a full one, as it only covers parts of what dynamic routing provide :)
Description
Currently, there is no way to add a route that has a name that's not already pre-defined :
/todos/[:id]
where[:id]
is a runtime-based value.The
url_segment
parameter of a@rio.page
annotation hasn't dynamic value slots for now.Suggested Solution
Add slots that could be used in the
url_segment
parameter of a@rio.page
annotation. Slots could be defined using a special suite of characters delimiting its value (e.g. like SvelteKit :[:my-path-name]
). This slot may only allow a string value for now, as other kind of restrictions/typing for that slot value is quite an advanced feature.The value of the slots should be accessible within the page and sub-pages (why not in the build context of the class ?).
Alternatives
Appart from generating pages at runtime or using URL query parameters (which both are not available features in rio-ui), I don't really see other alternatives.
Additional Context
No response
Related Issues/Pull Requests
No response