Jump to content

Module: AIOM+ (All In One Minify) for CSS, LESS, JS and HTML


David Karich

Recommended Posts

As would I. Currently I have a foreach pushing the list into an array and using that but if I could use the FilenameArray it would simplify my code a great deal.

$min_js = array();
foreach($config->scripts as $script){
	$min_js[] = $script;
}
if(count($min_js)) echo '<script src="'.AIOM::JS($min_js).'"></script>';

I'm not sure about my foreach since it could be run on an empty $config->scripts but I don't know how best to check a FilenameArray is not empty, count() returns 1 when it's empty usually.

  • Like 1
Link to comment
Share on other sites

What sort of hosting are you using, vxda? 

I sometimes come across this on Cloud hosting where shared NFS storage is used. Not just in this module, but also the core PW modules cache file, before that was moved to the new DB-backed WireCache class.

I've had success when removing the LOCK_EX parameter on file_put_contents calls. For this module, it's in two places - lines 464 and 111.

Link to comment
Share on other sites

Hi, for some reason module create empty files. Anyone else got same problem ?

I had this problem before I realised that the scripts and CSS files are relative to the templates directory. Check you're not using link relative to the site root.

Link to comment
Share on other sites

Some brief feedback after using this module (V 3.1.3) on a project with PW 2.4. All in all a great tool for reducing page load times.

There's an issue about this on Github and it will probably be addressed once the developer gets back from a trip but it took me a while to find so I'll mention that the cache ids are made from the modtime of the file(s). If you FTP files which arrive in the same second they will try to use the same cache file and your pages will be a mess. I suggested a fix.

When using dev tools in browsers to inspect elements and peek into CSS files you'll be seeing the cache file filenames (md5 gibberish). I made a small modification to list the file path(s) at the top of the file. Sort of contrary to minifying but useful.

EDIT: This idiom comes in handy to minimize only files in a certain folder. I do something just like it for 'styles' too. This way if I put URLs to external popular libraries (already minimized) in $config scripts they are left alone:

foreach ($config->scripts->unique() as $path){
    if(preg_match('#^'.$config->urls->templates.'scripts(.*)#',$path,$m)) $path = AIOM::JS('scripts'.$m[1]);
    echo '    <script type="text/javascript" src="'.$path.'"></script>'.PHP_EOL;
}    

 

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hi David! Any thoughts on changing the compression library yet? I'm getting this suggestion from google page speed insights:
 

Minify JavaScript for the following resources to reduce their size by 1KiB (4% reduction).

Minifying http://…m/js_8d0a111a71c0967baaa819dcafec03f2.js could save 1KiB (4% reduction) after compression.

Link to comment
Share on other sites

  • 1 month later...

Hey David, 

what a useful module! Thank you so much.

Does anyone else have issues with inline svg graphics? During the compression it seems like the AIOM-Module is breaking up. Perhaps wrong escaping?

background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHB vcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4wLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLVNWRy0yMDAxMDkwNC9EVEQvc3ZnMTAuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4wIiBpZD0iRWJlbmVfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyMCAyOSIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjAgMjkiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggaWQ9InBob25lLTItaWNvbiIgZmlsbD0iI0ZGRkZGRiIgZD0iTTEzLjc5OCwyOC45MDRDMTMuNzk4LDI4LjkwNCwxMy43OTgsMjguOTA0LDEzLjc5OCwyOC45MDQNCgljLTEuNTY5LDAtMy4xNTctMC43NDctNC43MjEtMi4yMTljLTEuODM0LTEuNzI2LTMuNzQ2LTQuNTU3LTUuNjgzLTguNDE1QzAuNjUxLDEyLjgwOS0wLjQxMiw4Ljc1NiwwLjE0Miw1Ljg4DQoJQzAuNzM0LDIuODExLDIuNjQ0LDIuMDM0LDYuNzM4LDAuMWw0Ljc0OSw5LjQ1NWwtMy4xNzIsMS41OTNjLTAuMTQxLDAuNCwwLjAyNSwxLjkzMiwxLjA3OCw0LjA1NQ0KCWMxLjA3NiwyLjE3LDIuMjIzLDMuMjUyLDIuNjM2LDMuMzgzYzAuMTg2LTAuMDkxLDMuMTctMS41OCwzLjE3LTEuNThsNC44LDkuNDQ4QzE2L jE3NCwyOC4zNjgsMTUuMzY5LDI4LjkwNCwxMy43OTgsMjguOTA0eg0KCSBNMi41NDksNi4zNDRDMi4yNDUsNy45MiwyLjUyNSwxMS4wNzgsNS41ODQsMTcuMTdjMS44MDgsMy42LDMuNTQ4LDYuMjAxLDUuMTczLDcuNzNjMS4wOTUsMS4wMywyLjExOCwxLjU1MiwzLjA0MSwxLjU1Mw0KCWMwLjc4OCwwLDEuMzUzLTAuMzEzLDIuOS0xLjA4NmwtMi41ODEtNS4wODFjLTAuODM0LDAuNDE3LTEuMDMyLDAuNTE0LTEuMDkzLDAuNTQzYy0xLjc5MywwLjg3NS0zLjU3Mi0wLjkzMy00LjcwOS0yLjYxMQ0KCWMtMC45OTUtMS40NjgtMS44MjgtMy4yNzktMi4yMjgtNC44NDRDNS4zOCwxMC42MTQsNi4yMzEsOS40ODksNy4wNyw5LjAzMWwwLjAzOC0wLjAybDEuMDg5LTAuNTQ3bC0yLjU2MS01LjENCglDMy44NjgsNC4yNTQsMi44ODQsNC42MDcsMi41NDksNi4zNDR6Ii8+DQo8L3N2Zz4NCg==')




			
		
Link to comment
Share on other sites

  • 2 weeks later...
Hey guys, 

sorry for the late feedback. I currently have so much with my company around the ears and stuck in large projects that I currently have no time to maintain AIOM+. I'm sorry. The project will continue to maintain. 

Did any of you like to take care of to AIOM+? At best a German developer. Then I give him on Github access to the Repositority. 

Dave

  • Like 3
Link to comment
Share on other sites

Hi David,

I'd be glad to take care of AIOM. I'm coming from the South of Germany.

I work together with @phil at Conclurer, a web development company. 

If you want to, I can send you my personal mail address so that we can talk about AIOM.

Thanks in advance,

Marvin

  • Like 11
Link to comment
Share on other sites

Hi David,

I'd be glad to take care of AIOM. I'm coming from the South of Germany.

I work together with @phil at Conclurer, a web development company. 

If you want to, I can send you my personal mail address so that we can talk about AIOM.

Thanks in advance,

Marvin

Hi Marvin, 
 
perfect. With you, the project is certainly in good hands. Send me please your contact information, then we can talk about AIOM. 
 
Thanks and best regards from Cologne. 
Dave
  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

Calling AIOM/chmod experts...

Just today a whole website of mine using AIOM ceased to function.

Precicely 1 month after installing AIOM on the site, I was getting a 500 error. Looking at the PW log file I saw countless repetitions of...

2014-10-18 15:59:18	guest	http://***.com/?/	Error: 	Exception: The permissions (chmod) to delete old cache files could not be changed. (in /srv/***/www/***.com/public_html/site/modules/AllInOneMinify/AllInOneMinify.module line 646)

So, I guess one or more of my cached files had hit a 30 day expiry date.

I did a bit of investigating, and it seems that before deleting cache files, AIOM like to chmod 777 the file. If it can't chmod the file, it throws this error and stops the site loading. No logging into PW admin, nothing.

It seems similar to this problem here:

https://github.com/ryancramerdesign/ProcessWire/issues/648

And the exact line of code in question is highlighted by Ryan there. https://github.com/FlipZoomMedia/ProcessWire-AIOM-All-In-One-Minify/blob/AIOM%2B/AllInOneMinify.module#L641... It's line 646.

Is there any real need to change the permissions to 777 before deleting?

The problem in my case is that www-data doesn't own these files. I copied this installation over from another server, and the owner (chown) is actuall "admin". But I have group rw permission to www-data, so the files can be deleted. I think that should be okay, right?

So, what I did was comment line 646 and added the following three lines

        // ------------------------------------------------------------------------
        // Remove all files that are older than the maximum lifetime.
        // ------------------------------------------------------------------------
        foreach ($_cacheFiles as $_cacheFile) {
            if (((filemtime(wire('config')->paths->assets.self::$cacheDir.DIRECTORY_SEPARATOR.$_cacheFile->getFilename()) + self::$cacheMaxLifetime) < time() OR $force_all === true) AND is_file($_cacheFile)) {
                $_file  = wire('config')->paths->assets.self::$cacheDir.DIRECTORY_SEPARATOR.$_cacheFile->getFilename();
                if(chmod($_file, 0777) !== false) {
                    if(unlink($_file) === false) {
                        throw new WireException('The old cache files could not be deleted.');
                    }
                } else {
                    // throw new WireException('The permissions (chmod) to delete old cache files could not be changed.');
                    if(unlink($_file) === false) {
                        throw new WireException('The old cache files could not be deleted.');
                    }                    
                }
            }
        }

And now everything seems to work again.

Stuff like this sort of scares me. The last thing I want is for sites to completely and arbitrarily stop working!

  • Like 1
Link to comment
Share on other sites

Hello everybody,

I'm happy to announce that David and I have negotiated, how to continue both development and support of the AIOM module.

This is our deal:

  • Conclurer will develop and support the AIOM module from now on
  • David will continue developing once he'll have more time available

Therefore, the repository has been migrated to a new URL: https://github.com/conclurer/ProcessWire-AIOM-All-In-One-Minify

At Conclurer, we are exited to take care of AIOM. For the near future, we're working on necessary bug fixes. We're also planning to release a new major version (AIOM 4) within the next months. 

For any new bugs in the current version of AIOM: please open a ticket on our GitHub repository.

Thank you in advance,

Marvin

  • Like 9
Link to comment
Share on other sites

Hello everybody,

We've just updated AIOM to Version 3.1.4. This is a minor update including the following changes:

  • Bugfix: CacheFiles for Pages are now deleted when a new minimized file is created
  • Bugfix: An error is thrown if the document root is different to ProcessWire's base path

If you find additional bugs or have some feature wishes, please open up a ticket at our GitHub repository.

Thank you!

Marvin

  • Like 6
Link to comment
Share on other sites

  • 1 month later...

Hey guys, i am trying this module out on my development (Local) server before deploying to staging server.

I am currently having an issue with CSS URL rewrites. My Local implementation of processwire for the site I am developing is at 

http://localhost/sitename/

I have tried with config file to add host 'localhost' and 'localhost/sitename'. Neither seems to make a difference the module is rewriting to 

http://localhost/site/templates/css/{fonts or icons}/filename

Any ideas what i should be doing, for instance would this work if I moved the directories for fonts and icons up to just under /templates/ ?

Link to comment
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 monollonom
      (once again I was surprised to see a work of mine pop up in the newsletter, this time without even listing the module on PW modules website 😅. Thx @teppo !)
      FieldtypeQRCode
      Github: https://github.com/romaincazier/FieldtypeQRCode
      Modules directory: https://processwire.com/modules/fieldtype-qrcode/
      A simple fieldtype generating a QR Code from the public URL of the page, and more.
      Using the PHP library QR Code Generator by Kazuhiko Arase.

      Options
      In the field’s Details tab you can change between .gif or .svg formats. If you select .svg you will have the option to directly output the markup instead of a base64 image. SVG is the default.
      You can also change what is used to generate the QR code and even have several sources. The accepted sources (separated by a comma) are: httpUrl, editUrl, or the name of any text/URL/file/image field.
      If LanguageSupport is installed the compatible sources (httpUrl, text field, ...) will return as many QR codes as there are languages. Note however that when outputting on the front-end, only the languages visible to the user will be generated.
      Formatting
      Unformatted value
      When using $page->getUnformatted("qrcode_field") it returns an array with the following structure:
      [ [ "label" => string, // label used in the admin "qr" => string, // the qrcode image "source" => string, // the source, as defined in the configuration "text" => string // and the text used to generate the qrcode ], ... ] Formatted value
      The formatted value is an <img>/<svg> (or several right next to each other). There is no other markup.
      Should you need the same markup as in the admin you could use:
      $field = $fields->get("qrcode_field"); $field->type->markupValue($page, $field, $page->getUnformatted("qrcode_field")); But it’s a bit cumbersome, plus you need to import the FieldtypeQRCode's css/js. Best is to make your own markup using the unformatted value.
      Static QR code generator
      You can call FieldtypeQRCode::generateQRCode to generate any QR code you want. Its arguments are:
      string $text bool $svg Generate the QR code as svg instead of gif ? (default=true) bool $markup If svg, output its markup instead of a base64 ? (default=false) Hooks
      Please have a look at the source code for more details about the hookable functions.
      Examples
      $wire->addHookAfter("FieldtypeQRCode::getQRText", function($event) { $page = $event->arguments("page"); $event->return = $page->title; // or could be: $event->return = "Your custom text"; }) $wire->addHookAfter("FieldtypeQRCode::generateQRCodes", function($event) { $qrcodes = $event->return; // keep everything except the QR codes generated from editUrl foreach($qrcodes as $key => &$qrcode) { if($qrcode["source"] === "editUrl") { unset($qrcodes[$key]); } } unset($qrcode); $event->return = $qrcodes; })
    • By Sebi
      AppApiFile adds the /file endpoint to the AppApi routes definition. Makes it possible to query files via the api. 
      This module relies on the base module AppApi, which must be installed before AppApiFile can do its work.
      Features
      You can access all files that are uploaded at any ProcessWire page. Call api/file/route/in/pagetree?file=test.jpg to access a page via its route in the page tree. Alternatively you can call api/file/4242?file=test.jpg (e.g.,) to access a page by its id. The module will make sure that the page is accessible by the active user.
      The GET-param "file" defines the basename of the file which you want to get.
      The following GET-params (optional) can be used to manipulate an image:
      width height maxwidth maxheight cropX cropY Use GET-Param format=base64 to receive the file in base64 format.
    • By MarkE
      This fieldtype and inputfield bundle was built for storing measurement values within a field, rendering them in a variety of formats and converting them to other units or otherwise modifying them via the API.
      The API consists of a number of predefined functions, some of which include...
      render() for rendering the measurement object, valueAs() for converting the value to another unit value, convertTo() for converting the whole measurement object to different units, and add() and subtract() for for modifying the stored value by the value (converted as required) in another measurement. In the admin the inputfield includes a checkbox (which can be optionally disabled) for converting values on page save. For an example if a value was typed in as centimeters, the unit was changed to metres, and the page saved with this checkbox selected, said value would be automatically converted so that e.g. 170 cm becomes 1.7 m.

      A simple length field using Fieldtype Measurement and Inputfield Measurement.
      Combination units (e.g. feet and inches) are also supported.
      Please note that this module is 'proof of concept' at the moment - there are limited units available and quite a lot of code tidying to do. More units will be added shortly.
      See the GitHub at https://github.com/MetaTunes/FieldtypeMeasurement for full details and updates.
    • By tcnet
      File Manager for ProcessWire is a module to manager files and folders from the CMS backend. It supports creating, deleting, renaming, packing, unpacking, uploading, downloading and editing of files and folders. The integrated code editor ACE supports highlighting of all common programming languages.
      https://github.com/techcnet/ProcessFileManager

      Warning
      This module is probably the most powerful module. You might destroy your processwire installation if you don't exactly know what you doing. Be careful and use it at your own risk!
      ACE code editor
      This module uses ACE code editor available from: https://github.com/ajaxorg/ace

      Dragscroll
      This module uses the JavaScript dragscroll available from: http://github.com/asvd/dragscroll. Dragscroll adds the ability to drag the table horizontally with the mouse pointer.
      PHP File Manager
      This module uses a modified version of PHP File Manager available from: https://github.com/alexantr/filemanager
       
    • By tcnet
      This module implements the website live chat service from tawk.to. Actually the module doesn't have to do much. It just need to inserted a few lines of JavaScript just before the closing body tag </body> on each side. However, the module offers additional options to display the widget only on certain pages.
      Create an account
      Visit https://www.tawk.to and create an account. It's free! At some point you will reach a page where you can copy the required JavaScript-code.

      Open the module settings and paste the JavaScript-code into the field as shown below. Click "Submit" and that's all.

      Open the module settings
      The settings for this module are located int the menu Modules=>Configure=>LiveChatTawkTo.

       
×
×
  • Create New...