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.

General Questions /

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

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

Mega Frontend combined files


Go to End
Reply


1135 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();
	}
}