-
Notifications
You must be signed in to change notification settings - Fork 83
Resolvers
The resolvers are perhaps the most important elements in the AssetManager module. The name might give it away already, but if it doesn't, here's a very short explanation of what resolvers are and do. Resolvers will try to expand a given value to an absolute path to an asset. If one of the resolvers finds a match, the given value will be considered resolved. The resolvers written for the AssetManager module are quite powerful, so let's dive right in.
Resolving to assets has been made very simple. It can be made more powerful by adding custom resolvers, but out of the box it supports adding resolver configuration very easily through your module's configuration.
There are several resolver types available for you to use. I've listed all of them, because every single one of them has its own benefits. Before going into details explaining them one by one, here's a list of resolvers and their resolver_config keys (resolvername - keyname):
- MapResolver - map
- CollectionResolver - collections
- PrioritizedPathsResolver - prioritized_paths
- PathStackResolver - paths
- AliasPathStackResolver - namespaced paths
Mini legend: The numbers behind the resolver types are priorities. The highest priority gets checked first. For the simplicity of reading, I've written the sections from highest to lowest.
The map resolver is probably the easiest one to explain. This is simply a key => value array, mapping request paths to files. I'll only give you a small example, as this should suffice:
<?php
return array(
'asset_manager' => array(
'resolver_configs' => array(
'map' => array(
'css/used-path-alias' => __DIR__ . '/../public/css/used-path-alias',
),
),
),
);
?>
The collection resolver is what brings your assets closer together. Literally, it combines them all into one big file. This has several advantages:
- Less http requests
- One alias to apply filters to
- One alias to apply caching to
Here's an example on how to configure a collection:
<?php
return array(
'asset_manager' => array(
'resolver_configs' => array(
'collections' => array(
'js/d.js' => array(
'js/a.js',
'js/b.js',
'js/c.js',
),
),
'paths' => array(
__DIR__ . '/../public',
),
),
),
);
As you might notice, I've also added a paths
entry. This has a reason. All files inside of a collection must be resolved individually, too. This allows for a lot of flexibility and structure. For example, you'll be able to have nested collections as well. This is very useful when filtering specific collections differently from the whole. Example:
<?php
return array(
'asset_manager' => array(
'resolver_configs' => array(
'collections' => array(
'css/everything.css' => array(
'css/everything-less.css',
'css/everything-css.css',
'css/cssfile3.css', // Just to illustrate that assets and collections can be combined.
),
'css/everything-less.css' => array(
'css/lessfile1.css',
'css/lessfile2.css',
),
'css/everything-css.css' => array(
'css/cssfile1.css',
'css/cssfile2.css',
),
),
'paths' => array(
__DIR__ . '/../public',
),
'map' => array(
'css/lessfile1.css' => __DIR__ . '/../less/lessfile1.less',
'css/lessfile2.css' => __DIR__ . '/../less/lessfile2.less',
),
),
'filters' => array(
'css/everything-less.css' => array(
array(
'filter' => 'Lessphp',
),
),
'css/everything.css' => array(
array(
'filter' => 'UglifyCss',
),
),
),
),
);
Now the css as a whole will be uglified, while the less files alone will be filtered using the Lessphp filter. Like this, you also work more optimal as the Lessphp filter won't be parsing your entire collection.
The prioritizedPathsResolver does exactly what you'd expect it to do. Also, it shares most of its behavior with the PathStackResolver. Given some paths, and priorities, this resolver will try to resolve the asset by going through the supplied paths. It will check the paths based on the priority, where the highest priority will be checked first, and the lowest priority last.
<?php
return array(
'asset_manager' => array(
'resolver_configs' => array(
'prioritized_paths' => array(
array(
'path' => __DIR__ . '/../public_assets',
'priority' => 100,
),
array(
'path' => __DIR__ . '/../fallback_assets',
'priority' => 50,
),
array(
'path' => __DIR__ . '/../assets',
'priority' => 10,
),
),
),
),
);
The AliasPathStackResolver works in the same way as the PrioritizedPathsResolver and the PathStackResolver. The difference with this resolver is it allows you to alias or namespace your modules paths. This can be helpful if you have a lot of modules that have files of the same name.
<?php
return array(
'asset_manager' => array(
'resolver_configs' => array(
'aliases' => array(
'my/alias1/' => __DIR__ . '/../public/',
'my/alias2/' => __DIR__ . '/../public2/',
),
),
),
);
The PathStackResolver behaves similar to the PrioritizedPathsResolver. The only difference, is the order in which the directories are checked. The PathStackResolver doesn't care about this, and will simply go through the directories, one by one in the order they've been added.
<?php
return array(
'asset_manager' => array(
'resolver_configs' => array(
'paths' => array(
__DIR__ . '/../public',
__DIR__ . '/../otherdir',
),
),
),
);
This, obviously has to be possible. And it is. You're able to supply a custom Resolver, as long as it implements the AssetManager\Resolver\ResolverInterface. You'll be able to supply it by creating a service and setting a priority. Here's an example:
<?php
return array(
'service_manager' => array (
'factories' => array (
'My\Service\MyResolver' => 'My\Service\MyResolverServiceFactory',
),
),
'asset_manager' => array(
'resolvers' => array(
'My\Service\MyResolver' => 2000,
),
),
);
Obviously the configuration key depends on your service entirely. I would like to ask you to contribute any custom resolvers to the AssetManager, if you think that it's useful.