urls.js
? ๐คท
Instead of defining routes in your code...
Instead of defining routes in your code...
...routes are defined by your code.
Instead of defining routes in your code...
...routes are defined by your code structure.
/blog
/
pages/index.jsx โ /
pages/blog/index.jsx โ /blog
pages/index.jsx โ /
pages/blog/index.jsx โ /blog
How is this possible?
export
s
// pages/index.jsx
export function HomePage() {
return Hello, world!
;
}
export
s
// pages/index.jsx
export default function HomePage() {
return Hello, world!
;
}
pages/
โโโ blog/
โ โโโ index.jsx โ /blog
โ โโโ first-post.jsx โ /blog/first-post
โโโ settings/
โ โโโ account/
โ โโโ password.jsx โ /settings/account/password
โโโ index.jsx โ /
pages/
โโโ blog/
โ โโโ index.jsx โ /blog
โ โโโ [slug].jsx โ /blog/:slug
โโโ profile/
โ โโโ [username]/
โ โโโ index.jsx โ /profile/:username
โ โโโ likes.jsx โ /profile/:username/likes
โโโ settings/
โ โโโ account/
โ โโโ password.jsx โ /settings/account/password
โโโ unknown/
โ โโโ [...all].jsx โ /unknown/*
โโโ index.jsx โ /
root.jsx โ /
routes/
โโโ blog/
โ โโโ index.jsx โ /blog
โ โโโ $slug.jsx โ /blog/:slug
โโโ profile/
โ โโโ $username/
โ โ โโโ likes.jsx โ /profile/:username/likes
โ โโโ $username.jsx โ /profile/:username
โโโ settings/
โ โโโ account/
โ โโโ password.jsx โ /settings/account/password
โโโ unknown/
โโโ $.jsx โ /unknown/*
pages/
โโโ blog/
โ โโโ index.vue โ /blog
โ โโโ _slug.vue โ /blog/:slug
โโโ profile/
โ โโโ _username/
โ โโโ index.vue โ /profile/:username
โ โโโ likes.vue โ /profile/:username/likes
โโโ settings/
โ โโโ account/
โ โโโ password.vue โ /settings/account/password
โโโ unknown/
โ โโโ _.vue โ /unknown/*
โโโ index.vue โ /
routes/ โ /
โโโ blog/ โ /blog
โ โโโ +page.svelte
โ โโโ [slug]/ โ /blog/:slug
โ โโโ +page.svelte
โโโ profile/
โ โโโ [username]/ โ /profile/:username
โ โโโ +page.svelte
โ โโโ likes/ โ /profile/:username/likes
โ โโโ +page.svelte
โโโ settings/
โ โโโ account/
โ โโโ password/ โ /settings/account/password
โ โโโ +page.svelte
โโโ unknown/
โ โโโ [...rest]/ โ /unknown/*
โ โโโ +error.svelte
โ โโโ +page.svelte
โโโ +page.svelte
pages/
โโโ blog/
โ โโโ {MarkdownRemark.parent__(File)__name}.js โ /blog/:filename
โโโ products/
โ โโโ {Product.category}/
โ โโโ {Product.fields__sku}.js โ /products/:category/:sku
โโโ profile/
โ โโโ [id]/
โ โ โโโ group/
โ โ โโโ [groupId].js โ /profile/:id/group/:groupId
โ โโโ [id].js โ /profile/:id
โโโ unknown/
โโโ [...rest].js โ /unknown/*
code structure โ๏ธ url structure
import BlogPost from 'pages/blog/[slug]';
pages/
โโโ about.jsx
โโโ index.jsx
โโโ posts/
โ โโโ [slug].jsx
โ โโโ index.jsx
โโโ projects/
โโโ [id].jsx
โโโ index.jsx
pages/
โโโ about.jsx
โโโ index.jsx
โโโ posts/
โ โโโ [slug].jsx
โ โโโ index.jsx
โโโ projects/
โโโ [id].jsx
โโโ index.jsx
myapp/views/
โโโ about.py
โโโ index.py
โโโ posts/
โ โโโ [slug].py
โ โโโ index.py
โโโ projects/
โโโ [id].py
โโโ index.py
pages/
โโโ about.jsx
โโโ index.jsx
โโโ posts/
โ โโโ [slug].jsx
โ โโโ index.jsx
โโโ projects/
โโโ [id].jsx
โโโ index.jsx
myapp/views/
โโโ about.py
โโโ __init__.py
โโโ posts/
โ โโโ [slug].py
โ โโโ __init__.py
โโโ projects/
โโโ [id].py
โโโ __init__.py
pages/
โโโ about.jsx
โโโ index.jsx
โโโ posts/
โ โโโ [slug].jsx
โ โโโ index.jsx
โโโ projects/
โโโ [id].jsx
โโโ index.jsx
myapp/views/
โโโ about.py
โโโ __init__.py
โโโ posts/
โ โโโ <slug:slug>.py
โ โโโ __init__.py
โโโ projects/
โโโ <int:id>.py
โโโ __init__.py
pages/
โโโ about.jsx
โโโ index.jsx
โโโ posts/
โ โโโ [slug].jsx
โ โโโ index.jsx
โโโ projects/
โโโ [id].jsx
โโโ index.jsx
myapp/views/
โโโ about.py
โโโ __init__.py
โโโ posts/
โ โโโ __slug__slug__.py
โ โโโ __init__.py
โโโ projects/
โโโ __int__id__.py
โโโ __init__.py
pages/
โโโ about.jsx
โโโ index.jsx
โโโ posts/
โ โโโ [slug].jsx
โ โโโ index.jsx
โโโ projects/
โโโ [id].jsx
โโโ index.jsx
myapp/views/
โโโ about.py
โโโ __init__.py
โโโ posts/
โ โโโ slug.py
โ โโโ __init__.py
โโโ projects/
โโโ id.py
โโโ __init__.py
export default function HomePage() {
return Hello, world!
;
}
export default function HomePage() {
return Hello, world!
;
}
def default(request):
return HttpResponse("Hello, world!")
export default function HomePage() {
return Hello, world!
;
}
def view(request):
return HttpResponse("Hello, world!")
export default function HomePage() {
return Hello, world!
;
}
def dispatch(request):
return HttpResponse("Hello, world!")
urls.py
urls.py
urlpatterns = [
fs_paths("myapp.views"),
# or fs_paths("myapp/views") ?
# or *fs_paths("myapp/views") ?
]
fs_paths
fs_paths
def fs_paths(module_path):
...
fs_paths
def fs_paths(module_path):
# 1. Get the module object from module_path (dynamic import)
fs_paths
def fs_paths(module_path):
# 1. Get the module object from module_path (dynamic import)
# 2. Use getattr(module, "dispatch") to get the view function
fs_paths
def fs_paths(module_path):
# 1. Get the module object from module_path (dynamic import)
# 2. Use getattr(module, "dispatch") to get the view function
# 3. Construct path(route, view)
fs_paths
def fs_paths(module_path):
# 1. Get the module object from module_path (dynamic import)
# 2. Use getattr(module, "dispatch") to get the view function
# 3. Construct path(route, view)
# 4. Repeat for all submodules
fs_paths
from importlib import import_module
def fs_paths(module_path):
module = import_module(module_path)
# 2. Use getattr(module, "dispatch") to get the view function
# 3. Construct path(route, view)
# 4. Repeat for all submodules
fs_paths
from importlib import import_module
def fs_paths(module_path):
module = import_module(module_path)
view = getattr(module, "dispatch")
# 3. Construct path(route, view)
# 4. Repeat for all submodules
fs_paths
from importlib import import_module
from django.urls import path
def fs_paths(module_path):
module = import_module(module_path)
view = getattr(module, "dispatch")
return path("", view, name="index")
# 4. Repeat for all submodules
fs_paths
from importlib import import_module
from django.urls import path
def fs_paths(module_path):
result = []
module = import_module(module_path)
view = getattr(module, "dispatch", None)
if callable(view):
result.append(path("", view, name="index"))
return path("", include((result, module_path)))
fs_paths
from importlib import import_module
from django.urls import path
def fs_paths(module_path, namespace=None):
result = []
module = import_module(module_path)
view = getattr(module, "dispatch", None)
if callable(view):
result.append(path("", view, name="index"))
if not namespace:
namespace = module_path
return path("", include((result, namespace)))
fs_paths
from pkgutil import walk_packages
from importlib import import_module
from django.urls import path
def fs_paths(module_path, namespace=None):
result = []
module = import_module(module_path)
view = getattr(module, "dispatch", None)
if callable(view):
result.append(path("", view, name="index"))
if not namespace:
namespace = module_path
prefix = f"{module_path}.")
for pkg in walk_packages(module.__path__, prefix=prefix):
finder, name, _ = pkg # pkgutil.ModuleInfo
module = finder.find_module(name).load_module(name)
view = getattr(module, "dispatch", None)
route_name = name[len(prefix):]
route = route_name.replace('.', '/')
if callable(view):
result.append(path(route, view, name=route_name))
result.sort(key=lambda x: str(x.pattern), reverse=True)
return path("", include((result, namespace)))
urls.py
urlpatterns = [
fs_paths("myapp.views", "myapp"),
]
It "just works โข๏ธ"
# myapp/views/posts/slug.py
path = "posts/<slug:slug>"
def dispatch(request, slug):
...
# myapp/views/projects/id.py
path = "projects/<int:id>"
def dispatch(request, id):
...
route = route_name.replace('.', '/')
if callable(view):
result.append(path(route, view))
route = getattr(module, "path", route_name.replace('.', '/'))
if callable(view):
result.append(path(route, view, name=route_name))
# myapp/views/projects/id.py
path = "<int:id>"
def dispatch(request, id):
...
dispatch
?dispatch
?
def dispatch(request, *args, **kwargs):
...
dispatch
?
def get(request, *args, **kwargs):
...
def post(request, *args, **kwargs):
...
...
re_path = r"(?P<year>[0-9]{4})"
def dispatch(request, *args, **kwargs):
...
{ "name": "Sage Abdullah", "username": "laymonage", "slides": { "hosted": "https://slides.laymonage.com/fs-paths", "source": "https://github.com/laymonage/slides-fs-paths" }, "project": "https://github.com/laymonage/django-fs-paths", "alternative": "https://github.com/jerivas/django-file-router", "misc": { "jobs": "https://torchbox.com/careers", "wagtail": "https://wagtail.org" } }