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 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
    • By CareerTeam GmbH
      Hi there,
      We are an executive search agency based in Germany looking for a freelancer (2-5 days per week) supporting us with the development and design of our websites. The position will be located in Hamburg, Germany and it would be great if you are on short call. German language knowledge is mandatory. 
      You can reach me via email jobs@careerteam.de.
      Thank you!
      Regards
      Annemie
    • By Robin S
      If you've ever needed to insert links to a large number of files within CKEditor you may have found that the standard PW link modal is a somewhat slow way to do it.
      This module provides a quicker way to insert links to files on the page being edited. You can insert a link to an individual file, or insert an unordered list of links to all files on the page with a single click.
      CKEditor Link Files
      Adds a menu to CKEditor to allow the quick insertion of links to files on the page being edited.

      Features
      Hover a menu item to see the "Description" of the corresponding file (if present). Click a menu item to insert a link to the corresponding file at the current cursor position. The filename is used as the link text. If you Alt-click a menu item the file description is used as the link text (with fallback to filename if no description entered). If text is currently selected in the editor then the selected text is used as the link text. Click "* Insert links to all files *" to insert an unordered list of links to all files on the page. Also works with the Alt-click option. Menu is built via AJAX so newly uploaded files are included in the menu without the page needing to be saved. However, descriptions are not available for newly uploaded files until the page is saved. There is an option in the module config to include files from Repeater fields in the edited page. Nested Repeater fields (files inside a Repeater inside another Repeater) are not supported. Installation
      Install the CKEditor Link Files module.
      For any CKEditor field where you want the "Insert link to file" dropdown menu to appear in the CKEditor toolbar, visit the field settings and add "LinkFilesMenu" to the "CKEditor Toolbar" settings field.
       
      http://modules.processwire.com/modules/cke-link-files/
      https://github.com/Toutouwai/CkeLinkFiles
    • By louisstephens
      I was really unsure of how to actually title this post, so I do apologize (if someone has a better idea, I will gladly edit it). I am using the profields: pagetable field to allow people to create their own "content" (copy, image, button, etc etc) and rearrange it. I also included a field called "column_size" using the RangeSlider set to (1-12).
      I guess I'll clarify a bit more on this. I am using flexbox where the "row" is <section></section> and the columns are <div class="column"></div> have given the "columns"  flex: 1 1 0; so no matter how many columns you have, the columns will automatically adjust for new content. Where my confusion is coming in: If a user has set up 3 copy items (with 12, 5, 7 respectfully for the column_size), how do I actually output this in my template? I was going to use a switch statement to handle the various items which I thought made it quite easy, but with closing sections and columns I have confused myself as I assume I need an if statement to check if the column size is > 12, or = 12 to determine the actual closing/opening of sections. I apologize if I have not made this very clear. I am a bit unsure how to word this let alone to go about this. 
      Im very appreciative of for any insight into this.
       
       
×
×
  • Create New...