Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.5] Allow to custom assets root URL #22372

Closed
wants to merge 1 commit into from
Closed

[5.5] Allow to custom assets root URL #22372

wants to merge 1 commit into from

Conversation

ElfSundae
Copy link
Contributor

This PR adds support to custom the root URL for generating assets URLs, now we can use the built-in asset() or secure_asset() methods to generate an independent domain or CDN URL.

app('url')->setAssetsRoot('https://assets.example.com');

I think this is helpful for framework users because using independent domain or CDN for assets is a very common thing for web apps. And for now it is hard to extend the UrlGenerator or the core RoutingServiceProvider to achieve this, right?

Why not just define my own asset_url() or cdn() helper?
Some packages publish their assets to the public path, and use the asset() method to ref them. If I want them cookie-free or to load from a cloud storage, I need to run vendor:publish even I just want to change asset() to cdn(), and I need to re-publish & modify every time these packages update.

@taylorotwell
Copy link
Member

I thought we had some way to do this already? Am I wrong? @themsaid

@tillkruss
Copy link
Collaborator

#22037

@GrahamCampbell
Copy link
Member

I'm not aware of this feature already existing, hence why I had to define as a quick hack:

if (!function_exists('cdn_asset')) {
    /**
     * Generate a cdn asset path.
     *
     * @param string $path
     *
     * @return string
     */
    function cdn_asset(string $path)
    {
        $base = config('app.cdn') ?: config('app.url');
        $file = ltrim($path, '/');

        return "{$base}/{$file}";
    }
}

@themsaid
Copy link
Member

themsaid commented Dec 11, 2017

@taylorotwell we have assetFrom since 5.1 where you can do

app('url')->assetFrom('https://assets.example.com', 'app.css')

and it will generate:

https://assets.example.com/app.css

Looking at @GrahamCampbell's custom method, I think we can have a config value instead of the proposed setAssetsRoot() method, if value is set we can use it as the root in asset().

@ElfSundae
Copy link
Contributor Author

Yeah, it seems the only built-in way to do this is using assetFrom, but I don't think it is a good/elegant way:

<script src="{{ app('url')->assetFrom(config('app.assets_url'), 'js/app.js') }}"></script>

In my opinion, there is no reason to code:

<script src="{{ asset('js/app.js') }}"></script>

instead of:

<script src="/js/app.js"></script>

I don't know how users use the app('url')->asset() or corresponding asset() helper function, for me it is useless.
I can imagine two situations to use it:

  1. It may be useful if someone runs Laravel application from a subfolder like http://example.com/blog.
    And that is why packages should use asset('vendor/package/js/foo.js') instead of '/vendor/package/js/foo.js' to ref their public assets.
  2. As the documentation says, we can use asset to create a URL for local storage, asset('storage/'.$file). But I prefer to change the default disk to public and use Storage::url($file).

@themsaid It would be wonderful if we can have a config value, I wondered my PR will be rejected if I introduce a new config like app.assets_url.
And I think we may not access application configurations directly in UrlGenerator, but should be something like:

$this->app->singleton('url', function ($app) {
    $url = new UrlGenerator(...);
    $url->setAssetsRoot($app['config']['app.assets_url']);
    // ...
});

@taylorotwell
Copy link
Member

I'm not sure we need to add anything to the framework for this. You can already define your own specific helpers that use assetFrom and assign the helpers whatever names like and make them as flexible as you like.

@ElfSundae
Copy link
Contributor Author

@taylorotwell As I said in the PR description, for the vendor packages shipping with assets, for example laravel-adminlte, users need to publish package's assets then replace all asset to custom_asset, and do this again when the package updates.

I think It is a small and harmless code change, but with big help and conveniences.

Currently the UrlGenerator::asset() just acts as a subset of the to method, and even there are two global helper functions for it: asset(), secure_asset(), why not simply use url():

url('blog', $post)
url('js/app.js')
url(mix('css/main.css'))

@themsaid @GrahamCampbell How do you think?

@ElfSundae
Copy link
Contributor Author

A workaround: define asset before including Composer's autoload file:

function asset($path, $secure = null)
{
    return app('url')->assetFrom(config('app.assets_url'), $path, $secure);
}

require __DIR__.'/../vendor/autoload.php';

@ElfSundae ElfSundae deleted the assets-root branch February 3, 2018 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants