Skip to content
This repository has been archived by the owner on Jul 4, 2018. It is now read-only.

Commit

Permalink
added a service provider for the Symfony Asset Component
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed Aug 22, 2015
1 parent 48a3fdc commit 7535175
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 67 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"symfony/routing": "~2.7"
},
"require-dev": {
"symfony/asset": "~2.7",
"symfony/security": "~2.7",
"symfony/config": "~2.7",
"symfony/locale": "~2.7",
Expand Down
66 changes: 0 additions & 66 deletions doc/cookbook/assets.rst

This file was deleted.

1 change: 0 additions & 1 deletion doc/cookbook/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ The cookbook section contains recipes for solving specific problems.
sub_requests
error_handler
multiple_loggers
assets

Recipes
-------
Expand Down
61 changes: 61 additions & 0 deletions doc/providers/asset.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
AssetServiceProvider
====================

The *AssetServiceProvider* provides a way to manage URL generation and
versioning of web assets such as CSS stylesheets, JavaScript files and image
files.

Parameters
----------

* **assets.version**: Default version for assets.

* **assets.format_version** (optional): Default format for assets.

* **assets.named_packages** (optional): Named packages. Keys are the package
names and values the configuration (supported keys are ``version``,
``version_format``, ``base_urls``, and ``base_path``).

Services
--------

* **assets.packages**: The asset service.

Registering
-----------

.. code-block:: php
$app->register(new Silex\Provider\AssetServiceProvider(), array(
'assets.version' => 'v1',
'assets.version_format' => '%s?version=%s',
'assets.named_packages' => array(
'css' => array('version' => 'css2', 'base_path' => '/whatever-makes-sense'),
'images' => array('base_urls' => array('https://img.example.com')),
),
));
.. note::

The Symfony Asset Component comes with the "fat" Silex archive but not with
the regular one. If you are using Composer, add it as a dependency:

.. code-block:: bash
composer require symfony/asset
Usage
-----

The AssetServiceProvider is mostly useful with the Twig provider:

.. code-block:: jinja
{{ asset('/css/foo.png') }}
{{ asset('/css/foo.css', 'css') }}
{{ asset('/img/foo.png', 'images') }}
{{ asset_version('/css/foo.png') }}
For more information, check out the `Asset Component documentation
<https://symfony.com/doc/current/components/asset/introduction.html>`_.
1 change: 1 addition & 0 deletions doc/providers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Silex
swiftmailer
translation
twig
asset
url_generator
validator
form
Expand Down
83 changes: 83 additions & 0 deletions src/Silex/Provider/AssetServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Silex\Provider;

use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Asset\Package;
use Symfony\Component\Asset\PathPackage;
use Symfony\Component\Asset\UrlPackage;
use Symfony\Component\Asset\Context\RequestStackContext;
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;

/**
* Symfony Asset component Provider.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class AssetServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['assets.packages'] = function ($app) {
$packages = array();
foreach ($app['assets.named_packages'] as $name => $package) {
$version = $app['assets.strategy_factory'](isset($package['version']) ? $package['version'] : '', isset($package['version_format']) ? $package['version_format'] : null);

$packages[$name] = $app['assets.package_factory'](isset($package['base_path']) ? $package['base_path'] : '', isset($package['base_urls']) ? $package['base_urls'] : array(), $version, $name);
}

return new Packages($app['assets.default_package'], $packages);
};

$app['assets.default_package'] = function ($app) {
$version = $app['assets.strategy_factory']($app['assets.version'], $app['assets.version_format']);

return $app['assets.package_factory']($app['assets.base_path'], $app['assets.base_urls'], $version, 'default');
};

$app['assets.context'] = function ($app) {
return new RequestStackContext($app['request_stack']);
};

$app['assets.base_path'] = '';
$app['assets.base_urls'] = array();
$app['assets.version'] = null;
$app['assets.version_format'] = null;

$app['assets.named_packages'] = array();

// prototypes

$app['assets.strategy_factory'] = $app->protect(function ($version, $format) use ($app) {
if (!$version) {
return new EmptyVersionStrategy();
}

return new StaticVersionStrategy($version, $format);
});

$app['assets.package_factory'] = $app->protect(function ($basePath, $baseUrls, $version, $name) use ($app) {
if ($basePath && $baseUrls) {
throw new \LogicException(sprintf('Asset package "%s" cannot have base URLs and base paths.', $name));
}

if (!$baseUrls) {
return new PathPackage($basePath, $version, $app['assets.context']);
}

return new UrlPackage($baseUrls, $version, $app['assets.context']);
});
}
}
5 changes: 5 additions & 0 deletions src/Silex/Provider/TwigServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Symfony\Bridge\Twig\Extension\AssetExtension;
use Symfony\Bridge\Twig\Extension\RoutingExtension;
use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Bridge\Twig\Extension\FormExtension;
Expand Down Expand Up @@ -70,6 +71,10 @@ public function register(Container $app)
$twig->addExtension(new HttpKernelExtension($app['fragment.handler']));
}

if (isset($app['assets.packages'])) {
$twig->addExtension(new AssetExtension($app['assets.packages']));
}

if (isset($app['form.factory'])) {
$app['twig.form.engine'] = function ($app) {
return new TwigRendererEngine($app['twig.form.templates']);
Expand Down
35 changes: 35 additions & 0 deletions tests/Silex/Tests/Provider/AssetServiceProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Silex\Tests\Provider;

use Silex\Application;
use Silex\Provider\AssetServiceProvider;

class AssetServiceProviderTest extends \PHPUnit_Framework_TestCase
{
public function testGenerateAssetUrl()
{
$app = new Application();
$app->register(new AssetServiceProvider(), array(
'assets.version' => 'v1',
'assets.version_format' => '%s?version=%s',
'assets.named_packages' => array(
'css' => array('version' => 'css2', 'base_path' => '/whatever-makes-sense'),
'images' => array('base_urls' => array('https://img.example.com')),
),
));

$this->assertEquals('/foo.png?version=v1', $app['assets.packages']->getUrl('/foo.png'));
$this->assertEquals('/whatever-makes-sense/foo.css?css2', $app['assets.packages']->getUrl('/foo.css', 'css'));
$this->assertEquals('https://img.example.com/foo.png', $app['assets.packages']->getUrl('/foo.png', 'images'));
}
}
14 changes: 14 additions & 0 deletions tests/Silex/Tests/Provider/TwigServiceProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Silex\Application;
use Silex\Provider\TwigServiceProvider;
use Silex\Provider\AssetServiceProvider;
use Symfony\Component\HttpFoundation\Request;

/**
Expand Down Expand Up @@ -52,4 +53,17 @@ public function testLoaderPriority()
};
$this->assertEquals('foo', $app['twig.loader']->getSource('foo'));
}

public function testAssetIntegration()
{
$app = new Application();
$app->register(new TwigServiceProvider(), array(
'twig.templates' => array('hello' => '{{ asset("/foo.css") }}'),
));
$app->register(new AssetServiceProvider(), array(
'assets.version' => 1,
));

$this->assertEquals('/foo.css?1', $app['twig']->render('hello'));
}
}

0 comments on commit 7535175

Please sign in to comment.