We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

minify the assets add later

hi . i have a base controller that all the other controller extends from it. in the base i add some general assets to the colection. every other controller has theire own related assets that add to collection . in the base controller :

  $this->assets
      ->collection('footer')
      ->addJs('js/bootstrap.min.js', true, false)
      ->addJs('js/jquery.slimscroll.min.js', true, false)
      ->addJs('js/jquery.slideandswipe.min.js', true, false)
      ->addJs('js/moment.min.js', true, false)
      ->addJs('js/moment-jalaali.js',true,false)
      ->addJs('js/friendlyDate.js');

and the other controller :

$this->assets->collection('footer') ->addJs('js/Chart.min.js') ->addJs('js/persian.js');

if i add the filter in the base controller , the 2 assets i add in the other controller wont add to the collection minified version.

i try to minify the collection using " afterExecuteRoute " so the collection minified version contain all the files . but it seems only the files in the base will merged into one file !

public function afterExecuteRoute(Event $event) { $this->assets->collection('footer') ->setTargetPath('js/merged.js') ->setTargetUri("js/merged.js") ->join(true) ->addFilter(new Jsmin()); }

am i missing something ?

Assets are probably already generated by the time the dispatcher reaches afterExecuteRoute.

Why not simply add the extra stylesheets in the controller's onConstruct() / initialize() ?

https://docs.phalcon.io/en/latest/controllers#initializing-controllers



1.2k
edited Jan '18

Hi Lajos . yes adding the filter to every controller can fix this , but its not the best way to do it . i have to add some line of codes in every controller and some actions . i need to do it once .

Assets are probably already generated by the time the dispatcher reaches afterExecuteRoute.

Why not simply add the extra stylesheets in the controller's onConstruct() / initialize() ?

https://docs.phalcon.io/en/latest/controllers#initializing-controllers

If only the "base" files get merged, what happens to the others? Do they get their own <script></script> tags or are they not output at all?

Just to test, what if you put the joining and filtering code right in your template file with raw PHP? Does that have a different result?



1.2k
edited Feb '18

hi @quasipickle. no the files wont get theire <script> tags and they are not in the collection either. i think i found the problem . the first time that jsmin get called . the file will created and doesnt get updated . in my problem : the base controller create a merged.js and thats it ! only the first time that jsmin called . in other controllers the files wont change .

i test your suggestion about adding the jsmin in the template. i got something new :) in my local machine ( Arch,Apache,Php7.2,PhalconPHP3) the files change every time and i get the correct file everytime and everything works. but on the site that is live (LightSpeed,Php5.6,Phalconphp2,Shared Hosting)i still have the problem . only the first time file will created and the other times , file wont get updated . im i missing something ? i need to compile specific files for specif controllers with specific names ? or the way im doing it is ok but i missed something ?

thanks .

If only the "base" files get merged, what happens to the others? Do they get their own <script></script> tags or are they not output at all?

Just to test, what if you put the joining and filtering code right in your template file with raw PHP? Does that have a different result?

If only the "base" files get merged, what happens to the others? Do they get their own <script></script> tags or are they not output at all?

Just to test, what if you put the joining and filtering code right in your template file with raw PHP? Does that have a different result?



125.7k
Accepted
answer
edited Feb '18

I see a couple more problems.

You're trying to minify base + action JS files, but do it for each action. So if the person views /foo/bar, they'll see base + foo/bar JS files, and if the go to /bah/humbug they'll see base + bah/humbug JS files. Minifying the scripts on every page load will save a little bit of network traffic, but you're doing TONS of work on each page load. This is probably why the file doesn't get regenerated - Phalcon's smart enough to try to avoid the additional work.

Plus, what happens if someone views /foo/bar and someone else views /bah/humbug at the same time? Someone's not getting the Javascript they need.

And finally, doing this will invalidate the cache every time, so the file will need to be re-downloaded.

I think you should have multiple collections. One collection for the base files that don't change from action-to-action. They can be minified once, downloaded once, cached, and don't change from user to user.

You should then have a collection for each action or controller - have each page that needs unique Javascript be its own collection. This will allow each user to get the javascript they need, and will still allow you to combine js files. You'll need to pass the name of the collection to the View in order to output it.



1.2k

OHHHHHHHH . that was my reaction when i find out the problem ! i was totaly wrong :) thanks <3

I see a couple more problems.

You're trying to minify base + action JS files, but do it for each action. So if the person views /foo/bar, they'll see base + foo/bar JS files, and if the go to /bah/humbug they'll see base + bah/humbug JS files. Minifying the scripts on every page load will save a little bit of networ traffic, but you're doing TONS of work on each page load. This is probably why the file doesn't get regenerated - Phalcon's smart enough to try to avoid the additional work.

Plus, what happens if someone views /foo/bar and someone else views /bah/humbug at the same time? Someone's not getting the Javascript they need.

And finally, doing this will invalidate the cache every time, so the file will need to be re-downloaded.

I think you should have multiple collections. One collection for the base files that don't change from action-to-action. They can be minified once, downloaded once, cached, and don't change from user to user.

You should then have a collection for each action or controller - have each page that needs unique Javascript be its own collection. This will allow each user to get the javascript they need, and will still allow you to combine js files. You'll need to pass the name of the collection to the View in order to output it.