Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Asset variables are breaking the use of the controller #136

Closed
stof opened this Issue · 9 comments

8 participants

@stof
Collaborator

When using the AsseticController, asset variables are used as placeholders in the route but are not passed to the router when generating the url

/cc @schmittjoh

@schmittjoh

It worked in my initial implementation afaik (I was using it with controllers at least), not sure what changed since then.

Right now, I'm using exclusively the --watch option.

@stof
Collaborator

There's nothing using the vars for the route generation here: https://github.com/symfony/AsseticBundle/blob/master/Twig/AsseticNode.php#L34-42

@fduch

@schmittjoh, is it possible that you dump your assets via assetic:dump --watch command and your web server fetches requested asset files already exist and compiled from the filesystem bypassing assetic controller?

I have the same issue when i am using asset variables.
During url generation for my assets i have MissingMandatoryParametersException
with message like this "The "assetic****" route has some missing mandatory parameters ("variable_name")." thrown.

It looks like these issues are related:
https://groups.google.com/forum/#!topic/symfony2/u7IxnRGALW8
schmittjoh/JMSTwigJsBundle#21

@jverdeyen

Any news on how to fix this issue?
I'm using use_controller: false and --watch when dumping the assets.

@weaverryan

An additional bug that makes this not work is the following. In order to use variables with an output, the output must include the variable (e.g. {env}):

        {% stylesheets filter='cssrewrite'
            'bundles/product/layout.css'
            'bundles/product/main_{env}.css'
            output='css/packed/layout_{env}.css'
            vars=['env']
        %}
            <link href="{{ asset_url }}" type="text/css" rel="stylesheet" />
        {% endstylesheets %}

With use_controller set to true, the assetic route that's generate for the output is: /css/packed/layout_{env}_main_{env}_2.css - with a double {env}. This is illegal in routing, which causes an error.

The issue happens in AssetCollectionIterator::current, where $this->output (which is now _controller/css/packed/layout_{env}_*.css) is mixed with $name (now main_{env}_2): https://github.com/kriswallsmith/assetic/blob/master/src/Assetic/Asset/Iterator/AssetCollectionIterator.php#L65. The fix may be in a totally different file, but you can see where things come together.

There seem to be a number of issues around the web about assetic variables. They're broken and we don't have any documentation. Now that I know how they work, I can handle the docs part, but I'm not sure if we should doc a broken feature anyways.

The fix for Assetic Variables (and how they work)

Not to hijack things, but here's a quick note on the fix for variables. First, set assetic.use_controller: false in your app/config/config_dev.yml file and use an example similar to the above. Details on use_controller: false can be found here: http://symfony.com/doc/current/cookbook/assetic/asset_management.html#dumping-asset-files-in-the-dev-environment

In Twig, both your output and any files that need the variable in them should include it in their filename (e.g. main_{env}.css). In this example, this would mean that you literally have physical main_dev.css and main_prod.css files.

You'll also need to set your assetic.variables.env (in my example) to the total possible combinations of your variable:

# app/config/config.yml
# ...
assetic:
    variables:
        env:      [dev, prod]

This configuration is used so that when you dump your files via assetic:dump, assetic knows to build two versions of your asset (e.g. layout_dev.css and layout_prod.css).

Also, you may be wondering how Assetic magically knows the value of the {env} variable, afterall, we never configured anything to tell Assetic that {env} is supposed to use the Symfony "environment" key. But still, when you refresh the page in the dev environment, Assetic will correctly use the main_dev.css file, for example. The answer is that only two variables work by default (locale and env, and their values are preconfigued in Symfony: https://github.com/symfony/AsseticBundle/blob/master/DefaultValueSupplier.php#L31. If you need a third variable, it will not work without you creating your own value supplier (which you can do by creating a new service for your value supplier, then reimplementing the service definition for assetic.value_supplier (which is an alias), and pointing that alias at your new service.

Thanks!

@sebastien-roch

@weaverryan I tried implementing my own ValueSupplier as described in your last comment. If I die('called')inside the myValueSupplier::getValues function, it exits with 'called', so it's correctly taken into account. But still, I couldn't make it work, I always get Unable to find file "@MyBundle/Resources/public/js/lib/pickadate/translations/{language}.js

I sent a PR which is maybe already a little step to fix this.

@snorl4x

I'm a little bit stucked on this issue. I only need to know if it's there any possibility of using assetic vars when use_controller: true.

As I have built it, is working perfect in prod cause use_controller : false. But I need to set use_controller: true in dev in order not to create so many files in the environment. Then I get this Symfony error:

An exception has been thrown during the rendering of a template ("Some mandatory parameters are missing ("country") to generate a URL for route "_assetic_8ffd87d_0".").

I think I have read everythng related with no help. Thanks to all of you!

@stof
Collaborator

Fixed in #250

@stof stof closed this
@sokil

Is it necessary to create file file{env}.js on disk? Without it i have got error
Unable to find file "@SomeBundle/Resources/public/js/file{locale}.js. But when i create it, all works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.