Laravel-Backpack / basset

Better asset helpers for Laravel apps.
MIT License
151 stars 10 forks source link

[BUG] How to add Tailwind css globally with basset? #116

Closed blondie63 closed 3 months ago

blondie63 commented 3 months ago

I've used Tailwindcss because i'm just using it in other blades but my previous developer import it in each blade with:

Now i'd like to use basset to have last tailwind 3.4.3 version global and optimized Can you advise me how to do it?

Originally posted by @blondie63 in https://github.com/Laravel-Backpack/community-forum/discussions/906#discussioncomment-8959031

karandatwani92 commented 3 months ago

Hey @blondie63

Try this(assuming you are using theme-tabler):

  1. Publish the theme config file:
    php artisan vendor:publish --tag="theme-tabler-config"
  2. Open theme config config\backpack\theme-tabler.php and add it to styles array:
    'styles' => [
        base_path('vendor/backpack/theme-tabler/resources/assets/css/color-adjustments.css'),
        base_path('vendor/backpack/theme-tabler/resources/assets/css/colors.css'),
    +       'https://cdn.example.com/version.css'
    +       'https://cdn.tailwindcss.com/3.4.3'
    ],

While doing it, I found a Bug. I'm assigning my colleague @pxpm to fix this:

BUG

While adding https://cdn.tailwindcss.com/3.4.3' I found an issue with the basset. It is not currently working for URLs without extensions.

pxpm commented 3 months ago

Hey @karandatwani92 thanks for the heads up.

I acknowledged that at the moment it's not possible to load urls without extension that easily.

For @blondie63 a "quick" workaround is to create a file in your public/assets/js/tailwind-3.4.3.js, download the contents from https://cdn.tailwindcss.com/3.4.3 into that file, and then load the local file with: public_path('assets/js/tailwind-3.4.3.js').


I will leave here also for future me and anybody that may have interest in this topic what I've tried/found while researching this.

I didn't came up with something I would be happy with. (I mean, small changes and not hacking a solution).

I think this may need some refactoring on basset workflow to be properly supported.

When you give an url without .css or .js, to basset(), we don't know if we should output <style> or <script> tags. In this case (tailwind cdn) it should be a <script> tag.

We can get the content-type header and display the tag accordingly, but that means 1 additional request to that asset.

Something along the following lines:

 if(Str::isUrl($path)) {
            $response = Http::get($path);
            $contentType = $response->header('content-type') ?? '';
            if(Str::contains($contentType, 'javascript')){
                $this->echoJs($path, $attributes);
            }else if(Str::contains($contentType, 'css')){
                $this->echoCss($path, $attributes);
            }
        }

When in dev-mode this is cumbersome, 2 requests for the same asset. Maybe with an option to internalize external assets, even in dev mode like I suggested in #114

I tried appending .js, or .css to the file we save when caching, but then found other myriad of issue linking back the internalized asset with the extension appended, with the url without extension.

I think @promatik can help here.

promatik commented 3 months ago

Yes, this is a known limitation. Basset absolutely needs to know what kind of file it is, and it figures out the type by the extension.

By not having the the file extension it also makes it complex

Anyway, @pxpm your solution would be nice, but in that case, that file is not of the type "javascript". It's a document 🫤

image

I think the only solution would be to allow devs to expressly tell the file type with @bassetJs and @bassetCss; @bassetJs('https://cdn.tailwindcss.com/3.4.3').

promatik commented 3 months ago

Ok! https://github.com/Laravel-Backpack/basset/pull/117 and https://github.com/Laravel-Backpack/CRUD/pull/5489 fix this issue 🙌

I was able to load tailwind in the demo project 🙌

image

blondie63 commented 3 months ago

Hey @karandatwani92 thanks for the heads up.

I acknowledged that at the moment it's not possible to load urls without extension that easily.

For @blondie63 a "quick" workaround is to create a file in your public/assets/js/tailwind-3.4.3.js, download the contents from https://cdn.tailwindcss.com/3.4.3 into that file, and then load the local file with: public_path('assets/js/tailwind-3.4.3.js').

I will leave here also for future me and anybody that may have interest in this topic what I've tried/found while researching this.

I didn't came up with something I would be happy with. (I mean, small changes and not hacking a solution).

I think this may need some refactoring on basset workflow to be properly supported.

When you give an url without .css or .js, to basset(), we don't know if we should output <style> or <script> tags. In this case (tailwind cdn) it should be a <script> tag.

We can get the content-type header and display the tag accordingly, but that means 1 additional request to that asset.

Something along the following lines:

 if(Str::isUrl($path)) {
            $response = Http::get($path);
            $contentType = $response->header('content-type') ?? '';
            if(Str::contains($contentType, 'javascript')){
                $this->echoJs($path, $attributes);
            }else if(Str::contains($contentType, 'css')){
                $this->echoCss($path, $attributes);
            }
        }

When in dev-mode this is cumbersome, 2 requests for the same asset. Maybe with an option to internalize external assets, even in dev mode like I suggested in #114

I tried appending .js, or .css to the file we save when caching, but then found other myriad of issue linking back the internalized asset with the extension appended, with the url without extension.

I think @promatik can help here.

Hi @pxpm i've created public/assets/js/tailwind-3.4.3.js then I added this code:

    'styles' => [
        public_path('assets/js/tailwind-3.4.3.js')
    ],

to my config/backpack/theme-coreuiv2.php but i no have this tailwind-3.4.3.js globally in my blades

Looking browser console i see: cdn.tailwindcss.com should not be used in production. To use Tailwind CSS in production, install it as a PostCSS plugin or use the Tailwind CLI: https://tailwindcss.com/docs/installation

what's wrong ?

pxpm commented 3 months ago

Nothing wrong with Backpack. If you are seeing that in your console is because tailwind is being successfully loaded into the page, so you should be able to do tailwind stuff. Read their install instruction as stated there, but you should probably generate distribution optimized files.

Cheers

blondie63 commented 3 months ago

Nothing wrong with Backpack. If you are seeing that in your console is because tailwind is being successfully loaded into the page, so you should be able to do tailwind stuff. Read their install instruction as stated there, but you should probably generate distribution optimized files.

Cheers

@pxpm In reality it doesn't work for me, if in fact I remove this line from a blade:

It doesn't work for me anymore...

I tried to put @basset(public_path('assets/js/tailwind-3.4.3.js')) on my blade and works fine, so now i'd like to have it globally for all my blades..

How can i do that ?

pxpm commented 3 months ago

Hey @blondie63 I can't see the line you removed from blade, maybe you missed to post it.

In your config/backpack/ui.php (assuming you are not using any theme, I am not sure Bootstrap play well with Tailwind), you add to your config:

'styles' => [
    public_path('assets/js/tailwind-3.4.3.js'),
 ]

If using a theme, eg. theme tabler, that change need to be done in config/backpack/theme-tabler.php.

Last try I tried to load tailwind with tabler it completely broke the panel, so for Backpack to work with tailwind I expect that you will need to customize quite a bit (A LOT) of files.

Cheers

blondie63 commented 3 months ago

Hi @pxpm Finally I'm using coreuiV2 and i've decide to add @basset(public_path('assets/js/tailwind-3.4.3.js')) only in my blade need! All works fine now.. :)