-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Asset] added the component #13234
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
[Asset] added the component #13234
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (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 Symfony\Bridge\Twig\Extension; | ||
|
||
use Symfony\Component\Asset\Packages; | ||
|
||
/** | ||
* Twig extension for the Symfony Asset component. | ||
* | ||
* @author Fabien Potencier <fabien@symfony.com> | ||
*/ | ||
class AssetExtension extends \Twig_Extension | ||
{ | ||
private $packages; | ||
|
||
public function __construct(Packages $packages) | ||
{ | ||
$this->packages = $packages; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getFunctions() | ||
{ | ||
return array( | ||
new \Twig_SimpleFunction('asset_path', array($this, 'getAssetPath')), | ||
new \Twig_SimpleFunction('asset_version', array($this, 'getAssetVersion')), | ||
); | ||
} | ||
|
||
/** | ||
* Returns the public path of an asset. | ||
* | ||
* If the package used to generate the path is an instance of | ||
* UrlPackage, you will always get a URL and not a path. | ||
* | ||
* @param string $path A public path | ||
* @param string $packageName The name of the asset package to use | ||
* | ||
* @return string The public path of the asset | ||
*/ | ||
public function getAssetPath($path, $packageName = null) | ||
{ | ||
return $this->packages->getUrl($path, $packageName); | ||
} | ||
|
||
/** | ||
* Returns the version of an asset. | ||
* | ||
* @param string $path A public path | ||
* @param string $packageName The name of the asset package to use | ||
* | ||
* @return string The asset version | ||
*/ | ||
public function getAssetVersion($path, $packageName = null) | ||
{ | ||
return $this->packages->getVersion($path, $packageName); | ||
} | ||
|
||
/** | ||
* Returns the name of the extension. | ||
* | ||
* @return string The extension name | ||
*/ | ||
public function getName() | ||
{ | ||
return 'asset'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,6 +108,7 @@ public function getConfigTreeBuilder() | |
$this->addSessionSection($rootNode); | ||
$this->addRequestSection($rootNode); | ||
$this->addTemplatingSection($rootNode); | ||
$this->addAssetsSection($rootNode); | ||
$this->addTranslatorSection($rootNode); | ||
$this->addValidationSection($rootNode); | ||
$this->addAnnotationsSection($rootNode); | ||
|
@@ -347,8 +348,8 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode) | |
->info('templating configuration') | ||
->canBeUnset() | ||
->children() | ||
->scalarNode('assets_version')->defaultValue(null)->end() | ||
->scalarNode('assets_version_format')->defaultValue('%%s?%%s')->end() | ||
->scalarNode('assets_version')->defaultNull()->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')->end() | ||
->scalarNode('assets_version_format')->defaultValue('%%s?%%s')->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')->end() | ||
->scalarNode('hinclude_default_template')->defaultNull()->end() | ||
->arrayNode('form') | ||
->addDefaultsIfNotSet() | ||
|
@@ -370,6 +371,7 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode) | |
->fixXmlConfig('assets_base_url') | ||
->children() | ||
->arrayNode('assets_base_urls') | ||
->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.') | ||
->performNoDeepMerging() | ||
->addDefaultsIfNotSet() | ||
->beforeNormalization() | ||
|
@@ -417,6 +419,7 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode) | |
->fixXmlConfig('package') | ||
->children() | ||
->arrayNode('packages') | ||
->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.') | ||
->useAttributeAsKey('name') | ||
->prototype('array') | ||
->fixXmlConfig('base_url') | ||
|
@@ -452,6 +455,54 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode) | |
; | ||
} | ||
|
||
private function addAssetsSection(ArrayNodeDefinition $rootNode) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code reminds me http://www.history.com/topics/ancient-history/the-egyptian-pyramids, 👯 #troll |
||
$rootNode | ||
->children() | ||
->arrayNode('assets') | ||
->info('assets configuration') | ||
->canBeUnset() | ||
->fixXmlConfig('base_url') | ||
->children() | ||
->scalarNode('version')->defaultNull()->end() | ||
->scalarNode('version_format')->defaultValue('%%s?%%s')->end() | ||
->scalarNode('base_path')->defaultValue('')->end() | ||
->arrayNode('base_urls') | ||
->requiresAtLeastOneElement() | ||
->beforeNormalization() | ||
->ifTrue(function ($v) { return !is_array($v); }) | ||
->then(function ($v) { return array($v); }) | ||
->end() | ||
->prototype('scalar')->end() | ||
->end() | ||
->end() | ||
->fixXmlConfig('package') | ||
->children() | ||
->arrayNode('packages') | ||
->useAttributeAsKey('name') | ||
->prototype('array') | ||
->fixXmlConfig('base_url') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could all this config below share the same code as the one before? extract it as a function maybe? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could indeed use a private method returning an array node, and then using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure it would bring us a lot. |
||
->children() | ||
->scalarNode('version')->defaultNull()->end() | ||
->scalarNode('version_format')->defaultNull()->end() | ||
->scalarNode('base_path')->defaultValue('')->end() | ||
->arrayNode('base_urls') | ||
->requiresAtLeastOneElement() | ||
->beforeNormalization() | ||
->ifTrue(function ($v) { return !is_array($v); }) | ||
->then(function ($v) { return array($v); }) | ||
->end() | ||
->prototype('scalar')->end() | ||
->end() | ||
->end() | ||
->end() | ||
->end() | ||
->end() | ||
->end() | ||
->end() | ||
; | ||
} | ||
|
||
private function addTranslatorSection(ArrayNodeDefinition $rootNode) | ||
{ | ||
$rootNode | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?xml version="1.0" ?> | ||
|
||
<container xmlns="http://symfony.com/schema/dic/services" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> | ||
|
||
<services> | ||
|
||
<service id="assets.packages" class="Symfony\Component\Asset\Packages"> | ||
<argument /> <!-- default package --> | ||
<argument type="collection" /> <!-- named packages --> | ||
</service> | ||
|
||
<service id="assets.context" class="Symfony\Component\Asset\Context\RequestStackContext"> | ||
<argument type="service" id="request_stack" /> | ||
</service> | ||
|
||
<service id="assets.path_package" class="Symfony\Component\Asset\PathPackage" abstract="true"> | ||
<argument /> <!-- base path --> | ||
<argument type="service" /> <!-- version strategy --> | ||
<call method="setContext"> | ||
<argument type="service" id="assets.context" /> | ||
</call> | ||
</service> | ||
|
||
<service id="assets.url_package" class="Symfony\Component\Asset\UrlPackage" abstract="true"> | ||
<argument /> <!-- base URLs --> | ||
<argument type="service" /> <!-- version strategy --> | ||
<call method="setContext"> | ||
<argument type="service" id="assets.context" /> | ||
</call> | ||
</service> | ||
|
||
<service id="assets.static_version_strategy" class="Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy" abstract="true"> | ||
<argument /> <!-- version --> | ||
<argument /> <!-- format --> | ||
</service> | ||
|
||
<service id="assets.empty_version_strategy" class="Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy" public="false" /> | ||
|
||
</services> | ||
</container> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it be possible to keep the old function name? and IMHO the possibility to pass a specific version for the asset was useful, could we restore that functionality back?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeping the old name would not allow us to keep both layers as explained in the description of this PR. Passing a specific version is a non-sense and using a custom version strategy is the best way to achieve that feature (also explained in the description of the PR).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thing with the new name it is that it's a little bit misleading because it can indeed generate absolute url's (not only paths) if you are using an UrlPackage, it just can't generate an absolute url if you are using a PathPackage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you. Any ideas for another name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think that we sould keep the old name, it's the best one. And it's a pitty that we have to struggle to find a new name just for BC reasons. I would prefer to have a ""harder"" approach like the one had before (only one layer at a time possible) and keep the same name.
Besides, keeping the old name makes it easier to upgrade, as the removed "absolute" and "version" params were mostly unused, and the asset name and package name remain in the new function, so there is almost full BC in the twig files if you choose to use the new layer, no need to rename anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@acasademont only one layer at a time means forcing all the open-source ecosystem to update at the same time to stay compatible (and then projects depending on them need to migrate when updating the dependencies).
The other solution is to find a way to implement a BC layer for the old API in the new system, to be able to reuse the names in a BC way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even with what you propose I don't see a clear update path. OS bundles will keep using the
asset
function because they won't know if in your project you have enabled the new component and can start usingasset_path
. So when Symfony 3 comes they'll have to update to the new function name to stay compatible.Besides, I'm pretty sure that in 99.9% of the
asset
function calls out there in external bundles there are no packages and no use of theabsolute
orversion
params (or like the WebProfilerBundle, they removed all asset calls and changed them for inline base64-encoded images). So keeping the same name is the best option for them, they probably won't even have to bother about the change, the simpleasset('/path/to/my/bundle/foo.jpg')
call has the exact same syntax and result in the new layer if we keep the name.Made a quick search here https://github.com/search?p=6&q=asset+NOT+url+extension%3Atwig&ref=searchresults&type=Code&utf8=%E2%9C%93 (unfortunately you can't search the parentheses symbol, which would narrow down the search a lot)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabpot any idea whether it would be possible to build the previous API as a BC layer on top of the new one, to avoid having to change all templates everywhere when migrating to the new API (making the upgrade path much better) ?