How can I force assetic to render assets each time the page is reloaded?
Asked Answered
B

4

11

How can I force assetic to render assets each time the page is reloaded (no matter if assets are modified or not)?

More explanation about my issue:

I'm currently working on a Symfony2 project where I use Assetic to manage and compile .less files. I got everything to work fine but I'm having a small issue that I'd like to fix.

In config.yml, I set the assetic use_controller to true.

# Assetic Configuration
assetic:
debug:          %kernel.debug%
use_controller: true

The result is that Symfony dynamically renders the new .css files each time .less files are modified. This is great.

My problem is that I use a main project.less file where I import all the other .less files

// Import Twitter Bootstrap
@import "../../../../../../vendor/twitter/bootstrap/less/bootstrap.less";

// Import Foo
@import "foo.less";

...

it allows me to keep a clean structure and also to import .less files from vendors, e.g: twitter bootstrap.

In my Twig template, I only call this main file.

{% stylesheets '@ProjectWebBundle/Resources/public/less/project.less' filter='less' %}
        <link rel="stylesheet" type="text/css" media="screen" href="{{ asset_url }}" />
{% endstylesheets %}    

Since this main .less file is never modified, Assetic doesn't recompile the assets. This is why I'd like it to render the files not matter if they've been modified or not.

Barony answered 22/8, 2012 at 14:50 Comment(2)
Try {% stylesheets '@ProjectWebBundle/Resources/public/less/project.less' filter='less' debug=true %}Accusation
Thanks for your quick answer @Accusation but it doesn't solve the problem.Barony
M
11

AFAIK there's no perfect solution for this yet

I use:

php app/console assetic:dump --watch

which will compile your .less files each time it detects a change in any of the .less files referenced on your templates.

To force a compilation you have to make any change in your "main" file (the file that @imports the others). But, the good news are that is just enough to "touch" the file to do that. So you can just manually touch it every time you need:

touch ~/web/css/main.less;

Or, what i usually do is to set up a script that touches this "main" file each 60 seconds or so:

while true; do
    sleep 60
    touch ~/web/css/main.less
done

This should work on linux and mac.

Hope it helps. At least temporarily :)

Maladjusted answered 13/12, 2012 at 14:58 Comment(0)
I
11

I'm using Assetic's Lessphp filter that caches files too. For myself I've created a class that extends default Assetic's filter and touches every file with current time

<?php

namespace Xxx\AssetsBundle\Assetic\Filter;

use Assetic\Asset\AssetInterface;
use Assetic\Filter\LessphpFilter;

class LessphpNonCachedFilter extends LessphpFilter
{
    public function filterLoad(AssetInterface $asset)
    {
        $root = $asset->getSourceRoot();
        $path = $asset->getSourcePath();

        $filename = realpath($root . '/' . $path);

        if (file_exists($filename)) {
            touch($filename);
        }

        parent::filterLoad($asset);
    }
}

And you must set "assetic.filter.lessphp.class" in your parameters section (services.yml):

parameters:
    assetic.filter.lessphp.class: Xxx\AssetsBundle\Assetic\Filter\LessphpNonCachedFilter
Intercessor answered 31/12, 2012 at 9:47 Comment(2)
Note: touch requires write permissions. You will need to make sure your 'project.less' file has xx6 permissions set. (I set mine to 0666.)Monopolize
I'm using LESS through node, The touch principle stays the same, touch the file (e.g:bootstrap.less) in your controller __construct() - It will force the recompile each page loadJermainejerman
T
3

I've created a simple script to solve this problem. Please try it out and let me know if it helped.

#!/bin/bash

# assetic-watch: A very simple shell-script to recursively and efficiently
# watch for asset changes and to trigger automatic recompilation.
#
# By Slava Fomin II <[email protected]>  
# Feel free to contact me.
# From Russia with Love.
# Let's make this World a Better place!
# --------------------------------------

#===============#
# CONFIGURATION #
#===============#

# Path relative to "Symfony/src" directory.
# File changes under specified directory will trigger recompilation
# of all assets.
WATCH_PATH="Name/Bundle/NameBundle/Resources/public/css"

# Environment.
ENV="dev"

# Additional options for "app/console".
OPTS=""

# inotifywait events to watch for.
INW_EVENTS="close_write,moved_to,create"

# Optional inotifywait arguments.
INW_OPTS=""

# Relative path to the Symfony root directory.
SYMFONY_PATH="../"

#============#
# PROCESSING #
#============#

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
CONSOLE_PATH="$SCRIPT_DIR/${SYMFONY_PATH}/app/console"
SRC_PATH="$SCRIPT_DIR/${SYMFONY_PATH}/src/$WATCH_PATH"

quietly() { "$@" > /dev/null 2>&1; }

while true; do
    quietly inotifywait --recursive -e $INW_EVENTS $INW_OPTS $SRC_PATH
    php $CONSOLE_PATH assetic:dump --env=$ENV $OPTS
done

I really hope Symfony developers will address this issue in the future versions of the Assetic bundle. I believe it's a serious limitation.

Tartuffery answered 20/10, 2012 at 5:20 Comment(3)
i cant thank you enough. last time i tried this, it wasnt working fo r me, but now my env. is a bit different. This is the ONLY solution thus far that works to autorefresh CSS that is @imported, using live.js. Thanks a bunch! I have spent way too much time looking for solutions, and i thought i would full circle back to you, because i know your script rocks. It paid off finally :-)Archiphoneme
Oh, thank you @BrianThomas, my pleasure to help = ) I'm not using assetic myself anymore, I switched to Grunt and now to Gulp to compile all my scripts automatically. It's a very flexible and powerful way to manage assets. You can even use livereload with it.Tartuffery
I agree, it's a very reasonable thing to do. Please, feel free to edit my answer and add code sample.Tartuffery
V
0

You should pass to use_controller: false and compile your assets after you finish your modification.

If you want to compile your assets:

php app/console assetic:dump
Velasco answered 22/8, 2012 at 15:37 Comment(1)
It works. However it means that every time I modify a file, I have to execute that command. This is a pain. If I add a --watch parameter to the command then I have the exact same problem as described above.Barony

© 2022 - 2024 — McMap. All rights reserved.