Skip to content

Commit 10ba809

Browse files
authored
perfer to always use splat and optional catchcall (#1436)
1 parent c542e6b commit 10ba809

File tree

3 files changed

+41
-61
lines changed

3 files changed

+41
-61
lines changed

docs/pages/dynamic_routing.md

Lines changed: 25 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import reflex as rx
33
from pcweb import constants, styles
44
```
55

6-
76
# Dynamic Routes
87

98
Dynamic routes in Reflex allow you to handle varying URL structures, enabling you to create flexible
@@ -12,17 +11,17 @@ and optional catch-all routes, each with detailed examples.
1211

1312
## Regular Dynamic Routes
1413

15-
Regular dynamic routes in Reflex allow you to match specific segments in a URL dynamically. A regular dynamic route is defined by square brackets in a route string / url pattern. For example `/users/[id]` or `/products/[category]`. These dynamic route arguments can be accessed through a state var. For the examples above they would be `rx.State.id` and `rx.State.category` respectively.
14+
Regular dynamic routes in Reflex allow you to match specific segments in a URL dynamically. A regular dynamic route is defined by square brackets in a route string / url pattern. For example `/users/[id]` or `/products/[category]`. These dynamic route arguments can be accessed through a state var. For the examples above they would be `rx.State.id` and `rx.State.category` respectively.
1615

1716
```md alert info
1817
# Why is the state var accessed as `rx.State.id`?
18+
1919
The dynamic route arguments are accessible as `rx.State.id` and `rx.State.category` here as the var is added to the root state, so that it is accessible from any state.
2020
```
2121

2222
Example:
2323

2424
```python
25-
2625
@rx.page(route='/post/[pid]')
2726
def post():
2827
'''A page that updates based on the route.'''
@@ -36,12 +35,10 @@ The [pid] part in the route is a dynamic segment, meaning it can match any value
3635

3736
If a user navigates to `/post/5`, `State.post_id` will return `5`, and the page will display `5` as the heading. If the URL is `/post/xyz`, it will display `xyz`. If the URL is `/post/` without any additional parameter, it will display `""`.
3837

39-
4038
### Adding Dynamic Routes
4139

4240
Adding dynamic routes uses the `add_page` method like any other page. The only difference is that the route string contains dynamic segments enclosed in square brackets.
4341

44-
4542
If you are using the `app.add_page` method to define pages, it is necessary to add the dynamic routes first, especially if they use the same function as a non dynamic route.
4643

4744
For example the code snippet below will:
@@ -55,12 +52,11 @@ app.add_page(index)
5552
But if we switch the order of adding the pages, like in the example below, it will not work:
5653

5754
```python
58-
app.add_page(index, route="/static/x", on_load=DynamicState.on_load)
55+
app.add_page(index, route="/static/x", on_load=DynamicState.on_load)
5956
app.add_page(index)
6057
app.add_page(index, route="/page/[page_id]", on_load=DynamicState.on_load)
6158
```
6259

63-
6460
## Catch-All Routes
6561

6662
Catch-all routes in Reflex allow you to match any number of segments in a URL dynamically.
@@ -72,74 +68,43 @@ class State(rx.State):
7268
@rx.var
7369
def user_post(self) -> str:
7470
args = self.router.page.params
75-
usernames = args.get('username', [])
71+
usernames = args.get('splat', [])
7672
return f"Posts by \{', '.join(usernames)}"
7773

78-
@rx.page(route='/users/[id]/posts/[...username]')
74+
@rx.page(route='/users/[id]/posts/[[...splat]]')
7975
def post():
8076
return rx.center(
8177
rx.text(State.user_post)
8278
)
8379

8480

8581
app = rx.App()
86-
8782
```
8883

89-
In this case, the `...username` catch-all pattern captures any number of segments after
84+
In this case, the `...splat` catch-all pattern captures any number of segments after
9085
`/users/`, allowing URLs like `/users/2/posts/john/` and `/users/1/posts/john/doe/` to match the route.
9186

92-
## Optional Catch-All Routes
93-
94-
Optional catch-all routes, enclosed in double square brackets (`[[...]]`). This indicates that the specified segments
95-
are optional, and the route can match URLs with or without those segments.
96-
97-
Example:
98-
99-
```python
100-
101-
class State(rx.State):
102-
@rx.var
103-
def user_post(self) -> str:
104-
args = self.router.page.params
105-
usernames = args.get('username', [])
106-
return f'Posts by \{', '.join(usernames)}'
107-
108-
@rx.page(route='/users/[id]/posts/[[...username]]')
109-
def post():
110-
return rx.center(
111-
rx.text(State.user_post)
112-
)
113-
114-
115-
app = rx.App()
116-
117-
```
118-
119-
Optional catch-all routes allow matching URLs with or without specific segments.
120-
Each optional catch-all pattern should be independent and not nested within another catch-all pattern.
121-
12287
```md alert
123-
# Catch-all routes must be placed at the end of the URL pattern to ensure proper route matching.
88+
# Catch-all routes must be named `splat` and be placed at the end of the URL pattern to ensure proper route matching.
12489
```
12590

12691
### Routes Validation Table
12792

128-
| Route Pattern | Example URl | valid |
129-
|:------------------------------------------------------|:-------------------------------------------------------|---------:|
130-
| `/users/posts` | `/users/posts` | valid |
131-
| `/products/[category]` | `/products/electronics` | valid |
132-
| `/users/[username]/posts/[id]` | `/users/john/posts/5` | valid |
133-
| `/users/[...username]/posts` | `/users/john/posts` | invalid |
134-
| | `/users/john/doe/posts` | invalid |
135-
| `/users/[...username]` | `/users/john/` | valid |
136-
| | `/users/john/doe` | valid |
137-
| `/products/[category]/[...subcategories]` | `/products/electronics/laptops` | valid |
138-
| | `/products/electronics/laptops/lenovo` | valid |
139-
| `/products/[category]/[[...subcategories]]` | `/products/electronics` | valid |
140-
| | `/products/electronics/laptops` | valid |
141-
| | `/products/electronics/laptops/lenovo` | valid |
142-
| | `/products/electronics/laptops/lenovo/thinkpad` | valid |
143-
| `/products/[category]/[...subcategories]/[...items]` | `/products/electronics/laptops` | invalid |
144-
| | `/products/electronics/laptops/lenovo` | invalid |
145-
| | `/products/electronics/laptops/lenovo/thinkpad` | invalid |
93+
| Route Pattern | Example URl | valid |
94+
| :----------------------------------------------- | :---------------------------------------------- | ------: |
95+
| `/users/posts` | `/users/posts` | valid |
96+
| `/products/[category]` | `/products/electronics` | valid |
97+
| `/users/[username]/posts/[id]` | `/users/john/posts/5` | valid |
98+
| `/users/[[...splat]]/posts` | `/users/john/posts` | invalid |
99+
| | `/users/john/doe/posts` | invalid |
100+
| `/users/[[...splat]]` | `/users/john/` | valid |
101+
| | `/users/john/doe` | valid |
102+
| `/products/[category]/[[...splat]]` | `/products/electronics/laptops` | valid |
103+
| | `/products/electronics/laptops/lenovo` | valid |
104+
| `/products/[category]/[[...splat]]` | `/products/electronics` | valid |
105+
| | `/products/electronics/laptops` | valid |
106+
| | `/products/electronics/laptops/lenovo` | valid |
107+
| | `/products/electronics/laptops/lenovo/thinkpad` | valid |
108+
| `/products/[category]/[[...splat]]/[[...splat]]` | `/products/electronics/laptops` | invalid |
109+
| | `/products/electronics/laptops/lenovo` | invalid |
110+
| | `/products/electronics/laptops/lenovo/thinkpad` | invalid |

pcweb/pcweb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
("/docs/recipes/others", "/docs/recipes"),
132132
("/docs/recipes/content", "/docs/recipes"),
133133
# redirect previous chakra links to the new chakra docs
134-
("/docs/library/chakra/[...component]", "https://chakra.reflex.run/introduction/"),
134+
("/docs/library/chakra/[[...splat]]", "https://chakra.reflex.run/introduction/"),
135135
("/gallery", "/templates"),
136136
# Redirect any removed pages to their new home.
137137
("/docs/components/style-props", "/docs/components/props"),

requirements.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
black==23.10.0
2+
email-validator==2.2.0
3+
flexdown==0.1.5a12
4+
googletrans-py==4.0.0
5+
mistletoe==1.4.0
6+
openai==1.78.1
7+
pandas==2.3.0
8+
plotly-express==0.4.1
9+
psycopg==3.2.9
10+
#reflex @ git+https://github.com/reflex-dev/reflex@7f88d9dbfd72ccfd198cfb920a2058bed8a71bc1
11+
reflex-ag-grid==0.0.10
12+
reflex-image-zoom==0.0.2
13+
reflex-pyplot==0.1.3
14+
replicate==1.0.6
15+
requests==2.32.4

0 commit comments

Comments
 (0)