Merge pull request #42 from green-ponies/master
Automatic Caching of CSS and Javascript
This commit is contained in:
commit
fc45aa2752
@ -150,6 +150,24 @@ class Page {
|
|||||||
$this->http_headers[$position] = $line;
|
$this->http_headers[$position] = $line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the HTML headers that are currently set and return as a string.
|
||||||
|
*/
|
||||||
|
public function get_all_html_headers() {
|
||||||
|
$data = '';
|
||||||
|
foreach ($this->html_headers as $line) {
|
||||||
|
$data .= $line . "\n";
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all currently set HTML headers. (Be careful..)
|
||||||
|
*/
|
||||||
|
public function delete_all_html_headers() {
|
||||||
|
$this->html_headers = array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a Block of data
|
* Add a Block of data
|
||||||
*/
|
*/
|
||||||
@ -230,99 +248,164 @@ class Page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This function caches the CSS and JavaScript files.
|
* Automatic caching of CSS and Javascript files
|
||||||
This is done to reduce the number of HTTP requests (recommended by
|
*
|
||||||
the Yahoo high-performance guidelines). It combines all of the CSS
|
* Allows site admins to have Shimmie automatically cache and minify all CSS and JS files.
|
||||||
and JavaScript files into one for each type, and stores them in
|
* This is done to reduce the number of HTTP requests (recommended by the Yahoo high-performance
|
||||||
cached files to serve the client. Changes to the CSS or JavaScript
|
* guidelines). It combines all of the CSS and JavaScript files into one for each type, and
|
||||||
files are caught by taking the md5sum of the concatenated files.
|
* stores them in cached files to serve the client. Changes to the CSS or JavaScript files are
|
||||||
*/
|
* caught by taking the md5sum of the concatenated files.
|
||||||
|
*
|
||||||
|
* Note: This can be somewhat problematic, as it edits the links to your CSS files (as well
|
||||||
|
* as the links to images inside them).
|
||||||
|
* Also, the directory cache directory needs to be writeable by the php/webserver user.
|
||||||
|
* PLEASE: Ensure that you test your site out throughly after enabling this module!
|
||||||
|
* Either that, or don't use this module unless you are sure of what it is doing.
|
||||||
|
*
|
||||||
|
* TODO: Add support for minify-ing CSS and Javascript files. (similar to Minify. See: http://code.google.com/p/minify/ or https://github.com/mrclay/minify)
|
||||||
|
* TODO: For performance reasons: Before performing the regex's, compute the md5 of the CSS & JS files and store somewhere to check later.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* This function returns FALSE if it failed to cache the files,
|
||||||
|
* and returns TRUE if it was successful.
|
||||||
|
*/
|
||||||
private function add_cached_auto_html_headers()
|
private function add_cached_auto_html_headers()
|
||||||
{
|
{
|
||||||
$cache_location = 'data/cache/';
|
global $config;
|
||||||
$data_href = get_base_href();
|
|
||||||
|
|
||||||
|
if (!$config->get_bool("autocache_css") && !$config->get_bool("autocache_js")) {
|
||||||
|
return false; // caching disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
$cache_location = $config->get_string("autocache_location", 'data/cache');
|
||||||
|
// Detect is there is a trailing slash, and add one if not.
|
||||||
|
$cache_location = ((strrpos($cache_location, '/') + 1) == strlen($cache_location)) ? $cache_location : $cache_location.'/';
|
||||||
|
|
||||||
|
// Create directory if needed.
|
||||||
if(!file_exists($cache_location)) {
|
if(!file_exists($cache_location)) {
|
||||||
if (!mkdir($cache_location, 0750, true)) {
|
if (!mkdir($cache_location, 0750, true)) {
|
||||||
return false; // failed to create directory
|
return false; // failed to create directory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----- CSS Files ----- */
|
$data_href = get_base_href();
|
||||||
// First get all the CSS from the lib directory
|
|
||||||
$data_1 = '';
|
|
||||||
$css_files = glob("lib/*.css");
|
|
||||||
if($css_files) {
|
|
||||||
foreach($css_files as $css_file) {
|
|
||||||
$data_1 .= file_get_contents($css_file);
|
|
||||||
}
|
|
||||||
// Can't directly cache the CSS files, as they might have relative locations to images, etc. in them.
|
|
||||||
// We have to adjust the URLs accordingly before saving the cached file.
|
|
||||||
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
|
|
||||||
$replace = 'url("../../lib/${1}")';
|
|
||||||
$data_1 = preg_replace($pattern, $replace, $data_1);
|
|
||||||
}
|
|
||||||
// Next get all the CSS from the extensions
|
|
||||||
$data_2 = '';
|
|
||||||
$css_files = glob("ext/*/style.css");
|
|
||||||
if($css_files) {
|
|
||||||
foreach($css_files as $css_file) {
|
|
||||||
$data_2 .= file_get_contents($css_file);
|
|
||||||
}
|
|
||||||
// Can't directly cache the CSS files, as they might have relative locations to images, etc. in them.
|
|
||||||
// We have to adjust the URLs accordingly before saving the cached file.
|
|
||||||
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
|
|
||||||
$replace = 'url("../../${1}")';
|
|
||||||
$data_2 = preg_replace($pattern, $replace, $data_2);
|
|
||||||
}
|
|
||||||
// Combine the two
|
|
||||||
$data = $data_1 . $data_2;
|
|
||||||
// compute the MD5 sum of the concatenated CSS files
|
|
||||||
$md5sum = md5($data);
|
|
||||||
|
|
||||||
if (!file_exists($cache_location.$md5sum.'.css')) {
|
|
||||||
// remove any old cached CSS files.
|
|
||||||
$mask = '*.css';
|
|
||||||
array_map( 'unlink', glob( $mask ) );
|
|
||||||
|
|
||||||
// output the combined file
|
|
||||||
if (file_put_contents($cache_location.$md5sum.'.css', $data, LOCK_EX) === FALSE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// tell the client where to get the css cache file
|
|
||||||
$this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$cache_location.$md5sum.'.css'.'" type="text/css">');
|
|
||||||
|
|
||||||
|
/* ----- CSS Files ----- */
|
||||||
|
if ($config->get_bool("autocache_css"))
|
||||||
|
{
|
||||||
|
// First get all the CSS from the lib directory
|
||||||
|
$contents_from_lib = '';
|
||||||
|
$css_files = glob("lib/*.css");
|
||||||
|
if($css_files) {
|
||||||
|
foreach($css_files as $css_file) {
|
||||||
|
$contents_from_lib .= file_get_contents($css_file);
|
||||||
|
}
|
||||||
|
// Can't directly cache the CSS files, as they might have relative locations to images, etc. in them.
|
||||||
|
// We have to adjust the URLs accordingly before saving the cached file.
|
||||||
|
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
|
||||||
|
$replace = 'url("../../lib/${1}")';
|
||||||
|
$contents_from_lib = preg_replace($pattern, $replace, $contents_from_lib);
|
||||||
|
}
|
||||||
|
// Next get all the CSS from the extensions
|
||||||
|
$contents_from_extensions = '';
|
||||||
|
$css_files = glob("ext/*/style.css");
|
||||||
|
if($css_files) {
|
||||||
|
foreach($css_files as $css_file) {
|
||||||
|
$contents_from_extensions .= file_get_contents($css_file);
|
||||||
|
}
|
||||||
|
// Can't directly cache the CSS files, as they might have relative locations to images, etc. in them.
|
||||||
|
// We have to adjust the URLs accordingly before saving the cached file.
|
||||||
|
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
|
||||||
|
$replace = 'url("../../${1}")';
|
||||||
|
$contents_from_extensions = preg_replace($pattern, $replace, $contents_from_extensions);
|
||||||
|
}
|
||||||
|
// Combine the two
|
||||||
|
$data = $contents_from_lib .' '. $contents_from_extensions;
|
||||||
|
|
||||||
|
// Minify the CSS if enabled.
|
||||||
|
if ($config->get_bool("autocache_min_css")){
|
||||||
|
// not supported yet.
|
||||||
|
// TODO: add support for Minifying CSS files.
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the MD5 sum of the concatenated CSS files
|
||||||
|
$md5sum = md5($data);
|
||||||
|
|
||||||
|
if (!file_exists($cache_location.$md5sum.'.css')) {
|
||||||
|
// remove any old cached CSS files.
|
||||||
|
$mask = '*.css';
|
||||||
|
array_map( 'unlink', glob( $mask ) );
|
||||||
|
|
||||||
|
// output the combined file
|
||||||
|
if (file_put_contents($cache_location.$md5sum.'.css', $data, LOCK_EX) === FALSE) {
|
||||||
|
return false; // failed to write the file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// tell the client where to get the css cache file
|
||||||
|
$this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$cache_location.$md5sum.'.css'.'" type="text/css">');
|
||||||
|
} else {
|
||||||
|
// Caching of CSS disabled.
|
||||||
|
foreach(glob("lib/*.css") as $css) {
|
||||||
|
$this->add_html_header("<link rel='stylesheet' href='$data_href/$css' type='text/css'>");
|
||||||
|
}
|
||||||
|
$css_files = glob("ext/*/style.css");
|
||||||
|
if($css_files) {
|
||||||
|
foreach($css_files as $css_file) {
|
||||||
|
$this->add_html_header("<link rel='stylesheet' href='$data_href/$css_file' type='text/css'>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----- JavaScript Files ----- */
|
/* ----- JavaScript Files ----- */
|
||||||
$data = '';
|
if ($config->get_bool("autocache_js"))
|
||||||
$js_files = glob("lib/*.js");
|
{
|
||||||
if($js_files) {
|
$data = '';
|
||||||
foreach($js_files as $js_file) {
|
$js_files = glob("lib/*.js");
|
||||||
$data .= file_get_contents($js_file);
|
if($js_files) {
|
||||||
|
foreach($js_files as $js_file) {
|
||||||
|
$data .= file_get_contents($js_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$js_files = glob("ext/*/script.js");
|
||||||
|
if($js_files) {
|
||||||
|
foreach($js_files as $js_file) {
|
||||||
|
$data .= file_get_contents($js_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Minify the JS if enabled.
|
||||||
|
if ($config->get_bool("autocache_min_js")){
|
||||||
|
// not supported yet.
|
||||||
|
// TODO: add support for Minifying CSS files.
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the MD5 sum of the concatenated JavaScript files
|
||||||
|
$md5sum = md5($data);
|
||||||
|
|
||||||
|
if (!file_exists($cache_location.$md5sum.'.js')) {
|
||||||
|
// remove any old cached js files.
|
||||||
|
$mask = '*.js';
|
||||||
|
array_map( 'unlink', glob( $mask ) );
|
||||||
|
// output the combined file
|
||||||
|
if (file_put_contents($cache_location.$md5sum.'.js', $data, LOCK_EX) === FALSE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// tell the client where to get the js cache file
|
||||||
|
$this->add_html_header('<script src="'.$data_href.'/'.$cache_location.$md5sum.'.js'.'" type="text/javascript"></script>');
|
||||||
|
} else {
|
||||||
|
// Caching of Javascript disabled.
|
||||||
|
foreach(glob("lib/*.js") as $js) {
|
||||||
|
$this->add_html_header("<script src='$data_href/$js' type='text/javascript'></script>");
|
||||||
|
}
|
||||||
|
$js_files = glob("ext/*/script.js");
|
||||||
|
if($js_files) {
|
||||||
|
foreach($js_files as $js_file) {
|
||||||
|
$this->add_html_header("<script src='$data_href/$js_file' type='text/javascript'></script>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$js_files = glob("ext/*/script.js");
|
|
||||||
if($js_files) {
|
|
||||||
foreach($js_files as $js_file) {
|
|
||||||
$data .= file_get_contents($js_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// compute the MD5 sum of the concatenated JavaScript files
|
|
||||||
$md5sum = md5($data);
|
|
||||||
|
|
||||||
if (!file_exists($cache_location.$md5sum.'.js')) {
|
|
||||||
// remove any old cached js files.
|
|
||||||
$mask = '*.js';
|
|
||||||
array_map( 'unlink', glob( $mask ) );
|
|
||||||
// output the combined file
|
|
||||||
if (file_put_contents($cache_location.$md5sum.'.js', $data, LOCK_EX) === FALSE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// tell the client where to get the js cache file
|
|
||||||
$this->add_html_header('<script src="'.$data_href.'/'.$cache_location.$md5sum.'.js'.'" type="text/javascript"></script>');
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -555,11 +555,15 @@ function array_remove($array, $to_remove) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an item to an array
|
* Adds an item to an array.
|
||||||
|
*
|
||||||
|
* Also removes duplicate values from the array.
|
||||||
*
|
*
|
||||||
* @retval array
|
* @retval array
|
||||||
*/
|
*/
|
||||||
function array_add($array, $element) {
|
function array_add($array, $element) {
|
||||||
|
// Could we just use array_push() ?
|
||||||
|
// http://www.php.net/manual/en/function.array-push.php
|
||||||
$array[] = $element;
|
$array[] = $element;
|
||||||
$array = array_unique($array);
|
$array = array_unique($array);
|
||||||
return $array;
|
return $array;
|
||||||
|
@ -173,6 +173,12 @@ class Setup extends SimpleExtension {
|
|||||||
$config->set_default_bool("word_wrap", true);
|
$config->set_default_bool("word_wrap", true);
|
||||||
$config->set_default_bool("use_captchas", false);
|
$config->set_default_bool("use_captchas", false);
|
||||||
$config->set_default_string("autodate_format", "F j, Y");
|
$config->set_default_string("autodate_format", "F j, Y");
|
||||||
|
// Automatic caching is disabled by default
|
||||||
|
$config->set_default_string("autocache_location", "data/cache");
|
||||||
|
$config->set_default_bool("autocache_css", false);
|
||||||
|
$config->set_default_bool("autocache_jss", false);
|
||||||
|
$config->set_default_bool("autocache_min_css", false);
|
||||||
|
$config->set_default_bool("autocache_min_js", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onPageRequest($event) {
|
public function onPageRequest($event) {
|
||||||
@ -280,6 +286,30 @@ class Setup extends SimpleExtension {
|
|||||||
$sb->add_text_option("api_recaptcha_privkey", "<br>Private key: ");
|
$sb->add_text_option("api_recaptcha_privkey", "<br>Private key: ");
|
||||||
$sb->add_text_option("api_recaptcha_pubkey", "<br>Public key: ");
|
$sb->add_text_option("api_recaptcha_pubkey", "<br>Public key: ");
|
||||||
$event->panel->add_block($sb);
|
$event->panel->add_block($sb);
|
||||||
|
|
||||||
|
|
||||||
|
// Options for Automatic Caching & Minifying
|
||||||
|
$minifyscript = "<script language='javascript'>
|
||||||
|
checkbox_css = document.getElementById('autocache_min_css');
|
||||||
|
checkbox_js = document.getElementById('autocache_min_js');
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
checkbox_css.disabled = true;
|
||||||
|
checkbox_css.checked = false;
|
||||||
|
checkbox_js.disabled = true;
|
||||||
|
checkbox_js.checked = false;
|
||||||
|
});
|
||||||
|
</script>";
|
||||||
|
|
||||||
|
$sb = new SetupBlock("Automatic Caching of CSS & JS");
|
||||||
|
$sb->add_text_option("autocache_location", "Location: ");
|
||||||
|
$sb->add_label("<br><i>This location needs to be writeable by the webserver.</i>");
|
||||||
|
$sb->add_bool_option("autocache_css", "<br>Automatic caching of CSS: ");
|
||||||
|
$sb->add_bool_option("autocache_js", "<br>Automatic caching of JS: ");
|
||||||
|
$sb->add_bool_option("autocache_min_css", "<br>Minimize CSS files: ");
|
||||||
|
$sb->add_bool_option("autocache_min_js", "<br>Minimize JS files: ");
|
||||||
|
$sb->add_label("<br><span id='autocache_minify'><i>Minifying currently not supported.</i></span>$minifyscript");
|
||||||
|
$event->panel->add_block($sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onConfigSave($event) {
|
public function onConfigSave($event) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user