Creating download page - best practices - passing path from URL to controller - routes

I am using CakePHP version 4.4.7 to make a download site.

I am wanting my URLs to be: https:// domain /downloads / [directory path]

[directory path] will be webroot/downloads/[directory path]

What I am trying to figure out how to do is have everything after “downloads/” in the URL be passed to my controller as a parameter.

For example, if https://domain/downloads/windows/version/2.1 was requested, my “Downloads” controller would be called with an “index” (or other) action and “windows/version/2.1” would be passed to the action.

The list of files in that directory would then presented to the user.

It seems like Routes is the way to do this, but I am having trouble getting it to work. I’m also having trouble with https://domain/downloads without a trailing ‘/’ being treated as a file in webroot rather than the controller. The trailing ‘/’ fires the controller while no trailing ‘/’ says webroot/downloads not found.

You should show us what you’ve tried so far in terms of routing. Otherwise, we can only guess at what you’ve got wrong.

Earlier we used the greedy star (/*) to capture additional path segments, there is also the trailing star (/**). Using a trailing double star, will capture the remainder of a URL as a single passed argument. This is useful when you want to use an argument that included a / in it:

$routes->connect(
‘/pages/**’,
[‘controller’ => ‘Pages’, ‘action’ => ‘show’]
);

    $routes->setRouteClass(DashedRoute::class);

    $routes->scope('/', function (RouteBuilder $builder) {
        /*
         * Here, we are connecting '/' (base path) to a controller called 'Pages',
         * its action called 'display', and we pass a param to select the view file
         * to use (in this case, templates/Pages/home.php)...
         */
        $builder->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);

        /*
         * ...and connect the rest of 'Pages' controller's URLs.
         */
        $builder->connect('/pages/*', 'Pages::display');

        $builder->connect('/downloads/**', 'Downloads::index');
        /*
         * Connect catchall routes for all controllers.
         *
         * The `fallbacks` method is a shortcut for
         *
         * ```
         * $builder->connect('/{controller}', ['action' => 'index']);
         * $builder->connect('/{controller}/{action}/*', []);
         * ```
         *
         * You can remove these routes once you've connected the
         * routes you want in your application.
         */
         $builder->fallbacks();

I think I have it working. I was expecting everything following “downloads” to come as a parameter to my controller. I found what I was looking for at $this->request->getParam(‘pass’);

Though I do still have a questions about the trailing ‘/’. If the trailing ‘/’ is omitted, it tries to find the file under ‘webroot’. With the trailing ‘/’, it passes everything to the Controller.

I don’t understand the difference.