Welcome Guest, Not a member yet? Register   Sign In
Assets library & path handler
#1

(This post was last modified: 10-23-2015, 08:20 AM by Martin7483.)

Hi everybody!

I have been working on an assets library. This library collects JavaScript and CSS files that are required for any page your website/project might have. From any thinkable location you can request an assets file. When you render you final output you only have to ask the library to return the js_output() and css_output(). The returned output is optimized for fast browser rendering. For example, any required JavaScript files are only downloaded when the window onload event is triggered. CSS can be added as regular CSS or as above the fold CSS. Above the fold CSS is returned as minified in-line CSS that can be placed in the head of your HTML.
When the output is requested, a unique JavaScript or CSS file for that page is compiled. The compiling only takes place if the output file does not exist or if any source file or number of source files has changed. After compiling the output file is minified.

Using the library

PHP Code:
/**
 * Load the library or have it auto loaded in your auto load config file
 * Set the assets config file to suit your needs
 */
$this->load->library('assets');

/**
 * Requesting a CSS file
 * The first argument is the required file
 * The second argument the location in your assets directory
 */
$this->assets->_load_css('default.css''website');

// You can pass in an array as the first argument
$assets_css = array();
$assets_css['bootstrap.css'] = 'shared';
$assets_css['default.css'] = 'website';
$this->assets->_load_css($assets_css);

// Loading above the fold CSS
$this->assets->_load_css('above_the_fold.css''website''css_fold');

// For JavaScript
$this->assets->_load_javascript('default.js''website');

// Get the output
// returns an array containing 2 elements, one for the CSSfile and one for above the fold CSS
$css_output $this->assets->output_css();
// Get the JavaScript output
$js_output $this->output_js(); 

The Assets path handler
All asset files, including images and the compiled output files, are mapped in a JSON file. Each available file is mapped to it's absolute path. This JSON file is then used by both the assets library and the assets path handler.
Why do this? When working on projects, it can become quite impossible to remember each path of all your available assets. This is where this JSON file comes in handy.
I store my assets in a directory named assets which is placed in the root of my project. This directory contains a number of sub-directories. These sub-directories are the available locations where an asset can be found. When requesting a file I only need to know in which sub-directory the file is stored. Any sub-directory can contain endless number of files and or sub-directories. But no need to remember the exact location Smile
The JSON mapping file is auto generated by the assets library and auto updated when a new file is compiled. The mapping can also be generated manually. This is handy when files have been uploaded via a form. After a succesful upload you regenerate the mapping file so the newly added file(s) can be located for use. The JSON mapping can also be regenerated via a browser request. I use the url /assetsmapping for this. When manually adding files you will need to regenerate the JSON file.

How it works
The Assets path handler is placed in the root of my project. Using a htaccess any request uri starting with files is redirected to the handler. This way, a file request does not need to go through CI.
See the following request:

Code:
http://www.mydomain.com/files/website/default.css
The first segment is files, so the request is directed to the handler. The second segment is the location where the handler should start looking. It makes use of the JSON file that is created with the assets library.

Any request uri starting with assetsmapping is redirected to the mapping generator.

The htacces rules

Code:
RewriteCond %{REQUEST_URI} ^/files.*$ [NC]
RewriteRule ^(.*)$ /webfiles/handle.php/$1?handle=1 [QSA,L]

RewriteCond %{REQUEST_URI} ^/assetsmapping.*$ [NC]
RewriteRule ^(.*)$ /webfiles/mapping.php/$1 [QSA,L]

Download and checkout the attached files for more information. When I have some more time I will add documentation for the use of the library and the assets path handler.

I hope it is clear what this does. I find it a great help in my projects. Any feedback is welcome Smile

- Martin

Attached Files
.zip   assets_library.zip (Size: 20.99 KB / Downloads: 110)
Reply
#2

(This post was last modified: 10-22-2015, 08:27 PM by PaulD. Edit Reason: Just a type or two )

Perhaps I am just working on much smaller projects and it is not an issue. I usually tackle assets by putting the following in the common footer views for my files (and a similar thing in the header for CSS files):


Code:
<?php
if((isset($extra_scripts)) AND (!is_null($extra_scripts)) )
{
   foreach ($extra_scripts as $script)
   {
     echo '<script src="'.base_url('assets/'.$script).'"></script>';
   }
}
?>

Then when I need to add additional scripts, I add it to an array for the view, something like this:

Code:
$footer_data['extra_scripts'] = array('summernote/dist/summernote.min.js', 'quickdraw/dist/quickdraw.min.js');

Perhaps I just do not understand the need the need for the JSON encoding and remapping etc.

I will definitely have a read of your documentation though when it is availabe and perhaps I will see the light.

Looks very clever though, so thanks for sharing it.

Best wishes,

Paul.
Reply
#3

@PaulD, thank for your reply, and based on that I see some extra explaining is needed Tongue

Some background information on my projects.
As many, if not all of us do, I have an assets directory in the root of my projects. And to make things easy the directory is named assets. Within this directory I have the following structure:
  • ./assets/
    • cache/        → cached and optimized images are stored here
    • crossfire/    → all assets related to the CMS are stored here
    • shared/      → all assets that are shared between the CMS and website
    • website/     → all assets related to the website are stored here
Any one of these directories can have any number of sub-directories and or files. So for instance a path to a shared asset could be ./assets/shared/bootstrap320/css/bootstrap.css. That's 4 segments I would need to know to load bootstrap.css. And I already need to remember so many things.
I wanted a solution to make loading the assets super easy, would give me nice short URLs to my assets and avoid the possibility of directly accessing the directory via a URL.

So instead of having
.mydomain.com/assets/shared/bootstrap320/css/bootstrap.css

the URL becomes:
.mydomain.com/files/shared/bootstrap.css

Calling the first URL will lead to a 404 page, and not the directory.

To make this work I created the Assets path handler. This tiny plug-in is placed in the root of my projects. The reason it is not a CodeIgniter library is because I didn't want every asset request being a separate instance of CodeIgniter causing unwanted resources being loaded.

In my htaccess file I route all request URIs starting with files to /webfiles/handle.php
The handler uses the JSON file to locate the requested file. The structure of the array within this files is:

PHP Code:
array(
 
   'cache' => array('name-of-file.jpg' => 'path_to_file'),
 
   'crossfire' => array(
 
                   'crossfire-responsive.css' => 'crossfire/css',
 
                   'browser_chrome.gif' => 'crossfire/images/browsers'
 
                  ),
 
   'shared' => array(
 
                  'bootstrap.min.css' => 'shared/bootstrap320/css',
 
                  'jquery.ui.datepicker-af.js' => 'shared/js/jquery-ui/ui/i18n'
 
               ),
 
   'website' => array(
 
                  'custom.css' => 'website/css',
 
                  'ba3988db0a31670_inline.js' => 'website/output/js'
 
                )
); 


This same file is used and generated by the assets library. It uses it so that all requested CSS and JavaScript files can be located, combined, minified and stored in the assets directory.

Maybe now it is a bit more clear on what is done with this code
Reply
#4

Actually, that is indeed very clever. And would really help when assets need updating too. All you would need to do is configure the route to the new version of the asset.

I see now how I misunderstood, and yes, that seems very useful. Have bookmarked to test/use in the future, thank you again.

Best wishes,

Paul
Reply
#5

Thanks! Would love to hear how your testing went Smile

Best wishes,

Martin
Reply
#6

Small update on the assets library. Have added a version number to the generated url. Somehow when defer loading JavaScript, the browser will not post the request if the filename is the same. Adding a version number to the url fixed this.

The zip file attached to the original post has been updated.
Reply
#7

Wow. You can do inline css and js with it too. I haven't tried it yet online but I see you have also got a minify function from https://developers.google.com/closure/compiler/?hl=en which is really cool too.

This looks really good. Looking forward to trying it out for real. I will definitely post feedback when I do use it.

"..and avoid the possibility of directly accessing the directory via a URL" - I also missed how nice that was too.

You should add this to github, and so it doesn't get lost add it to this list too:
https://github.com/codeigniter-id/awesome-codeigniter

Best wishes and thanks again for sharing this,

Paul.
Reply
#8

Thank for your reply Smile

I will be putting al my goodies up on github realy soon.

Best wishes,
Martin
Reply




Theme © iAndrew 2016 - Forum software by © MyBB