Jump to content
EyeDentify

Combine CSS files with PHP

Recommended Posts

Hello There PW fans and users.

I Thought i share something that i came up with a while ago when i decided to adopt the teachings in this guide:
MaintainableCSS

This guide has made my development much easier cause i allways was stressed about having all code in one giant file and jumping around trying to keep everything organized and clear.

So i decided to go with modules, as i call them, having all the CSS belonging to a specific module in one file, and also the responsive media querys that belongs to the module in the same file. Now... so far so good. Turns out that there is a 31 file limit in browsers to how many files you can load with css.

And also i wanted to make less HTTP requests, so i started thinking, and came up with a simple PHP script that i run on my PW site in a hidden template and when that PHP script runs, it combines/compiles or merges the CSS module files together to one giant file that i link to in my website header.

This way, there is one HTTP request for all the CSS that runs the site, minus some third party stuff.

Lets look at the PHP script

<?PHP             
/* 
    EyeDentifys CSS File combiner. v1.0
    
    Array of essential files - update as needed.
    We do this to ensure the order of how the files are combined.
    You can have as many CSS module files here as you want.
    
    Remember that the combined file is compiled in the order they
    are placed in the array.
    
    Remember to check all the paths so they reflect your setup before use.
    And also, the combined file is overwritten without notice when you re-combine.
*/
$cssModules[] = 'module_global.css';
$cssModules[] = 'module_table.css';
$cssModules[] = 'module_forms.css';
$cssModules[] = 'module_layout.css';


/* init vars */
$str = '';
$moduleCount = 0;
$errorCount = 0;
$listFiles = '';

/* add a string with the latest update time and date to the top of the combined file */
$dateStr = date('Y-m-d H:i:s');
$str .= '/* Combined file last updated at ' . $dateStr . ' */' . PHP_EOL;

/* go through modules and concatenate them in a string var */
foreach($cssModules AS $key => $module){

    /* check if the file exist */
    if(file_exists('css/modules/' . $module)){

        /* read file data */
        $str .= file_get_contents('css/modules/' . $module);

        /* add module count - used for output in template */
        $moduleCount++;

        /* add the file to list */
        $listFiles[] = '[' . $module . ']';

    } else {

        /* if the file do not exist add it to the "do not exist" list */
        $listFiles[] = 'Error - file [' . $module . '] do not exist!';
        
        /* increment error count */
        $errorCount++;
    }
}

/* render the combined css */
echo('<h2>Combined CSS</h2><pre class="code-view-pre">' . $str . '</pre>');

/* list combined files */
echo('<h2>Combined files</h2>');
echo('<ul class="unstyled-list">');
    foreach($listFiles AS $key => $file) {
        echo('<li>' . $file . '</li>');
    }
echo('</ul>');
echo('<p>Number of file errors <strong>' . $errorCount . '</strong> st.</p>');

/* the file name defaults */
$combinedFileName = 'css/combined_styles.css';
$backupFileName = 'css/backups/backup_styles_' . date("Y-m-d_H-i-s") . '.css';

/* backup the old combined file before updating it */
copy($combinedFileName, $backupFileName);
echo('<p>Backup created to file: <strong>' . $backupFileName . '</strong></p>');

/* create update the combined css file */
file_put_contents($combinedFileName, $str);
echo('<p>Combined css file: <strong>' . $combinedFileName . '</strong> updated!</p>');

echo('<p><strong>' . $moduleCount . '</strong> files combined.</p>');
?>


Like i said above, i have this in a hidden Template file that i run when logged in as ADMIN. 
I just refresh the page everytime i made a change and uploaded to the server so the new changes is combined into the big file and can be seen on the website.

My script assumes the following directory structure:

1. This is where the script looks for the module files:
templates -> css -> modules

2. This is where the script saves the combined big CSS file:
templates -> css

3. This is where the script saves a backup of the current big CSS file before creating and writing over the new big file:
templates -> css -> backups


You need to go through the script and change the hardcoded paths to suit your needs before use.
Also please try this out at some test site first so you get the hang of it. Be safe.

This way of dealing with alot of CSS code has realy made my life much easier.
Cause if i want to change some modules CSS i just open that file, make the changes, upload the module, and run the script and its compiled in with the other CSS in the big file.

I am sure you creative fellows on the forums can make refinements to this code, but it has served me well.

Hope it helps someone.
 

Share this post


Link to post
Share on other sites

Interesting way to handle many css files.

But, to avoid misunderstanding, wouldn't it have been better to replace the term "module" with something else?

Share this post


Link to post
Share on other sites
2 minutes ago, ottogal said:

Interesting way to handle many css files.

But, to avoid misunderstanding, wouldn't it have been better to replace the term "module" with something else?


Hello. Perhaps it can lead to confusion.

But my reason for using the term "module" is that the goal of the CSS modules as i call them, is for them to be independent of the other ones.
There for i use the term module. 

I use this reasoning after reading the MaintainableCSS guide i link to in my post.

But you can call it what suits you best and you feel comfortable with.


Its just a term i use for myself to understand what the intention are of the module files.

Share this post


Link to post
Share on other sites

I would add markup cache to the stack, with 0 timeout for superusers, and a few minutes for regular users.

But I'm fine with my current scss/gulp workflow, using includes. Imho it's more maintainable and scalable too, but requires a dev environment to work.

Share this post


Link to post
Share on other sites
15 minutes ago, tpr said:

I would add markup cache to the stack, with 0 timeout for superusers, and a few minutes for regular users.

But I'm fine with my current scss/gulp workflow, using includes. Imho it's more maintainable and scalable too, but requires a dev environment to work.


I Think you have missunderstood the use of this script.

It´s just a dev tool for handling the CSS merging to a single file.

Just meant for the developer and not the users of the site.

The user will only experience the merged file with all the CSS that controls the sites look and feel.

 

Update: i see what you mean by markup cache now. Missunderstood you.

Edited by EyeDentify
Missunderstandings

Share this post


Link to post
Share on other sites

I may, but I still see no benefits over less/sass/postcss etc. On saving included scss/less/etc files, or the main file, the final CSS gets compiled automatically, no need to do anything.

Share this post


Link to post
Share on other sites
32 minutes ago, tpr said:

I may, but I still see no benefits over less/sass/postcss etc. On saving included scss/less/etc files, or the main file, the final CSS gets compiled automatically, no need to do anything.


The thing is, that people have different ways of working.

I prefer to use just plain old CSS from the start and do not feel its worth messing around with Less/scss or similar thing.

Thats were my way of using this PHP script come into play.

But as i said, thats the beauty with the our age of web development that you can choose the way that works best for you.

And you can run all sorts of string functions on the main css file when its been merged to lets say minizise and such.
I know you can do that with your workflow as well.

But i also see this as an oportunity to use PHP do to different things. Besides i like to experiment.

  • Like 1

Share this post


Link to post
Share on other sites

maybe i'm misunderstanding, but isn't this doing exactly what AIOM does?

Share this post


Link to post
Share on other sites
2 minutes ago, bernhard said:

maybe i'm misunderstanding, but isn't this doing exactly what AIOM does?

I am sure it does.

But the point here is that i made something because i wanted to try it with PHP and to do one thing very good.
Not everything has to be a module.

This script is not meant to be a swizz army knife.

The point is to experiment, and share my findings so others could see have they could use PHP in different ways.

 

  • Like 4

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Marvin
      Hello, i want to ask, i maintain a website that using a processwire and php, and i want to make an archive at my website using a subfolder system, but when i try,
      the sebfolder is show but when i click the files in that subfolder not show, and my browser just show me an error Invalid argument supplied for foreach(), i don't know why it error
      Here i attach my code and my screenshoot website :
      This is my code

      This is result of my website

      This is my error

       
       
    • By hellomoto
      I can't tell what's wrong; my local development version appears just fine, but I copy over the site files and db online and the homepage content is not being contained. This is what it should look like (same site in the same browser, running on my localhost): http://imgur.com/UFZFzrd
      What could be the problem here? Sorry to bring up something so irrelevant to PW here, I just know that you all are a valiant and helpful group, and no one on StackExchange seems to even know what I'm talking about.
      Thanks a lot.
    • By picarica
      so i just downloaded this template  and i uploaded it to my server made some .php changes so it would work and stuff but all the css-transitions or css-animations don't work. they just stop
      if you checked out the template all those buttons are smooth and really nice, bit when you check out my site all those animations are gone, why is that? is there some option i have to toggle? or is it normal? how do i fix it ?
    • By gebeer
      Hello all,
      wasn't sure where to put this, so it goes in General section.
      Ryan shows a hook that we can use to mirror files on demand from live server to development environment to be up to date with the files on the server without having to download complete site/assets/files folder.
      I just implemented this but had problems getting files to load from a site in development that is secured with user/password via htaccess.
      First I tried to use WireHttp setHeader method for basic authentication like this
      function mirrorFilesfromLiveServer(HookEvent $event) { $config = $event->wire('config'); $file = $event->return; if ($event->method == 'url') { // convert url to disk path $file = $config->paths->root . substr($file, strlen($config->urls->root)); } if (!file_exists($file)) { // download file from source if it doesn't exist here $src = 'http://mydomain.com/site/assets/files/'; $url = str_replace($config->paths->files, $src, $file); $http = new WireHttp(); // basic authentication $u = 'myuser'; $pw = 'mypassword'; $http->setHeader('Authorization: Basic', base64_encode("$u:$pw")); $http->download($url, $file); } } But, unfortunately this didn't work.
      So now I am using curl to do the download. My hook function now looks like this
      function mirrorFilesfromLiveServer(HookEvent $event) { $config = $event->wire('config'); $file = $event->return; if ($event->method == 'url') { // convert url to disk path $file = $config->paths->root . substr($file, strlen($config->urls->root)); } if (!file_exists($file)) { // download file from source if it doesn't exist here $src = 'http://mydomain.com/site/assets/files/'; $fp = fopen($file, 'w+'); // init file pointer $url = str_replace($config->paths->files, $src, $file); $u = 'myuser'; $pw = 'mypassword'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, 50); // crazy high timeout just in case there are very large files curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERPWD, "$u:$pw"); // authentication curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // authentication curl_setopt($ch, CURLOPT_FILE, $fp); // give curl the file pointer so that it can write to it curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $data = curl_exec($ch); curl_close($ch); } } Now I can load files and images from the htaccess protected development server 🙂
      If anyone knows how to get this to work with WireHttp, please let me know. Thank you.
    • By Mithlesh
      Hi there,
      My form is not getting submitted, it is showing:
      Unable to verify successful email delivery of this form submission.
      Attaching for your reference as well: 

      In the Backend, it is showing Connection timed out with smtp.gmail.com
      Pl guide me how to resolve that
×
×
  • Create New...