Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We're retiring the forums!

The SilverStripe forums have passed their heyday. They'll stick around, but will be read only. We'd encourage you to get involved in the community via the following channels instead:

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Mega Frontend combined files


Go to End


1286 Views

Avatar
Martijn

Community Member, 271 Posts

21 July 2010 at 10:07am

Edited: 21/07/2010 10:11am

I was experimenting to find a way to collect all js (and css later on) requirements that are used in Content_Controller and its subclasses.

The reason I want this, is that I want to use 1 javascript file that works on all pages, even those Pagetypes I do not create.

I came up with this (not extensively tested) code to collect all those js files and combined them.

Wonder what you think of this approach:


<?php
/**
 * FrontendCombiner to combine all javascript that are added in Page_Controller::init() (and its subclasses);
 * _config.php : Object::add_extension('Page_Controller','FrontendCombiner');
 * _config.php : Object::useCustomClass('Requirements', 'RequirementsExtension');
 *
 * You need to set the site to live mode to uses combined files : Director::set_environment_type("live"); 
 *
 */


class FrontendCombiner extends Extension{
		
	static $combined_javascript = array();
	
	// need this bypass pagetypes with Director::redirects in init();       
	static $exclude_controllers = array(
		'ContentController', 
		'ErrorPage_Controller', 
		'RedirectorPage_Controller',
		'PageCommentInterface_Controller',
		'VirtualPage_Controller'
	);
	
	function onAfterInit(){
		if(Director::isLive()){
			
			$combinepath = 'themes/'.SSViewer::current_theme().'/combined';
			
			if(!file_exists(Director::baseFolder() . '/' . $combinepath.'/combined.js')){
				// collect all subclasses of ContentController. SS will order them by subclass depth
				$controllers = ClassInfo::subclassesFor('ContentController');
				
				// loop thru the controllers
				foreach($controllers as $c){
					if(!in_array($c, self::$exclude_controllers) && !is_subclass_of($c, 'ErrorPage_Controller')){ //dirty for now...
						$x = new $c; // create an instance of the controller
						$x->init(); //  run init() to get the Requirements;
						$e = new RequirementsExtension; // run the extended Requirements class
						if($requirements = $e->get_javascript()){
							foreach($requirements as $file){
								self::$combined_javascript[$file] = $file; // create an array with all the js files
							}
						}
					}
				}
				if($js = self::$combined_javascript){
					self::$combined_javascript = array(); // clear combined_javascript
					foreach($js as $j){ // skip external javascripts
						if(Director::is_relative_url($j) || (Director::is_absolute_url($j) && strstr($j, Director::absoluteBaseURL()))){
							$f = Director::makeRelative($j); // make all paths relative
							self::$combined_javascript[$f] = $f; // add cleaned files to the array
						}
					}
				}
		 
				Requirements::combine_files('combined.js',self::$combined_javascript);  
				Requirements::process_combined_files(); // do the magic
			}
			
			foreach(RequirementsExtension::get_javascript() as $j){
				if(Director::is_relative_url($j) || (Director::is_absolute_url($j) && strstr($j, Director::absoluteBaseURL()))){
					RequirementsExtension::backend()->block($j); // block all local javascripts
				}
			}
			Requirements::javascript($combinepath.'/combined.js'); // add the combined javascript file
		}
	}
	
}

/**
 * Simple Requirements extension to access Requirements_Backend::get_javascript();
 */
 
class RequirementsExtension extends Requirements{
	
	static function get_javascript() {
		return self::backend()->get_javascript();
	}
}