Closed mlsen closed 1 year ago
It looks like Folio sets the route names based on this pattern: 'folio-'.substr(sha1([baseUri]), 0, 10);
<?php
namespace Laravel\Folio;
class MountPath
{
/**
* The path based middleware for the mounted path.
*/
public PathBasedMiddlewareList $middleware;
/**
* Create a new mounted path instance.
*/
public function __construct(public string $path,
public string $baseUri,
array $middleware = [])
{
$this->middleware = new PathBasedMiddlewareList($middleware);
}
/**
* Get the route name assigned to the route at this mount path.
*/
public function routeName(): string
{
return 'folio-'.substr(sha1($this->baseUri), 0, 10);
}
}
// Laravel\Folio\FolioManager;
/**
* Register a route to handle page based routing at the given paths.
*
* @throws \InvalidArgumentException
*/
public function route(string $path = null, ?string $uri = '/', array $middleware = []): static
{
$path = $path ? realpath($path) : config('view.paths')[0].'/pages';
if (! is_dir($path)) {
throw new InvalidArgumentException("The given path [{$path}] is not a directory.");
}
$this->mountPaths[] = $mountPath = new MountPath($path, $uri, $middleware);
if ($uri === '/') {
Route::fallback($this->handler($mountPath))
->name($mountPath->routeName());
} else {
Route::get(
'/'.trim($uri, '/').'/{uri?}',
$this->handler($mountPath)
)->name($mountPath->routeName())->where('uri', '.*');
}
return $this;
}
It looks like Folio sets the route names based on this pattern: 'folio-'.substr(sha1([baseUri]), 0, 10);
Doesn't look like it's naming "routes". It's just the name of one fallback route that Folio is using to process all the urls that you haven't captured with your routes.
Named routes is the first thing I stumbled upon trying to migrate a project I had to Folio.
should be able to use it with something like route('folio-'.substr(sha1('pages'), 0, 10), ['uri' => 'users'] )
if I'm not mistaken, if for instance you set the base uri to 'pages' in the Folio service provider:
Folio::route(resource_path('views/pages'), uri: 'pages' , middleware: [
'*' => [
//
],
]);
Would be nice to have a helper or something
function folioRouteName(string $uri): string
{
return 'folio-'.substr(sha1($uri), 0, 10);
}
would whittle that down to route(folioRouteName('pages'), ['uri' => 'users'] )
.
Even better I guess would be to have a pattern or convention for naming routes based on the segments or paths, and/or maybe be able import a function in the blade file to name the route. I don't believe the package traverses the directory structure at all until it's hit with a request though, so as it stands now they couldn't be indexed or named ahead of time.
Probably would need an array argument of names we can pass to Folio::route
that correspond to pages. Defining the name within the page itself would be convenient but we would have to scan every possible page if we don't have a cache building step.
How about a nice convention, since the whole point of Folio is routing by convention and folder structure? It would easily work since I guess you wouldn't use Folio for updating or deleting or other "resource" operations.
Something like a dot notation name based on the folder structure:
users/[User:uuid] -> 'users.user'
posts -> 'posts'
You could add an optional prefix in some settings somewhere to avoid possible collisions with web.php
routes. Something like folio.*
How about a nice convention, since the whole point of Folio is routing by convention and folder structure? It would easily work since I guess you wouldn't use Folio for updating or deleting or other "resource" operations.
Something like a dot notation name based on the folder structure:
users/[User:uuid] -> 'users.user' posts -> 'posts'
You could add an optional prefix in some settings somewhere to avoid possible collisions with
web.php
routes. Something likefolio.*
This would be a nice default, but it doesn't allow much flexibility or control, also it would require that folio view path be scanned recursively when the application boots
I think the spirit of Folio is not flexibility or configuration. I think it's a tool that you reach out when you want to throw in your views and expect everything to just work.
If you want control and flexibility why not just use the good routes?
True, but it being extensible doesn't have to mean it won't "just work" as is.
It would be convenient to "just know" your route names based the directory structure or file path, The only challenge really is it would require some kind or caching step or something: the directory would have to be scanned to load the route names. Unless it was implemented manually using an array. However, it would be really neat for it to "just work" the way you've illustrated above.
And by the way, if you are defining all your routes and names manually anyway using an array, why not just use traditional routes?
Probably would need an array argument of names we can pass to
Folio::route
that correspond to pages. Defining the name within the page itself would be convenient but we would have to scan every possible page if we don't have a cache building step.
Its already recommended to run route:cache
when deploying. Can't we make a syntax like this and add a warning that route caching is needed for good performance?
<?php
use function Laravel\Folio\{withNamedRoute};
withNamedRoute('user.display');
?>
<div>
User {{ $user->id }}
</div>
@tpetry Folio pages aren't registered as "real" routes, there are only a handful of routes that use wildcard route parameters to match again pages. I'm working on #54 which is a first step in getting some support in places, but it's much more likely that a folio:cache
command or something will be introduced to add support for a name()
function or similar.
@ryangjchandler That's why I proposed manually registering routes - exactly like you can assign HTTP kernel middlewares. And still keep the prominent feature of Folio not having a central place you have to register routes. Because otherwise we could also add routes in the web.php
with something like Route::folio()
as you are working on. But you're right, your work could be the building block for more.
There may be a good way to handle this outside the scope of folio. For instance What if there was a way to map route names to route paths, without assigning a handler? Something like the following api:
// Somewhere in a service provider (or bootstrap/app.php in L11):
Route::define(name: (string) 'users.index', path: (string) '/users', params: null); // ...params
if there is not handler set for the path such a route would simply return 404
(or even an exception reminding to handle the route) , and it could be accessed using the route()
helper. Under php artisan routes:list
the path could be shown pointing to the defined name and the folio route, or fallback handler, if one exists, or simply errors::404
if one does not.
Currently developing a solution that allows you to define the name of the route on the view itself:
use function Laravel\Folio\{name};
name('users-list');
?>
<div>
// ...
</div>
@nunomaduro can you please comment on the convention idea as well?
Lets follow this issue on the pull request now: https://github.com/laravel/folio/pull/79.
Hello,
I couldn't find a way to implement named routes in Folio. That would be a pretty important feature to me, since I can't generate links to Folio pages via the route() helper.
I checked the output of "artisan route:list" and it doesn't seem like it is registering routes at all? Edit: Ah ok, all under one route, I see.
Thanks!