Skip to content

Adding Assetic coffeescript/apply_to cookbook article #462

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

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 172 additions & 0 deletions cookbook/assetic/apply_to_option.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
How to Apply an Assetic Filter to a Specified File Extension
============================================================

One of Assetic's filters compiles CoffeeScript files into JavaScript.
This offers the advantages of caching the end result so the compilation
does not run every time whilst also automatically recompiling when ever
the script changes during development.

Whilst Assetic's ``CoffeeScriptFilter`` will do the work for you it does
not do the actual compilation, you will still need to install CoffeeScript
itself along with node.js on which it runs.

The main configuration is just the paths to coffee and node. These default
respectively to ``/usr/bin/coffee`` and ``/usr/bin/node``:

.. configuration-block::

.. code-block:: yaml

# app/config/config.yml
assetic:
filters:
coffee:
bin: /usr/bin/coffee
node: /usr/bin/node

.. code-block:: xml

<!-- app/config/config.xml -->
<assetic:config>
<assetic:filter
name="coffee"
bin="/usr/bin/coffee"
node="/usr/bin/node" />
</assetic:config>

.. code-block:: php

// app/config/config.php
$container->loadFromExtension('assetic', array(
'filters' => array(
'jpegoptim' => array(
'bin' => '/usr/bin/coffee',
'node' => '/usr/bin/node',
),
),
));


You can then serve up CoffeeScript files as JavaScript from within your
templates:

.. configuration-block::

.. code-block:: html+jinja

{% javascripts '@AcmeFooBundle/Resources/public/js/example.coffee'
filter='coffee'
%}
<script src="{{ asset_url }} type="text/javascript"></script>
{% endjavascripts %}

.. code-block:: html+php

<?php foreach ($view['assetic']->javascripts(
array('@AcmeFooBundle/Resources/public/js/example.coffee'),
array('coffee')) as $url): ?>
<script src="<?php echo $view->escape($url) ?>" type="text/javascript"></script>
<?php endforeach; ?>


This is all was needed and the file was served up as regular JavaScript.
You can combine multiple CoffeeScript files into a single output file:

.. configuration-block::

.. code-block:: html+jinja

{% javascripts '@AcmeFooBundle/Resources/public/js/example.coffee'
'@AcmeFooBundle/Resources/public/js/another.coffee'
filter='coffee'
%}
<script src="{{ asset_url }} type="text/javascript"></script>
{% endjavascripts %}

.. code-block:: html+php

<?php foreach ($view['assetic']->javascripts(
array('@AcmeFooBundle/Resources/public/js/example.coffee',
'@AcmeFooBundle/Resources/public/js/another.coffee'),
array('coffee')) as $url): ?>
<script src="<?php echo $view->escape($url) ?>" type="text/javascript"></script>
<?php endforeach; ?>


Both the files will now be served up as a single file compiled into regular
JavaScript.

One of the great advantages of using Assetic is reducing the number of asset
files to lower ``HTTP`` requests. In order to make full use of this it would
be good to combine all your JavaScript and CoffeeScript files together
since they will ultimately all be served as JavaScript. Unfortunately just
adding the JavaScript files to the files to be combined as above will not
work as the regular JavaScript files will not survive the CoffeeScript compilation.

This problem can be avoid though by using the ``apply_to`` option in the
config, this allows you to specify that a filter is always applied to particular
file extensions. In this case you can specify that the Coffee filter is
applied to all ``.coffee`` files:

.. configuration-block::

.. code-block:: yaml

# app/config/config.yml
assetic:
filters:
coffee:
bin: /usr/bin/coffee
node: /usr/bin/node
apply_to: "\.coffee$"

.. code-block:: xml

<!-- app/config/config.xml -->
<assetic:config>
<assetic:filter
name="coffee"
bin="/usr/bin/coffee"
node="/usr/bin/node"
apply_to="\.coffee$" />
</assetic:config>

.. code-block:: php

// app/config/config.php
$container->loadFromExtension('assetic', array(
'filters' => array(
'jpegoptim' => array(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe rename that to coffee?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed now

'bin' => '/usr/bin/coffee',
'node' => '/usr/bin/node',
'apply_to' => '\.coffee$',
),
),
));



So you can now remove specifying the filter in the Twig template and list
any regular JavaScript files which will now be combined into the output
file without having been run through coffee:

.. configuration-block::

.. code-block:: html+jinja

{% javascripts '@AcmeFooBundle/Resources/public/js/example.coffee'
'@AcmeFooBundle/Resources/public/js/another.coffee'
'@AcmeFooBundle/Resources/public/js/regular.js'
%}
<script src="{{ asset_url }} type="text/javascript"></script>
{% endjavascripts %}

.. code-block:: html+php

<?php foreach ($view['assetic']->javascripts(
array('@AcmeFooBundle/Resources/public/js/example.coffee',
'@AcmeFooBundle/Resources/public/js/another.coffee',
'@AcmeFooBundle/Resources/public/js/regular.js'),
as $url): ?>
<script src="<?php echo $view->escape($url) ?>" type="text/javascript"></script>
<?php endforeach; ?>