Apache::AxKit::Language::FOP - generate PDF using Apache FOP |
Apache::AxKit::Language::FOP - generate PDF using Apache FOP
AxAddStyleMap text/xslfo +Apache::AxKit::Language::FOP PerlSetVar AxFOPConfigFile /path/to/my/userconfig.xml PerlSetVar AxFOPPath /usr/bin/fop
If you want to use JavaServer, specify one or more of:
PerlSetVar AxFOPJavaServerPort 2000 PerlSetVar AxFOPJavaServerAuthFile /path/to/my/authfile PerlSetVar AxFOPJavaServerDirectory /my/special/directory
If you want to cache when PDF is generated dynamically with XSP:
PerlSetVar AxFOPCache IfNoCache
When running under JavaServer, this module will reset FOP's image cache when needed. If you are using an older FOP that does not support this feature, then specify the following to leave the image cache alone:
PerlSetVar AxFOPImageCache On
This module uses Apache FOP to generate PDF by processing XSL-FO files. It can either call the command line tool ``fop'', or for better performance, it can use the XML::ApacheFOP package (which uses the Java.pm Perl package and JavaServer software).
For running FOP via the command line, you can specify the path to your FOP executable with the directive AxFOPPath. The default value is simply ``fop'' which will get resolved by your shell using whatever PATH is currently in effect.
To enable use of XML::ApacheFOP, specify one or more AxFOPJavaServer directives as shown above. Unspecified directives will fall back to their default values defined in XML::ApacheFOP.
If you need FOP to run with an external configuration file, specify
the location using the AxFOPConfigFile directive. See
http://xmlgraphics.apache.org/fop/configuration.html for options you
can specify in an external configuration file. For example, you can
specify a baseDir
to be used when resolving a relative URL from the
src
attribute of an fo:external-graphic
.
Multiple output render types are supported by FOP, to varying degrees:
pdf: application/pdf mif: application/vnd.mif pcl: application/vnd.hp-PCL ps: application/postscript txt: text/plain svg: image/svg+xml at: text/xml
If the AxKit PreferredStyle matches one of the above styles, then that style will be the render type output by this module. If the PreferredStyle does not match, then the output type will be pdf.
The standard AxKit caching mechanism automatically caches the output in most cases (unless disabled with AxNoCache). However, if your content is being generated dynamically from an XSP script, then AxKit will not cache the output.
To enable caching for XSP-generated content, set the configuration directive AxFOPCache to ``IfNoCache''. When this directive is set (and caching is not disabled with AxNoCache), the output will be cached separately by this module whenever AxKit has turned off its caching (that is, when $AxKit::Cache->no_cache returns a true value). The cache file is managed using Apache::AxKit::Cache with a key generated using Digest::MD5 from the input content and the output style.
To turn off separate caching by this module you can set ``AxFOPCache Off'' (this is the default).
The AxKit cache is not automatically cleaned. If space is an issue, such as when you are caching pages that are customized for individual users, then you need to run a cron job or something similar to delete stale files from the cache. For example, see Apache::AxKit::CacheCleaner.
fo:external-graphic
You can use relative links to external graphics. They will be
resolved relative to the directory of your source file. If the
resulting file does not exist, then the relative link will be resolved
relative to the definition of baseDir
in the FOP configuration
file. This behavior mimics that of FOP when called from the command
line--it resolves relative links first with respect to the current
directory and second with respect to baseDir
, which is set to the
location of your source file unless otherwise defined in the FOP
configuration file.
When using JavaServer be sure it has permission to locate and access the external graphic file.
If you have not defined a baseDir
in a FOP configuration file, then
this module will create one with baseDir
set to the source
directory, in case FOP needs to resolve a relative link on its own.
(This feature may be redundant since the link to the external graphic
will have already been resolved by this module, but the feature
remains just in case FOP uses baseDir
for other reasons.)
Why does this module resolve the relative links instead of letting FOP do it? As explained below, FOP caches images between runs (when called through JavaServer), and unfortunately it caches the image based on the link before it gets resolved, which can lead to the wrong image being used if it has the same name but resides in a different directory. For example, if you have a document in one directory that loads an image ``logo.svg'', and you have another document in another directory that loads a different image ``logo.svg'', then FOP will re-use the first image. An additional reason this module resolves the links is because FOP might not run from the same directory as your source file, especially if it is being run through JavaServer, so FOP could load some random graphic relative to its current directory instead of relative to your source file.
AxKit is informed of any external-graphics from your document so that it can check the timestamp and recreate the output instead of using its cache if a graphic file is newer than the cache file (unless you have AxDependencyChecks Off). This module will also perform these dependency checks when you have turned on separate caching (unless you have AxDependencyChecks Off).
When using XML::ApacheFOP with JavaServer, images are cached by FOP between runs. See http://xmlgraphics.apache.org/fop/0.20.5/graphics.html#caching for more information. If you have not disabled caching with AxNoCache and have not turned off AxDependencyChecks, then this module will keep track of which external-graphics have been used and will reset FOP's image cache whenever a graphic file changes or when FOP has cached 1000 images. You can change the limit, for example:
AxFOPImageCache 100
This module uses an SDBM file named AxFOPImageTrack located in AxKit's cache directory to keep track of the graphic files. You can specify a different location or file name, for example:
AxFOPImageTrack /var/cache/axkit_fop_images
If you have disabled caching with AxNoCache, then this module will not keep track of external-graphics, and it will reset FOP's image cache before each run. You can force this behavior by specifying:
AxFOPImageCache Off
The ability to reset the image cache is available starting with FOP version 0.20.5. If you have an earlier version, you can instruct this module to leave the cache alone so as to avoid error messages in your log:
AxFOPImageCache On
This module will also leave the cache alone if you have turned off AxDependencyChecks. With an earlier version of FOP or when you instruct this module to leave the cache alone, you should restart JavaServer whenever you change an external-graphic file or whenever you think it is running out of memory from caching too many images. For example:
/etc/init.d/javaserver restart invoke-rc.d javaserver restart # on Debian
A temporary directory with a prefix of ``axkit-fop-'' is created on each request (using File::Temp) to contain the input and output files for FOP. This directory is readable/writable only by the web server process and it is automatically deleted in the mod_perl cleanup phase at the end of each request.
If you are using XML::ApacheFOP and JavaServer, then the JavaServer process needs read/write permission on this temporary directory. One way to allow this permission is to run your JavaServer process under the same user as your web server.
An alternative method, if your JavaServer is running as a different user from your web server, is to run your JavaServer under a group in which the web server belongs, and create a special temporary directory owned by this group with the group sticky bit set so that subdirectories will also be owned by the group. Inform this module of that directory with this directive:
PerlSetVar AxFOPJavaServerDirectory /my/special/directory
This module will turn on the group read/write permissions on temporary subdirectories created under this special directory.
Here is an example setup using Debian GNU/Linux commands (if someone can generalize this example let me know). Assume your JavaServer process is running under the user ``javaserv'' and the group ``javaserv'', and your web server is running under the user ``www-data'' and the group ``www-data''.
Add your web server user to the JavaServer group:
adduser www-data javaserv
Create a temporary directory with the group sticky bit set:
install -m 2770 -o javaserv -g javaserv -d /var/cache/javaserver
Update your Apache configuration with this directive:
PerlSetVar AxFOPJavaServerDirectory /var/cache/javaserver
AxKit, XML::ApacheFOP, Apache::AxKit::CacheCleaner
Ken Neighbors <ken@nsds.com>
Based on the Apache::AxKit::Language::PassiveTex module, but severely rewritten.
Copyright (c) 2005-2007 Ken Neighbors. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Apache::AxKit::Language::FOP - generate PDF using Apache FOP |