You are here

README.txt in Advanced CSS/JS Aggregation 7

Same filename and directory in other branches
  1. 8.2 README.txt
  2. 6 README.txt
----------------------------------
ADVANCED CSS/JS AGGREGATION MODULE
----------------------------------


CONTENTS OF THIS FILE
---------------------

 * Fast 404
 * Features & benefits
 * Configuration
 * Notes
 * JavaScript Bookmarklet
 * Technical Details & Hooks
 * Single htaccess rules
 * nginx Configuration


FAST 404
--------

Assuming that this guide was followed:
http://2bits.com/drupal-planet/reducing-server-resource-utilization-busy-sites-implementing-fast-404s-drupal.html
and your having issues with Advanced CSS/JS Aggregation. Advagg works similar
to imagecache, thus we need to add in an exceptions for the directories that
advagg uses. Replace this if statement

    if (!strpos($_SERVER['QUERY_STRING'], 'imagecache')) {

with one like this:

    if (!strpos($_SERVER['QUERY_STRING'], 'imagecache') && !strpos($_SERVER['QUERY_STRING'], '/advagg_')) {

This will most likely be in your settings.php file.

If using Nginx make sure there is a rule similar to this in your configuration.
http://drupal.org/node/1116618#comment-4321724

If this is still an issue you can try setting the
"IP Address to send all asynchronous requests to" setting on the
admin/settings/advagg/config page to -1. This will use the hostname instead of
an IP address when making the http request.

If you are still having problems, open an issue on the advagg issue queue:
http://drupal.org/project/issues/advagg


FEATURES & BENEFITS
-------------------

Advanced CSS/JS Aggregation Core Module:
 * Imagecache style CSS/JS Aggregation. If the file doesn't exist it will be
   generated on demand.
 * Stampede protection for CSS and JS aggregation. Uses locking so multiple
   requests for the same thing will result in only one thread doing the work.
 * Zero file I/O if the Aggregated file already exists. Results in better page
   generation performance.
 * Fully cached CSS/JS assets making this module faster than drupal core.
 * Smarter aggregate deletion. CSS/JS aggregates only get removed from the cache
   if they have not been used/accessed in the last 3 days.
 * Smarter cache flushing. Scans all CSS/JS files that have been added to any
   aggregate; if that file has changed then rebuild all aggregates that contain
   the updated file and give the newly aggregated file a new name. The new name
   ensures changes go out when using CDNs.
 * Works with Drupal's private file system. Can Use a separate directory for
   serving aggregated files from.
 * Footer JS gets aggregated as well.
 * One can add JS to any region & have it aggregated.
   drupal_add_js($data, 'module', 'left') is now possible; JS is appended to the
   the end of that region.
 * One can add external JS/CSS resources.
    drupal_add_js('http://example.org/example.js', 'external');
    drupal_add_css('http://example.org/example.css', 'external');
   is now possible.
 * Url query string to turn off aggregation for that request. ?advagg=0 will
   turn off file aggregation if the user has the "bypass advanced aggregation"
   permission. ?advagg=-1 will completely bypass all of Advanced CSS/JS
   Aggregations modules and submodules.
 * Button on the admin page for dropping a cookie that will turn off file
   aggregation. Useful for theme development.
 * Url query string to turn on advagg debugging for that request.
   ?advagg-debug=1 will output a large debug string to the watchdog if the user
   has the "bypass advanced aggregation" permission.
 * Gzip support. All aggregated files can be pre-compressed into a .gz file and
   served from Apache. This is faster then gzipping the file on each request.
 * IE Unlimited CSS support. If using ?advagg=0 the CSS output will change
   to use @import style in order to get around the 31 CSS files limit in IE.
 * CDN support. Advagg integrates with this module.
 * jQuery Update support. Advagg integrates with this module.
 * LABjs support. Advagg integrates with this module.
 * One year browser cache lifetimes for all aggregated files. This is a good
   thing.
 * Drush support. "cc advagg" will issue a smart cache flush.
 * Admin menu support. Cache flushing Advanced CSS/JS Aggregation is available
   in the "Flush all caches" menu.

Advanced CSS/JS Aggregation Submodules:
 CSS:
 * CSSTidy library support. Can compress the generated CSS files with the
   CSSTidy library.
 * CSS Compressor 3.0 support. https://github.com/codenothing/css-compressor
 JS:
 * JSMin+ library support. Can compress the generated JS files with the jsmin+
   library.
 * JSMin PHP Extension support. http://www.ypass.net/software/php_jsmin/
 * Use Dean Edwards Packer on non gzipped files. .gz files will not be packed.
 CDN:
 * Google's CDN network. Load jquery.js & jquery-ui.js from using the Google
   Libraries API. This is a good thing.
 Bundler:
 * Bundler. Will split up an aggregate into sub aggregates for better load
   times throughout your site.

3rd Party modules:
 CSS:
 * Parallel CSS - AdvAgg Plugin. Have url()'s in css files reference different
   CDN domains.


CONFIGURATION
-------------

Settings page is located at:
admin/settings/advagg
 * Enable Advanced Aggregation. You can disable the module here. Same effect as
   placing ?advagg=-1 in the URL.
 * Use AdvAgg in closure. If enabled javascript files in the closure region will
   be aggregated by advagg.
 * Generate CSS/JS files on request (async mode). If advagg doesn't have a route
   back to its self and this is enabled then you will have a broken site. With
   this enabled one can expect much quicker page generation times after a cache
   flush.
 * Gzip CSS/JS files. For every Aggregated file generated, this will create a
   gzip version of that and then serve that out if the browser accepts gzip
   compression.
 * Generate .htaccess files in the advagg_* dirs. If your using the rules
   located at the bottom of this document in your webroots htaccess file then
   you can disable this checkbox.
 * Regenerate flushed bundles in the cache flush request. You can enable if your
   server will not timeout on a request. This will call advagg_rebuild_bundle()
   as a shutdown function for every bundle that has been marked as expired;
   thus rebuilding that bundle in the same request as the flush.
 * Use a different directory for storing advagg files. Only available if your
   using a private file system. Allows you to save the generated aggregated
   files in a different directory. This gets around the private file system
   restrictions. If boost is installed, you can safely use the cache directory.
 * Aggregation Inclusion Mode. Should the page wait for the aggregate to be
   built before including the file, or should it send out the page with
   aggregates not included.
 * Disable page caching if all aggregates are not included on the page.
 * File Checksum Mode. mtime is the file modification time. md5 is a hash of the
   files contents.
 * IP Address to send all asynchronous requests to. If you wish to have one
   server generate all CSS/JS aggregated files then this allows for that to
   happen.
 * Smart cache flush button. Scan all files referenced in aggregated files. If any of
   them have changed, increment the counters containing that file and rebuild
   the bundle.
 * Cache Rebuild button. Recreate all aggregated files. Useful if JS or CSS
   compression was just enabled.
 * Forced Cache Rebuild. Recreate all aggregated files by incrementing internal
   counter for every bundle. One should never have to use this option.
 * Master Reset. Clean slate; same affect as uninstalling the module.
 * Rebuild htaccess files. Recreate the generated htaccess files.
 * Aggregation Bypass Cookie. This will set or remove a cookie that disables
   aggregation for the remainder of the browser session. It acts almost the same
   as adding ?advagg=0 to every URL.

Additional information is available at:
admin/settings/advagg/info
 * Hook Theme Info. Displays the preprocess_page order. Used for debugging.
 * CSS files. Displays how often a files checksum has changed and any data
   stored about it.
 * JS files. Displays how often a files checksum has changed and any data
   stored about it.
 * Modules implementing advagg hooks. Lets you know what modules are using
   advagg.
 * Missing files. Lets you know the files that are trying to be added but are
   not there.
 * Asynchronous debug info. Outputs the the full object returned from
   drupal_http_request() which is helpful when debugging async issues.


NOTES
-----

--Bundler Sub Module--
When using the bundler sub module, tools like Google Page Speed and YSlow will
complain that not all CSS/JS files are in one aggregate. This has to do with
how drupal_add_js/drupal_add_css works. You can get a better score on these
tools by placing all files into one aggregate, but the issue with doing that
is, different pages load different css/js files, thus on page 2 of the users
visit, you will get worse performance because the browser has to re-download a
whole new css & js aggregate rather then the smaller aggregate that only
changed. The bundler attempts to work around this issue by creating various
bundles, each one being chosen fairly smartly so that instead of downloading a
200KB js file you only have to download a 20KB file on the 2nd page.

The bundler sub module is all about balancing trade offs. You can make a site
that had really good performance stats according to the tools but you would
then have to re-download just about everything on a different page of your
site, because not all your pages are the same. If you don't care about this and
want a good score from pagespeed, disable the bundler sub-module. That will
give you a better score, but then you have to download a new (large) aggregate
on different parts of your website and already downloaded file reuse will be
lower.

--Cron--
The cron job for AdvAgg is there as a garbage collector. It only needs to run
once a week; running it every hour isn't going to be bad, it isn't necessary
though.


JAVASCRIPT BOOKMARKLET
----------------------

You can use this JS code as a bookmarklet for toggling the AdvAgg URL parameter.
See http://en.wikipedia.org/wiki/Bookmarklet for more details.

    javascript:(function(){var loc = document.location.href,qs = document.location.search,regex_off = /\&?advagg=-1/,goto = loc;if(qs.match(regex_off)) {goto = loc.replace(regex_off, '');} else {qs = qs ? qs + '&advagg=-1' : '?advagg=-1';goto = document.location.pathname + qs;}window.location = goto;})();


TECHNICAL DETAILS & HOOKS
-------------------------

Technical Details:
 * There are two database tables and two cache table used by advagg.
 * Files are generated by this pattern: css_[MD5]_[Counter].css
 * Every JS file is tested for compressibility. This is necessary because jsmin+
   can run out of memory on certain files. This allows us to catch these bad
   files and mark them. Also allows us to skip files that are already
   compressed.

Hooks:
 * hook_advagg_css_alter. Modify the data before it gets written to the file.
   Useful for compression.
 * hook_advagg_css_inline_alter. Modify the data before it gets embedded in the
   page. Useful for compression.
 * hook_advagg_css_pre_alter. Modify the raw $variables['css'] before it gets
   processed. Useful for file replacement.
 * hook_advagg_css_extra_alter. Allows one to set the a prefix and suffix to be
   added into the HTML DOM. Useful for CSS conditionals.

 * hook_advagg_js_alter. Modify the data before it gets written to the file.
   Useful for compression.
 * hook_advagg_js_inline_alter. Modify the data before it gets embedded in the
   page. Useful for compression.
 * hook_advagg_js_pre_alter. Modify the raw $javascript before it gets
   processed. Useful for file replacement.
 * hook_advagg_js_extra_alter. Allows one to set the a prefix and suffix to be
   added into the HTML DOM.
 * hook_advagg_js_header_footer_alter. Allows one to move JS from the header to
   the footer. Also one can look at both header and footer JS arrays before they
   get processed.

 * hook_advagg_filenames_alter. Allows for a one to many relationship. A single
   request for a bundle name can result in multiple bundles being returned.
 * hook_advagg_files_table. Allows for modules to mark a file as expired.
 * advagg_master_reset. Allows other modules to take part in a master reset.
 * advagg_disable_processor. Allows one to turn off advagg from a hook. See the
   advagg_advagg_disable_processor() function for example usage.
 * advagg_disable_page_cache. Allows 3rd party page cache plugins like boost or
   varnish to not cache this page.
 * advagg_bundler_analysis_alter. Give installed modules a chance to alter the
   bundler's analysis array.

JS/CSS Theme Override:

    $conf['advagg_css_render_function'] - advagg_unlimited_css_builder
    $conf['advagg_js_render_function'] - advagg_js_builder

JS/CSS File Save Override:

    $conf['advagg_file_save_function'] - advagg_file_saver

Public Functions:
 * advagg_add_css_inline. Adds the ability to add in inline CSS to the page with
   a prefix and suffix being set as well.


SINGLE HTACCESS RULES
---------------------

If the directory level htaccess rules are interfering with your server, you can
place these rules in the Drupal root htaccess file. Place these rules after
"RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]" but before "</IfModule>"


  # Rules to correctly serve gzip compressed CSS and JS files.
  # Requires both mod_rewrite and mod_headers to be enabled.
  <IfModule mod_headers.c>
    # Serve gzip compressed CSS/JS files if they exist and client accepts gzip.
    RewriteCond %{HTTP:Accept-encoding} gzip
    RewriteCond %{REQUEST_URI} (^/(.+)/advagg_(j|cs)s/(.+)\.(j|cs)s) [NC]
    RewriteCond %{REQUEST_FILENAME}\.gz -s
    RewriteRule ^(.*)\.(j|cs)s$ $1\.$2s\.gz [QSA]

    # Serve correct content types, and prevent mod_deflate double gzip.
    RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
    RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]

    <FilesMatch "\.(j|cs)s\.gz$">
      # Serve correct encoding type.
      Header set Content-Encoding gzip
      # Force proxies to cache gzipped & non-gzipped css/js files separately.
      Header append Vary Accept-Encoding
    </FilesMatch>
  </IfModule>


You also need to place these rules at the very end of your htaccess file, after
"</IfModule>".


# AdvAgg Rules Start.
<FilesMatch "^(j|cs)s_[0-9a-f]{32}_.+\.(j|cs)s(\.gz)?">
  # No mod_headers
  <IfModule !mod_headers.c>
    # No mod_expires
    <IfModule !mod_expires.c>
      # Use ETags.
      FileETag MTime Size
    </IfModule>

    # Use Expires Directive.
    <IfModule mod_expires.c>
      # Do not use ETags.
      FileETag None
      # Enable expirations.
      ExpiresActive On
      # Cache all aggregated CSS/JS files for 480 weeks after access (A).
      ExpiresDefault A290304000
    </IfModule>
  </IfModule>

  <IfModule mod_headers.c>
    # Set a far future Cache-Control header to 480 weeks.
    Header set Cache-Control "max-age=290304000, no-transform, public"
    # Set a far future Expires header.
    Header set Expires "Tue, 20 Jan 2037 04:20:42 GMT"
    # Pretend the file was last modified a long time ago in the past.
    Header set Last-Modified "Wed, 20 Jan 1988 04:20:42 GMT"
    # Do not use etags for cache validation.
    Header unset ETag
  </IfModule>
</FilesMatch>
# AdvAgg Rules End.


Be sure to disable the "Generate .htaccess files in the advagg_* dirs" setting
on the admin/settings/advagg page after placing these rules in the webroots
htaccess file. This is located at the same directory level as Drupal's
index.php.


NGINX CONFIGURATION
-------------------

http://drupal.org/node/1116618

    ###
    ### advagg_css and advagg_js support
    ###
    location ~* files/advagg_(?:css|js)/ {
      access_log off;
      expires    max;
      add_header ETag "";
      add_header Cache-Control "max-age=290304000, no-transform, public";
      add_header Last-Modified "Wed, 20 Jan 1988 04:20:42 GMT";
      try_files  $uri @drupal;
    }

File

README.txt
View source
  1. ----------------------------------
  2. ADVANCED CSS/JS AGGREGATION MODULE
  3. ----------------------------------
  4. CONTENTS OF THIS FILE
  5. ---------------------
  6. * Fast 404
  7. * Features & benefits
  8. * Configuration
  9. * Notes
  10. * JavaScript Bookmarklet
  11. * Technical Details & Hooks
  12. * Single htaccess rules
  13. * nginx Configuration
  14. FAST 404
  15. --------
  16. Assuming that this guide was followed:
  17. http://2bits.com/drupal-planet/reducing-server-resource-utilization-busy-sites-implementing-fast-404s-drupal.html
  18. and your having issues with Advanced CSS/JS Aggregation. Advagg works similar
  19. to imagecache, thus we need to add in an exceptions for the directories that
  20. advagg uses. Replace this if statement
  21. if (!strpos($_SERVER['QUERY_STRING'], 'imagecache')) {
  22. with one like this:
  23. if (!strpos($_SERVER['QUERY_STRING'], 'imagecache') && !strpos($_SERVER['QUERY_STRING'], '/advagg_')) {
  24. This will most likely be in your settings.php file.
  25. If using Nginx make sure there is a rule similar to this in your configuration.
  26. http://drupal.org/node/1116618#comment-4321724
  27. If this is still an issue you can try setting the
  28. "IP Address to send all asynchronous requests to" setting on the
  29. admin/settings/advagg/config page to -1. This will use the hostname instead of
  30. an IP address when making the http request.
  31. If you are still having problems, open an issue on the advagg issue queue:
  32. http://drupal.org/project/issues/advagg
  33. FEATURES & BENEFITS
  34. -------------------
  35. Advanced CSS/JS Aggregation Core Module:
  36. * Imagecache style CSS/JS Aggregation. If the file doesn't exist it will be
  37. generated on demand.
  38. * Stampede protection for CSS and JS aggregation. Uses locking so multiple
  39. requests for the same thing will result in only one thread doing the work.
  40. * Zero file I/O if the Aggregated file already exists. Results in better page
  41. generation performance.
  42. * Fully cached CSS/JS assets making this module faster than drupal core.
  43. * Smarter aggregate deletion. CSS/JS aggregates only get removed from the cache
  44. if they have not been used/accessed in the last 3 days.
  45. * Smarter cache flushing. Scans all CSS/JS files that have been added to any
  46. aggregate; if that file has changed then rebuild all aggregates that contain
  47. the updated file and give the newly aggregated file a new name. The new name
  48. ensures changes go out when using CDNs.
  49. * Works with Drupal's private file system. Can Use a separate directory for
  50. serving aggregated files from.
  51. * Footer JS gets aggregated as well.
  52. * One can add JS to any region & have it aggregated.
  53. drupal_add_js($data, 'module', 'left') is now possible; JS is appended to the
  54. the end of that region.
  55. * One can add external JS/CSS resources.
  56. drupal_add_js('http://example.org/example.js', 'external');
  57. drupal_add_css('http://example.org/example.css', 'external');
  58. is now possible.
  59. * Url query string to turn off aggregation for that request. ?advagg=0 will
  60. turn off file aggregation if the user has the "bypass advanced aggregation"
  61. permission. ?advagg=-1 will completely bypass all of Advanced CSS/JS
  62. Aggregations modules and submodules.
  63. * Button on the admin page for dropping a cookie that will turn off file
  64. aggregation. Useful for theme development.
  65. * Url query string to turn on advagg debugging for that request.
  66. ?advagg-debug=1 will output a large debug string to the watchdog if the user
  67. has the "bypass advanced aggregation" permission.
  68. * Gzip support. All aggregated files can be pre-compressed into a .gz file and
  69. served from Apache. This is faster then gzipping the file on each request.
  70. * IE Unlimited CSS support. If using ?advagg=0 the CSS output will change
  71. to use @import style in order to get around the 31 CSS files limit in IE.
  72. * CDN support. Advagg integrates with this module.
  73. * jQuery Update support. Advagg integrates with this module.
  74. * LABjs support. Advagg integrates with this module.
  75. * One year browser cache lifetimes for all aggregated files. This is a good
  76. thing.
  77. * Drush support. "cc advagg" will issue a smart cache flush.
  78. * Admin menu support. Cache flushing Advanced CSS/JS Aggregation is available
  79. in the "Flush all caches" menu.
  80. Advanced CSS/JS Aggregation Submodules:
  81. CSS:
  82. * CSSTidy library support. Can compress the generated CSS files with the
  83. CSSTidy library.
  84. * CSS Compressor 3.0 support. https://github.com/codenothing/css-compressor
  85. JS:
  86. * JSMin+ library support. Can compress the generated JS files with the jsmin+
  87. library.
  88. * JSMin PHP Extension support. http://www.ypass.net/software/php_jsmin/
  89. * Use Dean Edwards Packer on non gzipped files. .gz files will not be packed.
  90. CDN:
  91. * Google's CDN network. Load jquery.js & jquery-ui.js from using the Google
  92. Libraries API. This is a good thing.
  93. Bundler:
  94. * Bundler. Will split up an aggregate into sub aggregates for better load
  95. times throughout your site.
  96. 3rd Party modules:
  97. CSS:
  98. * Parallel CSS - AdvAgg Plugin. Have url()'s in css files reference different
  99. CDN domains.
  100. CONFIGURATION
  101. -------------
  102. Settings page is located at:
  103. admin/settings/advagg
  104. * Enable Advanced Aggregation. You can disable the module here. Same effect as
  105. placing ?advagg=-1 in the URL.
  106. * Use AdvAgg in closure. If enabled javascript files in the closure region will
  107. be aggregated by advagg.
  108. * Generate CSS/JS files on request (async mode). If advagg doesn't have a route
  109. back to its self and this is enabled then you will have a broken site. With
  110. this enabled one can expect much quicker page generation times after a cache
  111. flush.
  112. * Gzip CSS/JS files. For every Aggregated file generated, this will create a
  113. gzip version of that and then serve that out if the browser accepts gzip
  114. compression.
  115. * Generate .htaccess files in the advagg_* dirs. If your using the rules
  116. located at the bottom of this document in your webroots htaccess file then
  117. you can disable this checkbox.
  118. * Regenerate flushed bundles in the cache flush request. You can enable if your
  119. server will not timeout on a request. This will call advagg_rebuild_bundle()
  120. as a shutdown function for every bundle that has been marked as expired;
  121. thus rebuilding that bundle in the same request as the flush.
  122. * Use a different directory for storing advagg files. Only available if your
  123. using a private file system. Allows you to save the generated aggregated
  124. files in a different directory. This gets around the private file system
  125. restrictions. If boost is installed, you can safely use the cache directory.
  126. * Aggregation Inclusion Mode. Should the page wait for the aggregate to be
  127. built before including the file, or should it send out the page with
  128. aggregates not included.
  129. * Disable page caching if all aggregates are not included on the page.
  130. * File Checksum Mode. mtime is the file modification time. md5 is a hash of the
  131. files contents.
  132. * IP Address to send all asynchronous requests to. If you wish to have one
  133. server generate all CSS/JS aggregated files then this allows for that to
  134. happen.
  135. * Smart cache flush button. Scan all files referenced in aggregated files. If any of
  136. them have changed, increment the counters containing that file and rebuild
  137. the bundle.
  138. * Cache Rebuild button. Recreate all aggregated files. Useful if JS or CSS
  139. compression was just enabled.
  140. * Forced Cache Rebuild. Recreate all aggregated files by incrementing internal
  141. counter for every bundle. One should never have to use this option.
  142. * Master Reset. Clean slate; same affect as uninstalling the module.
  143. * Rebuild htaccess files. Recreate the generated htaccess files.
  144. * Aggregation Bypass Cookie. This will set or remove a cookie that disables
  145. aggregation for the remainder of the browser session. It acts almost the same
  146. as adding ?advagg=0 to every URL.
  147. Additional information is available at:
  148. admin/settings/advagg/info
  149. * Hook Theme Info. Displays the preprocess_page order. Used for debugging.
  150. * CSS files. Displays how often a files checksum has changed and any data
  151. stored about it.
  152. * JS files. Displays how often a files checksum has changed and any data
  153. stored about it.
  154. * Modules implementing advagg hooks. Lets you know what modules are using
  155. advagg.
  156. * Missing files. Lets you know the files that are trying to be added but are
  157. not there.
  158. * Asynchronous debug info. Outputs the the full object returned from
  159. drupal_http_request() which is helpful when debugging async issues.
  160. NOTES
  161. -----
  162. --Bundler Sub Module--
  163. When using the bundler sub module, tools like Google Page Speed and YSlow will
  164. complain that not all CSS/JS files are in one aggregate. This has to do with
  165. how drupal_add_js/drupal_add_css works. You can get a better score on these
  166. tools by placing all files into one aggregate, but the issue with doing that
  167. is, different pages load different css/js files, thus on page 2 of the users
  168. visit, you will get worse performance because the browser has to re-download a
  169. whole new css & js aggregate rather then the smaller aggregate that only
  170. changed. The bundler attempts to work around this issue by creating various
  171. bundles, each one being chosen fairly smartly so that instead of downloading a
  172. 200KB js file you only have to download a 20KB file on the 2nd page.
  173. The bundler sub module is all about balancing trade offs. You can make a site
  174. that had really good performance stats according to the tools but you would
  175. then have to re-download just about everything on a different page of your
  176. site, because not all your pages are the same. If you don't care about this and
  177. want a good score from pagespeed, disable the bundler sub-module. That will
  178. give you a better score, but then you have to download a new (large) aggregate
  179. on different parts of your website and already downloaded file reuse will be
  180. lower.
  181. --Cron--
  182. The cron job for AdvAgg is there as a garbage collector. It only needs to run
  183. once a week; running it every hour isn't going to be bad, it isn't necessary
  184. though.
  185. JAVASCRIPT BOOKMARKLET
  186. ----------------------
  187. You can use this JS code as a bookmarklet for toggling the AdvAgg URL parameter.
  188. See http://en.wikipedia.org/wiki/Bookmarklet for more details.
  189. javascript:(function(){var loc = document.location.href,qs = document.location.search,regex_off = /\&?advagg=-1/,goto = loc;if(qs.match(regex_off)) {goto = loc.replace(regex_off, '');} else {qs = qs ? qs + '&advagg=-1' : '?advagg=-1';goto = document.location.pathname + qs;}window.location = goto;})();
  190. TECHNICAL DETAILS & HOOKS
  191. -------------------------
  192. Technical Details:
  193. * There are two database tables and two cache table used by advagg.
  194. * Files are generated by this pattern: css_[MD5]_[Counter].css
  195. * Every JS file is tested for compressibility. This is necessary because jsmin+
  196. can run out of memory on certain files. This allows us to catch these bad
  197. files and mark them. Also allows us to skip files that are already
  198. compressed.
  199. Hooks:
  200. * hook_advagg_css_alter. Modify the data before it gets written to the file.
  201. Useful for compression.
  202. * hook_advagg_css_inline_alter. Modify the data before it gets embedded in the
  203. page. Useful for compression.
  204. * hook_advagg_css_pre_alter. Modify the raw $variables['css'] before it gets
  205. processed. Useful for file replacement.
  206. * hook_advagg_css_extra_alter. Allows one to set the a prefix and suffix to be
  207. added into the HTML DOM. Useful for CSS conditionals.
  208. * hook_advagg_js_alter. Modify the data before it gets written to the file.
  209. Useful for compression.
  210. * hook_advagg_js_inline_alter. Modify the data before it gets embedded in the
  211. page. Useful for compression.
  212. * hook_advagg_js_pre_alter. Modify the raw $javascript before it gets
  213. processed. Useful for file replacement.
  214. * hook_advagg_js_extra_alter. Allows one to set the a prefix and suffix to be
  215. added into the HTML DOM.
  216. * hook_advagg_js_header_footer_alter. Allows one to move JS from the header to
  217. the footer. Also one can look at both header and footer JS arrays before they
  218. get processed.
  219. * hook_advagg_filenames_alter. Allows for a one to many relationship. A single
  220. request for a bundle name can result in multiple bundles being returned.
  221. * hook_advagg_files_table. Allows for modules to mark a file as expired.
  222. * advagg_master_reset. Allows other modules to take part in a master reset.
  223. * advagg_disable_processor. Allows one to turn off advagg from a hook. See the
  224. advagg_advagg_disable_processor() function for example usage.
  225. * advagg_disable_page_cache. Allows 3rd party page cache plugins like boost or
  226. varnish to not cache this page.
  227. * advagg_bundler_analysis_alter. Give installed modules a chance to alter the
  228. bundler's analysis array.
  229. JS/CSS Theme Override:
  230. $conf['advagg_css_render_function'] - advagg_unlimited_css_builder
  231. $conf['advagg_js_render_function'] - advagg_js_builder
  232. JS/CSS File Save Override:
  233. $conf['advagg_file_save_function'] - advagg_file_saver
  234. Public Functions:
  235. * advagg_add_css_inline. Adds the ability to add in inline CSS to the page with
  236. a prefix and suffix being set as well.
  237. SINGLE HTACCESS RULES
  238. ---------------------
  239. If the directory level htaccess rules are interfering with your server, you can
  240. place these rules in the Drupal root htaccess file. Place these rules after
  241. "RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]" but before ""
  242. # Rules to correctly serve gzip compressed CSS and JS files.
  243. # Requires both mod_rewrite and mod_headers to be enabled.
  244. # Serve gzip compressed CSS/JS files if they exist and client accepts gzip.
  245. RewriteCond %{HTTP:Accept-encoding} gzip
  246. RewriteCond %{REQUEST_URI} (^/(.+)/advagg_(j|cs)s/(.+)\.(j|cs)s) [NC]
  247. RewriteCond %{REQUEST_FILENAME}\.gz -s
  248. RewriteRule ^(.*)\.(j|cs)s$ $1\.$2s\.gz [QSA]
  249. # Serve correct content types, and prevent mod_deflate double gzip.
  250. RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
  251. RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]
  252. # Serve correct encoding type.
  253. Header set Content-Encoding gzip
  254. # Force proxies to cache gzipped & non-gzipped css/js files separately.
  255. Header append Vary Accept-Encoding
  256. You also need to place these rules at the very end of your htaccess file, after
  257. "".
  258. # AdvAgg Rules Start.
  259. # No mod_headers
  260. # No mod_expires
  261. # Use ETags.
  262. FileETag MTime Size
  263. # Use Expires Directive.
  264. # Do not use ETags.
  265. FileETag None
  266. # Enable expirations.
  267. ExpiresActive On
  268. # Cache all aggregated CSS/JS files for 480 weeks after access (A).
  269. ExpiresDefault A290304000
  270. # Set a far future Cache-Control header to 480 weeks.
  271. Header set Cache-Control "max-age=290304000, no-transform, public"
  272. # Set a far future Expires header.
  273. Header set Expires "Tue, 20 Jan 2037 04:20:42 GMT"
  274. # Pretend the file was last modified a long time ago in the past.
  275. Header set Last-Modified "Wed, 20 Jan 1988 04:20:42 GMT"
  276. # Do not use etags for cache validation.
  277. Header unset ETag
  278. # AdvAgg Rules End.
  279. Be sure to disable the "Generate .htaccess files in the advagg_* dirs" setting
  280. on the admin/settings/advagg page after placing these rules in the webroots
  281. htaccess file. This is located at the same directory level as Drupal's
  282. index.php.
  283. NGINX CONFIGURATION
  284. -------------------
  285. http://drupal.org/node/1116618
  286. ###
  287. ### advagg_css and advagg_js support
  288. ###
  289. location ~* files/advagg_(?:css|js)/ {
  290. access_log off;
  291. expires max;
  292. add_header ETag "";
  293. add_header Cache-Control "max-age=290304000, no-transform, public";
  294. add_header Last-Modified "Wed, 20 Jan 1988 04:20:42 GMT";
  295. try_files $uri @drupal;
  296. }