Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Try Vanilla Forums Cloud product

Ready to contribute?

Amazing! Sign our contributors' agreement and then join us on GitHub.

Update for critical security issue in PHPMailer included in release Vanilla 2.3.1
Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.

Vanilla Packer

This discussion is related to the Vanilla Packer addon.


  • I never used it, can you post the "$Head->AddScript..." lines?
  • I got them...

    replace line 479 and 480 with just AddScriptaculous();
    I will look to that for a better solution when I have time
  • Another issue: I've been just testing the Category Roles extension and because you need to add a specific delegate to Vanilla.Control.CategoryForm.php, Vanilla Packer doesn't patch that file properly.
  • It should be patch correctly, the vanilla packer just setting just can't check it anymore.
    I should change the error message on the setting page. However, CategoryForm and the Packer should still work.
  • This is hands down the best addon you can install for Vanilla. Packing your JS/CSS decreases your page load so much, you'll wonder how you lived without it.

    Thanks, Dinoboff!
  • Any new developments on this? I've not really had any problems using this on my test site since I started using it. Would be great to get this integrated into the core ;)
  • Hi, I'm trying to test this great extension on my local server and here's what get when going to js/css packer settings:

    Notice: unserialize() [function.unserialize]: Error at offset 872 of 917 bytes in C:\AppServ\www\Vanilla\extensions\VanillaPacker\md5.php on line 2 Warning: Invalid argument supplied for foreach() in C:\AppServ\www\Vanilla\extensions\VanillaPacker\default.php on line 92

    Any idea how to fix this?
  • Does this work with 1.1.4 ?

    I need to upgrade but don't want to not have the packer when I do so.
  • It should, but I don't support this extension any more.

    Low-Cal Vanilla doesn't try to do as much as the packer (doesn't pack css files yet, extension js file are only pack is the extension is compatible...), but it shouldn't break anything like the packer can do.
  • Ah, I'll hack around and keep it working for my install. The reduction in HTTP requests is far more effective than the minifying of the javascript.
  • PS: Thanks for all the great work, it is appreciated.
  • David, if you're updating this, even though Dinoboff's no longer supporting it, it would be good if you shared your work with the community :) Thanks.
  • Hmm. No way of uploading.

    Basically all I've done is gone through the patch and separated out the files that are uploaded that do not touch shipped Vanilla files, from the files that are shipped Vanilla files that are modified.

    Then with the modified Vanilla files, I've diff'd the patch versions against the original shipped files. From that I've created a single document that summarises what is needed to patch Vanilla manually.

    So the patch step is now split into two:
    1) Upload new files
    2) Manually modify existing .php files

    The manual modifications I've bundled into text files for each significant version of Vanilla, so at the moment I have a text file for 1.1.2 and 1.1.4, though in the future more will appear to keep Packer working.

    The differences between Packer for 1.1.2 and 1.1.4, nothing at all. However if you used the original Patch files, those get replaced during the upgrade so it would break but if you follow my text files you'll be able to re-apply the patch manually.

    Here's the list of files in the upload folder now (was the Patch folder, just delete anything that isn't one of these from the old Patch folder);

    And the readme.txt becomes:

    NOTE: This installation requires modifying core Vanilla files. You will need to be comfortable editing .php files.

    1. Install this package in /extensions/VanillaPacker/
    2. Back up all your files
    3. Copy the files from /extensions/VanillaPacker/upload on top of the vanilla one (There is only the files needed to be cached)
    4. Be sure that /js/cache/, /themes/vanilla/style/default/cache and conf/packer.php are writable.
    5. Apply manually the changes documented in /extensions/VanillaPacker/ManualPatch*.txt. Only apply the changes relating to the Vanilla that you have
    6. Go to "Settings" > "extension", to "Vanilla Packer".
    7. Go to "Settings" > "js/css packer settings" to check if the installation was successful.
    8. You might have to copy some images used by the other extension into your style folder(s).
  • And if you are running Vanilla 1.1.4 apply these changes:
    FILE: \appg\database.php FIND: ?> INSERT BEFORE: // HACK : START : PACKER $DatabaseTables['FilesToPack'] = 'FilesToPack'; $DatabaseTables['CssMedia'] = 'CssMedia'; $DatabaseColumns['FilesToPack']['FileID'] = 'FileID'; $DatabaseColumns['FilesToPack']['FilePath'] = 'FilePath'; $DatabaseColumns['CssMedia']['MediaID'] = 'MediaID'; $DatabaseColumns['CssMedia']['MediaName'] = 'MediaName'; // HACK : END : PACKER FILE: \appg\init_people.php FIND: $Head->AddScript('js/global.js'); $Head->AddStyleSheet($Context->StyleUrl.'people.css', 'screen', 100, ''); REPLACE WITH: // HACK : START : PACKER // $Head->AddScript('js/global.js'); // $Head->AddStyleSheet($Context->StyleUrl.'people.css', 'screen', 100, ''); $Head->AddScript('js/global.js', '~', '290', 1, 0); //need a path relative to vanilla root $StylePath = $Context->StyleUrl; $StylePath = ereg_replace("^".$Context->Configuration['WEB_ROOT'], '', $StylePath); $Head->AddStyleSheet($StylePath.'people.css', 'screen', 100, '~', 1); // HACK : END : PACKER FILE: \appg\init_vanilla.php FIND: $Head->AddScript('js/global.js'); $Head->AddScript('js/vanilla.js'); $Head->AddScript('js/ajax.js'); $Head->AddScript('js/ac.js'); $Head->AddStyleSheet($Context->StyleUrl.'vanilla.css', 'screen', 100, ''); $Head->AddStyleSheet($Context->StyleUrl.'vanilla.print.css', 'print', 101, ''); REPLACE WITH: // HACK : START : PACKER //$Head->AddScript('js/global.js'); //$Head->AddScript('js/vanilla.js'); //$Head->AddScript('js/ajax.js'); //$Head->AddScript('js/ac.js'); //$Head->AddStyleSheet($Context->StyleUrl.'vanilla.css', 'screen', 100, ''); //$Head->AddStyleSheet($Context->StyleUrl.'vanilla.print.css', 'print', 101, ''); $Head->AddScript('js/global.js', '~', '290', 1, 0); $Head->AddScript('js/vanilla.js', '~', '291', 1, 0); $Head->AddScript('js/ajax.js', '~', '292', 1, 0); $Head->AddScript('js/ac.js', '~', '293', 1, 0); //need a path relative to vanilla root $StylePath = $Context->StyleUrl; $StylePath = ereg_replace("^".$Context->Configuration['WEB_ROOT'], '', $StylePath); $Head->AddStyleSheet($StylePath.'vanilla.css', 'screen', 100, '~', 1); $Head->AddStyleSheet($StylePath.'vanilla.print.css', 'print', 101, '~', 1); // HACK : END : PACKER FILE: \library\Framework\Framework.Control.Head.php FIND: var $Meta; // An associative array of meta tags/content to be added to the head. INSERT AFTER: // HACK : START : PACKER var $_Scripts; var $_StyleSheets; var $PackManager; // HACK : END : PACKER FIND: function AddScript($ScriptLocation, $ScriptRoot = '~') { if (!is_array($this->Scripts)) $this->Scripts = array(); if ($ScriptRoot == '~') $ScriptRoot = $this->Context->Configuration['WEB_ROOT']; $ScriptPath = $ScriptLocation; if ($ScriptRoot != '') $ScriptPath = ConcatenatePath($ScriptRoot, $ScriptLocation); if (!in_array($ScriptPath, $this->Scripts)) $this->Scripts[] = $ScriptPath; } REPLACE WITH: // HACK : START : PACKER // function AddScript($ScriptLocation, $ScriptRoot = '~') { // if (!is_array($this->Scripts)) $this->Scripts = array(); // if ($ScriptRoot == '~') $ScriptRoot = $this->Context->Configuration['WEB_ROOT']; // $ScriptPath = $ScriptLocation; // if ($ScriptRoot != '') $ScriptPath = ConcatenatePath($ScriptRoot, $ScriptLocation); // if (!in_array($ScriptPath, $this->Scripts)) $this->Scripts[] = $ScriptPath; // } /*$Position: Position in the list of script. You should try to the appropriate: 100-199: for libraries that can't be packed (e.g. YUI hosted on yahoo servers); 200-299: for libraries that can be packed (e.g. jQuery); 300-399: for script that can be pack; 400+: for script that can't be packed. */ function AddScript($ScriptLocation, $ScriptRoot = '~', $Position = '350', $ToPack = 1, $ToMinify = 0) { if (!is_array($this->_Scripts)) $this->_Scripts = array(); if ($ScriptRoot == '~') { $ScriptRoot = $this->Context->Configuration['WEB_ROOT']; } else { //the script need a relative path to the forum to merge it //If you specify you specify a web root it can't be merge $ToPack = 0; } $Location = $ScriptLocation; if ($ScriptRoot != '') $Location = ConcatenatePath($ScriptRoot, $ScriptLocation); $this->InsertItemAt($this->_Scripts, array('Location' => $Location, 'Path' => $ScriptLocation, 'ToPack' => $ToPack, 'ToMinify' => $ToMinify), $Position); } // HACK : END : PACKER FIND: function AddStyleSheet($StyleSheetLocation, $Media = '', $Position = '100', $StyleRoot = '~') { if ($StyleRoot == '~') $StyleRoot = $this->Context->Configuration['WEB_ROOT']; if (!is_array($this->StyleSheets)) $this->StyleSheets = array(); $StylePath = $StyleSheetLocation; if ($StylePath != '') $StylePath = ConcatenatePath($StyleRoot, $StyleSheetLocation); $this->InsertItemAt($this->StyleSheets, array('Sheet' => $StylePath, 'Media' => $Media), $Position); } REPLACE WITH: // HACK : START : PACKER // function AddStyleSheet($StyleSheetLocation, $Media = '', $Position = '100', $StyleRoot = '~') { // if ($StyleRoot == '~') $StyleRoot = $this->Context->Configuration['WEB_ROOT']; // if (!is_array($this->StyleSheets)) $this->StyleSheets = array(); // $StylePath = $StyleSheetLocation; // if ($StylePath != '') $StylePath = ConcatenatePath($StyleRoot, $StyleSheetLocation); // $this->InsertItemAt($this->StyleSheets, // array('Sheet' => $StylePath, 'Media' => $Media), // $Position); // } function AddStyleSheet($StyleSheetLocation, $Media = '', $Position = '100', $StyleRoot = '~', $ToPack = 1) { if (!is_array($this->_StyleSheets)) $this->_StyleSheets = array(); if ($StyleRoot == '~') { $StyleRoot = $this->Context->Configuration['WEB_ROOT']; } else { $ToPack = 0; } $Sheet = $StyleSheetLocation; if ($StyleRoot != '') $Sheet = ConcatenatePath($StyleRoot, $StyleSheetLocation); $Media = strtolower($Media); $this->InsertItemAt($this->_StyleSheets, array('Sheet' => $Sheet, 'Path' => $StyleSheetLocation, 'Media' => $Media, 'ToPack' => $ToPack), $Position); } // HACK : END : PACKER FIND: $this->Meta = array(); INSERT AFTER: // HACK : START : PACKER $this->PackManager = $this->Context->ObjectFactory->NewContextObject($this->Context, 'PackManager'); // HACK : END : PACKER FIND: } ?> INSERT BEFORE: // HACK : START : PACKER function _SortScripts(){ if (is_array($this->_Scripts)) { $Pack = new Pack($this->Context); $Pack->Extension = 'js'; $this->Scripts = array(); ksort($this->_Scripts); if($this->Context->Configuration['PACKER_ON']){ foreach ($this->_Scripts as $Script) { $url = ''; if ($Script['ToPack']){ $Pack->AddFile($Script['Path'], $Script['ToMinify']); } else { if ($url = $this->PackManager->GetPackUrl($Pack)){ $this->Scripts[] = $url; } $Pack->files_to_merge = array(); $this->Scripts[] = $Script['Location']; } } $url = ''; if ($url = $this->PackManager->GetPackUrl($Pack)){ $this->Scripts[] = $url; } } else { foreach ($this->_Scripts as $Script) { $this->Scripts[] = $Script['Location']; } } } } function _SortSheets(){ if(is_array($this->_StyleSheets)){ $Pack = $this->Context->ObjectFactory->NewContextObject($this->Context, 'Pack'); $Pack->Extension = 'css'; $this->StyleSheets = array(); ksort($this->_StyleSheets); if($this->Context->Configuration['PACKER_ON']){ //check if we should pack the sheets foreach ($this->_StyleSheets as $Sheet) { $url = ''; if($Sheet['ToPack']){ //check is this sheet will be packed with the others $Pack->AddFile($Sheet['Path'], $Sheet['Media']); // we just add it to the list of sheets to pack } else { if($url = $this->PackManager->GetPackUrl($Pack)){ // we pack the sheets that need to be packed $this->StyleSheets[] = array('Sheet' => $url, 'Media' => 'all'); } $Pack->files_to_merge = array(); // start a need pack $Pack->files_to_merge_by_id = array(); $this->StyleSheets[] = $Sheet; //add this sheet alone to the head. } } $url = ''; if($url = $this->PackManager->GetPackUrl($Pack)){ // pack the remaining script that need to be pack $this->StyleSheets[] = array('Sheet' => $url, 'Media' => 'all'); } } else { //We don't pack them foreach ($this->_StyleSheets as $Sheet) { $this->StyleSheets[] = $Sheet; } } } } // HACK : END : PACKER FILE: \library\People\People.Control.RoleForm.php FIND: global $Head; $Head->AddScript('js/prototype.js'); $Head->AddScript('js/scriptaculous.js'); REPLACE WITH: // HACK : START : PACKER // global $Head; // $Head->AddScript('js/prototype.js'); // $Head->AddScript('js/scriptaculous.js'); AddScriptaculous(); // HACK : END : PACKER FILE: \library\Vanilla\Vanilla.Control.CategoryForm.php FIND: global $Head; $Head->AddScript('js/prototype.js'); $Head->AddScript('js/scriptaculous.js'); REPLACE WITH: // HACK : START : PACKER // global $Head; // $Head->AddScript('js/prototype.js'); // $Head->AddScript('js/scriptaculous.js'); AddScriptaculous(); // HACK : END : PACKER
  • And as you may have noticed I've wrapped all changes with "HACK" tags.

    For future upgrades, once you're running this, you should be able to just diff the files that Vanilla upgrades and where you see the word HACK you know where to start and end your merging.
  • The reduction in HTTP requests is far more effective than the minifying of the javascript.

    It is what doing Low-Cal Vanilla as well. It does try to pack (jspack) or minify the js files (it is the responsability of the extension author to do that). It compress pages , css and js files; and allow js files to be packed together.

    It automatically core js files and allow extensions to add their scripts to this package using something like that:// Check the Low-Cal Vanilla is installed if ($Configuration['LOWCALVANILLA_TOOLS_PATH']) { // Include Low-Cal Vanilla tools file. // Important: Use require_once or include_once to not load it again if it is already done. require_once($Configuration['LOWCALVANILLA_TOOLS_PATH']); // Add your script LowCalVanilla_AddScript($Context, $Head, 'extensions/MyExtension/script.js'); // Add a library // Use the position argument (300 by default) to be sure it will be added first LowCalVanilla_AddScript($Context, $Head, 'extensions/MyExtension/jQuery-min.js', 100); } else { $Head->AddScript('extensions/MyExtension/jQuery-min.js'); $Head->AddScript('extensions/MyExtension/script.js'); }
  • But if the extension writers don't update all of their extensions, it doesn't happen right?
    But if we add packer to Vanilla, it does.

    Why not just add LowCal into Vanilla core in a way that intercepts AddScript commands and packs accordingly. Hmm, isn't that what Packer does?

    LowCal is great. But unless every extension writer adds it or we're willing to hack each and every extension (and maintain those over all extension updates), adding Packer is more time efficient for us.
  • the problem is the interception. That can break stuff.
    What i hope for Vanilla 1.2+, is being able to add to the core a new method to Head (AddScriptToPack() or something like that), not a replacement to AddScript().
  • You know what would be awesome? If extensions had to be submitted to a community SVN repository so with things like this we could go along and fix them all.

    In the meantime, Packer. I eagerly await 1.2+ and the ease of batch replacing AddScript with AddScriptToPack.
  • I like the sound of this new header add method (it will be for CSS as well right?). Will the old one just be deprecated for removal at a later date?

    DavidK, if you email me the hacked files (see my profile), then I'll make them downloadable with a link in this discussion – In the mean time, I should update my extensions to take advantage of Low-Cal...
  • If someone want to support the packer, he can go there:
  • Just update my forum to 1.1.4, I found a change also have to apply:
    FILE: \library\Framework\Framework.Control.Head.php FIND: if (is_array($this->StyleSheets)) ksort($this->StyleSheets); REPLACE WITH: // HACK : START : PACKER //if (is_array($this->StyleSheets)) ksort($this->StyleSheets); $this->_SortSheets(); $this->_SortScripts(); // HACK : END : PACKER
    Otherwise, nothing javascript and css would be appeared. XD
  • Tinymce already has a gzip version use that
    you can download it from their site
  • ok so this extension works fine on every page but the settings page.

    a little background -

    Originally there was an error on every page referring to the newsmailer extension - it couldn't find style.css within that extension folder. So, since this was causing errors (well, annoyances really) I simply added a blank "style.css" in the newsmailer folder. It fixed the error, but now there's no css at all on the settings page. What's causing this & what can i do?
  • fixed it ---

    there's a line in /extensions/newsmailer/default.php that i deleted:


    or something to that effect.
    It's odd that it exists in the first place, considering "style.css" wasn't included w/ the extension.

    so i guess i'll delete the blank one i created to stop the error.
This discussion has been closed.