Skip to content

Commit

Permalink
Added file combiner and minification for prod deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
colintucker committed Sep 22, 2017
1 parent 2e526eb commit cf11911
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 34 deletions.
3 changes: 3 additions & 0 deletions _config/controller.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ SilverStripe\CMS\Controllers\ContentController:
load_themed_css: false
load_custom_css: true
disable_cache: true
combine_files: true
combined_js: combined.js
combined_css: combined.css

---
Name: silverware-controller-live
Expand Down
157 changes: 123 additions & 34 deletions src/Extensions/ControllerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

use SilverStripe\CMS\Controllers\ContentController;
use SilverStripe\Control\Director;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Extension;
use SilverStripe\Security\Security;
Expand Down Expand Up @@ -125,6 +126,103 @@ public function onBeforeInit()
$this->initRequirements();
}

/**
* Answers an array of all JavaScript files required by the content controllers of the app.
*
* @return array
*/
public function getRequiredJSFiles()
{
$files = [];

foreach (ClassInfo::subclassesFor(ContentController::class) as $controller) {

if ($required_js = Config::inst()->get($controller, 'required_js')) {

foreach ($required_js as $file) {

if (!isset($files[$file])) {
$files[$file] = file_get_contents(Director::getAbsFile($file));
}

}

}

}

return $files;
}

/**
/**
* Answers an array of all CSS files required by the content controllers of the app.
*
* @return array
*/
public function getRequiredCSSFiles()
{
$files = [];

foreach (ClassInfo::subclassesFor(ContentController::class) as $controller) {

if ($required_css = Config::inst()->get($controller, 'required_css')) {

foreach ($required_css as $file) {

if (!isset($files[$file])) {
$files[$file] = file_get_contents(Director::getAbsFile($file));
}

}

}

}

return $files;
}

/**
* Answers the custom CSS required for the template as a string.
*
* @return string
*/
public function getCustomCSSAsString()
{
// Create CSS Array:

$css = [];

// Merge Custom CSS from Page Controller:

if ($this->owner instanceof PageController) {
$css = array_merge($css, $this->owner->getCustomCSS());
}

// Create CSS String:

$css = implode("\n", $css);

// Remove Empty Lines:

$css = ViewTools::singleton()->removeEmptyLines($css);

// Trim CSS String:

$css = trim($css);

// Minify CSS String:

if (!Director::isDev()) {
$css = ViewTools::singleton()->minifyCSS($css);
}

// Answer CSS String:

return $css;
}

/**
* Answers true if a webpack development server is currently being used.
*
Expand Down Expand Up @@ -281,6 +379,10 @@ protected function initRequirements()
}

}

// Combine Files (dev only):

$this->combineFiles();
}

/**
Expand Down Expand Up @@ -378,40 +480,6 @@ protected function loadCustomCSS($css)
Requirements::customCSS($css);
}

/**
* Answers the custom CSS required for the template as a string.
*
* @return string
*/
public function getCustomCSSAsString()
{
// Create CSS Array:

$css = [];

// Merge Custom CSS from Page Controller:

if ($this->owner instanceof PageController) {
$css = array_merge($css, $this->owner->getCustomCSS());
}

// Create CSS String:

$css = implode("\n", $css);

// Remove Empty Lines:

$css = ViewTools::singleton()->removeEmptyLines($css);

// Trim CSS String:

$css = trim($css);

// Answer CSS String:

return $css;
}

/**
* Loads the themed JavaScript with the given name.
*
Expand Down Expand Up @@ -444,6 +512,27 @@ protected function loadThemedCSS($name)
}
}

/**
* Combines required files together for bundling with the theme.
*
* @return void
*/
protected function combineFiles()
{
if (Director::isDev() && $this->owner->config()->combine_files) {

// Obtain Tools:

$tools = ViewTools::singleton();

// Combine Files:

$tools->combineFiles($this->owner->config()->combined_js, $this->owner->getRequiredJSFiles());
$tools->combineFiles($this->owner->config()->combined_css, $this->owner->getRequiredCSSFiles());

}
}

/**
* Applies the given extension to the given file name if it is not already present.
*
Expand Down
56 changes: 56 additions & 0 deletions src/Tools/ViewTools.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace SilverWare\Tools;

use SilverStripe\Assets\File;
use SilverStripe\Control\Director;
use SilverStripe\Core\Convert;
use SilverStripe\Core\Injector\Injectable;
Expand Down Expand Up @@ -138,6 +139,61 @@ public function loadJSTemplate($file, $vars, $uniquenessID = null)
Requirements::customScript($script, $uniquenessID);
}

/**
* Combines the given array of files into a single file within the specified name and answers the URL.
*
* @param string $name
* @param array $files
*
* @return string
*/
public function combineFiles($name, $files)
{
$backend = Requirements::backend();

$path = File::join_paths($backend->getCombinedFilesFolder(), $name);

return $backend->getAssetHandler()->getContentURL($path, function () use ($files) {

$output = [];

foreach ($files as $file => $data) {
$output[] = "/***** FILE: $file *****/";
$output[] = $data;
}

return implode("\n", $output);

});
}

/**
* Minifies and wraps the given string of CSS.
*
* @param string $css
* @param integer $wrap
*
* @return string
*/
public function minifyCSS($css, $wrap = 200)
{
// Remove Comments:

$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);

// Remove Space Following Colons:

$css = str_replace(': ', ':', $css);

// Remove Whitespace:

$css = str_replace(["\r\n", "\r", "\n", "\t", ' ', ' ', ' '], '', $css);

// Wrap and Answer:

return wordwrap($css, $wrap);
}

/**
* Converts the given associative array of attributes to a string of HTML.
*
Expand Down
6 changes: 6 additions & 0 deletions src/View/Renderable.php
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,12 @@ public function getCustomCSSAsString()

$css = trim($css);

// Minify CSS String:

if (!Director::isDev()) {
$css = ViewTools::singleton()->minifyCSS($css);
}

// Answer CSS String:

return $css;
Expand Down

0 comments on commit cf11911

Please sign in to comment.