Created
December 13, 2014 23:09
-
-
Save gbrock/10e530053b9c16727752 to your computer and use it in GitHub Desktop.
Includes controller for CodeIgniter (JS and CSS) w/ caching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |
/** | |
* Includes for CodeIgniter | |
* | |
* @author gBrock | |
* | |
* Reads the passed URLs and renders the appropriate CSS and JS files from | |
* the application's /views/ folder. Hopefully self-explanatory. | |
* | |
* BASIC USAGE | |
* | |
* Target /includes/css/file.css and/or /includes/js/file.js in your views, then | |
* put your renderable files in /application/views/includes/css and /js. | |
* | |
* Make sure your /application/cache/ folder is writable if you want to use | |
* the filecache (if global ENVIRONMENT is production, by default). | |
**/ | |
class Includes extends CI_Controller { | |
function __construct() | |
{ | |
parent::__construct(); | |
} | |
// Renders a CSS file to the page. | |
// | |
// EXAMPLE: targetting site_url("includes/css/screen.css") in your HTML would correspond to this function, | |
// look for "application/views/includes/less" and, if found, pass it to a renderer function render_css() | |
// (LESS renderer not included), and cache the file using CodeIgniter's file cache (if in production). | |
public function css() | |
{ | |
// Where our application's renderable files are located | |
$sCSSFolder = 'views/includes/less'; | |
// our target file | |
$sTargetFile = implode('/', array_slice($this->uri->segment_array(), 2)); | |
// The info about where it is supposed to exist in our filestructure | |
$oPath = (object) array_filter(pathinfo($sTargetFile)); | |
// How long should it be cached? (seconds) | |
$iCacheTime = 0; | |
switch(ENVIRONMENT) | |
{ | |
case 'production': | |
$iCacheTime = 60*10; // one hour in production | |
break; | |
} | |
// This page should only serve CSS files | |
if(empty($oPath) || | |
empty($oPath->extension) || | |
$oPath->extension !== 'css') | |
{ | |
return show_404(); | |
} | |
// The basic, non-extensioned path. | |
$sBasePath = ($oPath->dirname != '.' ? $oPath->dirname.'/' : '').$oPath->filename; | |
// The CSS file | |
$sCSSPath = $sBasePath.'.css'; | |
// The source LESS file | |
$sRealFile = | |
APPPATH. | |
$sCSSFolder.'/'. | |
$sBasePath. | |
'.less'; | |
if(!file_exists($sRealFile)) // No file, get out of here | |
{ | |
return show_404(); | |
} | |
/////// | |
// SERVER CACHING | |
////// | |
$this->load->driver('cache'); | |
// The target cache key | |
$sCacheKey = str_replace('/', '.', $sCSSPath); | |
// If we don't have valid cache data we have to generate it (i.e. RENDER FILE HERE) | |
if(!$sOutput = $this->cache->file->get($sCacheKey)) | |
{ | |
// Use $sBasePath here to do specific things with different files | |
if(file_exists($sRealFile))// If our file exists, render and cache it. | |
{ | |
$sOutput = $this->render_css($sRealFile); | |
if($iCacheTime > 0) | |
{ | |
$this->cache->file->save($sCacheKey, $sOutput, $iCacheTime); | |
} | |
} | |
} | |
/////// | |
/////// | |
// CLIENT CACHING | |
////// | |
$iSecondsValid = 0; | |
switch(ENVIRONMENT) { | |
case 'production': | |
$iSecondsValid = (60*60*24*7); // one week | |
break; | |
} | |
$this->cache_headers($iSecondsValid, $sRealFile); | |
/////// | |
// Output the CSS string | |
$this->output | |
->set_content_type('css') | |
->set_output($sOutput); | |
} | |
// Renders a JS file to the page. | |
// | |
// EXAMPLE: targetting site_url("includes/css/app.js") in your HTML would correspond to this function, | |
// look first for "application/views/includes/js/app.js" and then for the same filename but with ".php", | |
// and, if either was found, render it and cache the file using CodeIgniter's file cache (if in production). | |
public function js() | |
{ | |
// Where our application's renderable files are located | |
$sJSFolder = 'includes/js'; | |
// our target file | |
$sTargetFile = implode('/', array_slice($this->uri->segment_array(), 2)); | |
// The info about where it is supposed to exist in our filestructure | |
$oPath = (object) array_filter(pathinfo($sTargetFile)); | |
// How long should it be cached? (seconds) | |
$iCacheTime = 0; | |
switch(ENVIRONMENT) { | |
case 'production': | |
$iCacheTime = 60*60; // one hour in production | |
break; | |
} | |
// This page should only serve JS files | |
if(empty($oPath) || | |
empty($oPath->extension) || | |
$oPath->extension !== 'js') | |
{ | |
return show_404(); | |
} | |
// The basic, non-extensioned path. | |
$sBasePath = ($oPath->dirname != '.' ? $oPath->dirname.'/' : '').$oPath->filename; | |
// The JS file | |
$sJSPath = $sBasePath.'.js'; | |
// The potential viewfile | |
$sViewFile = | |
$sJSFolder.'/'. | |
$sJSPath; | |
// The potential source JS file | |
$sRealFile = | |
APPPATH. | |
'views/'.$sViewFile; | |
if(!file_exists($sRealFile) && !file_exists(APPPATH.'views/'.$sViewFile.'.php')) // No file | |
{ | |
return show_404(); | |
} | |
// SERVER FILE CACHING | |
$this->load->driver('cache'); | |
// The target cache key | |
$sCacheKey = str_replace('/', '.', $sJSPath); | |
// If we don't have valid cache data we have to generate it (i.e. RENDER FILE HERE) | |
if(!$sOutput = $this->cache->file->get($sCacheKey)) | |
{ | |
// Use $sBasePath here to do specific things with different files | |
if(file_exists($sRealFile))// If our file exists, render and cache it. | |
{ | |
$sOutput = file_get_contents($sRealFile); | |
} | |
else | |
{ | |
$sOutput = $this->load->view($sViewFile.'.php', NULL, TRUE); | |
} | |
if($iCacheTime > 0) { | |
$this->cache->file->save($sCacheKey, $sOutput, $iCacheTime); | |
} | |
} | |
// CLIENT CACHING | |
$iSecondsValid = 0; // No cache headers | |
switch(ENVIRONMENT) { | |
case 'production': | |
$iSecondsValid = (60*60*24*7); // one week | |
break; | |
} | |
$this->cache_headers($iSecondsValid, $sRealFile); | |
// output as JS. | |
$this->output | |
->set_content_type('js') | |
->set_output($sOutput); | |
} | |
// Renders a CSS file to a string. Add your favorite LESS / SCSS renderer here. | |
private function render_css($sInputFile = '') { | |
// By default, no rendering, just get the file contents and spit them back | |
$sOutput = file_get_contents($sInputFile); | |
return $sOutput; | |
} | |
// Send the common caching headers. Optionally include when the file was last modified. | |
private function cache_headers($iSeconds, $sFile = FALSE) | |
{ | |
if($iSeconds) | |
{ | |
$sValidUntil = gmdate('D, d M Y H:i:s', time() + $iSeconds) . ' GMT'; | |
$this->output | |
->set_header('Cache-Control: public') | |
->set_header('Expires: ' . $sValidUntil); | |
if($sFile !== FALSE && file_exists($sFile)) | |
{ | |
$sLastModified = gmdate('D, d M Y H:i:s', filemtime($sFile)) . ' GMT'; | |
$this->output | |
->set_header('Last-Modified: ' . $sLastModified); | |
} | |
} | |
} | |
} | |
/* End of file includes.php */ | |
/* Location: ./application/controllers/includes.php */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment