When a user loads a page of your website in their browser, it includes a number of <link ...>
, <img ...>
, <script ...>
and other tags that tell their browser how to fetch these additional resources from the server.
When dealing with assets on the server, our application needs to address two problems:
These questions are answered in this chapter.
Since the client must issue a separate request to retrieve an asset after loading a page, we need a way to generate asset URLs in
our templates. To automatically build a url for a single asset in a Twig template, you may use the assets.url()
helper. This helper takes a file path to an asset, and generates an appropriate absolute url:
<img src="{{ assets.url('assets://userfrosting/images/barn-owl.jpg') }}">
You'll notice that we reference the file path using the assets://
stream wrapper. Stream wrappers allow UserFrosting to define a sort of virtual mini-filesystem for a particular type of resource (in this case, assets).
When we refer to an asset using the path assets://userfrosting/images/barn-owl.jpg
, UserFrosting will search through each loaded Sprinkle's assets/
directory, starting with the most recently loaded Sprinkle, looking for a relative match to userfrosting/images/barn-owl.jpg
. As with other sorts of entities, this allows us to override assets from previously loaded Sprinkles.
For example, suppose we have:
account
└── assets
└── userfrosting
└── images
└── barn-owl.jpg
as well as:
site
└── assets
└── userfrosting
└── images
└── barn-owl.jpg
Assuming we've loaded the account
and site
Sprinkles (in that order), we can now use the uri assets://userfrosting/images/barn-owl.jpg
in our code, and UserFrosting will correctly resolve it to /site/assets/userfrosting/images/barn-owl.jpg
.
Notice the directory pattern used to organise the assets. Generally speaking, the basic assets that come with UserFrosting go in a
userfrosting/
subdirectory in each Sprinkle's main assets directory. You should put your own custom assets in a separate subdirectory at the same level, unless you actually need to override one of assets that ship with UserFrosting.
Custom stream uris like assets://userfrosting/images/barn-owl.jpg
will be correctly interpreted in your server-side code, but cannot be understood by clients' browsers. To serve an asset like this to the client, UserFrosting must generate a public http(s) URL for use in HTML (e.g. for <img>
, <link>
, <script>
, and other tags).
This is handled automatically by the assets.url()
helper in Twig. For example, the call to assets.url('assets://userfrosting/images/barn-owl.jpg')
might generate a URL https://owlfancy.com/assets-raw/site/assets/userfrosting/images/barn-owl.jpg
.
The question is, how does this URL get correctly resolved by the server when it is requested? After all, there is no assets-raw/
directory in our project's public root directory. By default, all requests made to URLs beginning with /assets-raw/
are sent to a special route defined in the core Sprinkle. This route then uses the assetLoader
service to resolve the request to an asset in a Sprinkle.
For example, http://localhost/myUserFrostingProject/public/assets-raw/core/assets/vendor/bootstrap-3.3.6/css/bootstrap.css
will be resolved to the core
Sprinkle, and respond with the contents of vendor/bootstrap-3.3.6/css/bootstrap.css
(if it exists).
The
assetLoader
service will automatically try to determine the MIME type of the asset based on the file extension, and set the appropriateContent-Type
header in the response.