
Objectives
----------

I made this utility for the works in the jsonserver integration and
AZAX/kukit. This was meant to be a temporary, lightweight solution but it
has long term merits too. I needed this because I wanted a solution that
works right now, works on zope3 and zope 2.8 even (so zc.resourcelibraries
was not a choice), does not depend on Plone (so ResourceRegistries is out
too).

The interesting point of the utility is: instead of building registries to
emit include tags in the HTML, it simply makes one resource that needs to
be imported in a single line::

    <browser:concatresource
           name="test.js"
           files="test1.js
                  test2.js"
    />

Also:

- it compresses the JS or CSS files with Florian Schulze's compressor
  from ResourceRegistries
  
- it contains an utility interface that another component can implement
  to dynamically extend the list of files (like I did with AZAX). So the
  "registry" is not really implemented but can be plugged in.
  
- it is tested (although not much) to work with Zope 2.8, 2.9, 3.1, 3.2

Meanwhile I implemented the cache headers for the resources correctly
here, the current implementation of caching is broken in Five and I
believe in Z3 resources as well; beware that I considered the original
Zope3 code only and did not look at additional utilities. According to my
observation: in Z3 the original resources attempt to handle the cache
headers correctly but never really check if the file gets changed on the
filesystem (only on restart). If this is really a problem and not just I
believe, then it is fixed in my code. (Read more in the Caching part.)

More information on this issue:

http://article.gmane.org/gmane.comp.web.zope.z3base.general/53

Compression
-----------

You can use more levels of compressions with the compress_level attribute.

    <browser:concatresource
           name="test.js"
           files="test1.js
                  test2.js"
           compress_level="full"
    />

Some explanation:

- compression is only implemented for JavaScript and CSS

- The default level is "safe", this is useable with all scripts

- The "full" level gives even better compression by taking out all newlines
  and mangling private variable names, but some preparation must be made
  in the scripts for that (like putting a ; after }-s I think, and
  also maybe more).
  
- Specifying "none" will leave your resource uncompressed. This
  can be useful for debugging.

Caching control
---------------

You have some possibility to control how caching of resources are done.

    <browser:concatresource
           name="test.js"
           files="test1.js
                  test2.js"
           caching="memory"
           lmt_check_period="10.0"
    />

The attribute "lmt_checking_period" controls how often the file
modification dates are checked from the filesystem. By default this is
60.0, this means that once the file modification is checked, it will not be
checked before the next 60 seconds elapses. In other words, if you change
the files on the filesystem, it will cause a maximum of this long delay
until the changes propagate to the rendered resources. For debugging this
can be set to 0 to allow immediate changes, however in production this
setup would cause the files often looked up in the filesystem, which,
especially with badly implemented filesystems can cause a problem. This
feature is already an enhancement to the original Zope 3 resource
implementation where, unless running in debug mode, changes in the resource
files will require a restart to become visible in the result.

The attribute "caching", when set to "memory", will result that the cooked
resource will be cached in memory and looked up from them as long as the
files are unchanged. This, especially with compress options, can cause a
speedup in rendering the resources. However, in normal operation this is
not necessary at all, since if caching is set up properly, the browser and
the upstream cache asks via the "If-Modified-Since" headers if the resource
has been changed recently, and the resource itself is queried only when
needed, independently of the setup of this option. While debugging,
however, when browser caching is forced to switch off, without this option
the resource would be cooked each time the browser reloads the dependent
page, so in this case setting "caching" to "memory" causes a significant
speedup in these cases. In production however, is not only unnecessary but
also causes an additional memory consumption.

Debug setup
-----------

To summarize with an example, the following settings are advisable while
debugging:

   <browser:concatresource
           name="test.js"
           files="test1.js
                  test2.js"
           compress_level="none"
           caching="memory"
           lmt_check_period="10.0"
    />

Release notes
-------------

In Zope 2.9.2 there is Five 1.3.3 included. This contains a bug that
the resources will never be looked up from the
application root.

To fix this, you need to update Five to version 1.3.5, or update Zope
to version >= 2.9.3.


