odan / slim4-tutorial

Slim 4 Tutorial - Source Code
96 stars 26 forks source link

Base path for assets with PHP-View renderer #17

Closed samuelgfeller closed 3 years ago

samuelgfeller commented 3 years ago

I've installed selective/basepath like explained here, and I am facing the following issue.
Templates are loaded correctly, but its assets are 404 Not Found.

With Twig-View we have the handy base_path() function, so I can tell the browser where the base path is (like you explained here) but how can I figure out the base path before routing and pass it to the slimphp/PHP-View layout so when templates are loaded I can set the base path like the following:

<base href="<?= $basePath ?>/"/>

I tried to get the basepath from the app instance and add it as a global attribute to the renderer in a middleware after right after BasePathMiddleware but the BasePathDetector only works after routing is done, and I need to add the attribute before routing since the templates are loaded while routing.

How can I figure out the base path and pass it to the PHP-View renderer to use it in the layout.

odan commented 3 years ago

Hi @samuelgfeller I hope this link answers your question:

https://odan.github.io/2020/12/09/slim4-php-view.html#url-helper

The PhpViewExtensionMiddleware will pass the Slim basePath to all templates. You can output the basePath into a slim/php-view template as follows:

<base href="<?= $basePath ?>/"/>
samuelgfeller commented 3 years ago

Apologies for the delay. Argh I didn't see that you made that blogpost.. 1 month ago. Is there somewhere I can sign up to receive a notification when you release a new article? Otherwise, I'll just check regularly ;) Thank you so much for all the info you share which is so valuable for me. I love the comparison of similar services and also your personal opinion on them.

I tried the same approach with the middleware and now, finally I found out what I did wrong. I didn’t take into account that Slim middlewares are First in Last out so the order is backwards for the response. That got me confused about where exactly to put the middleware in the stack (before routing or after, before BasePathMiddleware or after) and all the positions I tried didn't work. This works now:

return function (App $app) {
    // ...

    $app->addRoutingMiddleware();

    // After routing but before BasePathMiddleware
    $app->add(PhpViewExtensionMiddleware::class); 

    // After routing and PhpViewMiddleware but will be invoked first for the response
    $app->add(BasePathMiddleware::class); 

    // ...
};

Then the <base href="<?= $basePath ?>/"/> finally worked but assets were not loading correctly. Problem there was the trailing slash I put before the asset path. I did href="/assets/bundle/style.css" and I should have used href="assets/bundle/style.css".

Now all works as I want. Thank you again.

odan commented 3 years ago

Hi Samuel, you are welcome :-)

Is there somewhere I can sign up to receive a notification when you release a new article?

You can follow me on twitter and enable the clock and/or you add my RSS feed, for example on https://feedly.com/

Slim middlewares are First in Last out s

Yes, it's a little confusing sometimes, even to me.

Problem there was the trailing slash I put before the asset path

Correct, the base href defines the base path for all relative urls. So all assets should also be relative to the base href.

Now all works as I want. Thank you again.

That's great!