Gather content of a page in named zones while rendering it
The primary purpose of ZonePlugin is to streamline the anatomy of a HTML page
in a way to allow today's browsers to process it more efficiently. Page loading
time has been
reported to
decrease significantly when all JavaScript files are removed from the HEAD
element and appended to the end of the BODY element of a page. That's because
the browser will stop processing a page as soon as a JavaScript file is found
in the linear order of the page. The browser will only proceed after this file
has been downloaded and excecuted. Notably other content like CSS files and
image material will
not be downloaded in parallel as long as the JavaScript
interpreter hasn't finished.
Currently, Foswiki uses ADDTOHEAD to place additional CSS and JS files into the
HEAD element. It does
not reorder those files in any way other than specified
by the explicit
requires
argument to the macro. Further more, it is only able
to add stuff to one specific location of a HTML page, the HEAD element.
By using ADDTOZONE CSS and JS material can be added to the resulting page
incrementally while the core engine parses templates and wiki applications.
ADDTOZONE's first parameter is the name of the zone to add stuff to. There are
two special zones:
script
and
head
. All CSS should be added to the
head
zone while all JS goes into the
script
zone.
The actual location of a zone is specified with an explicit RENDERZONE macro.
This macro expands to the content of all material that has been posted to the
named zone. Note, that this happens at the very end of the rendering pipeline
of Foswiki. That means RENDERZONE is not processed as a normal macro obeying
the evaluation order of the TML parser. Instead, all calls to ADDTOZONE are
processed by the TML parser first after which all zones are expanded.
If RENDERZONE{head} and RENDERZONE{script} aren't found in the final page
explicitly, they are expanded at the appropriate position, that is at
</head>
.
The features of this plugin have been
proposed as a core feature for
Foswiki to replace the standard ADDTOHEAD with the more generic ADDTOZONE tag.
This plugin allows authors of extensions and wiki applications to make use of
this advanced feature in a backwards-compatible way. As soon as the ADDTOZONE
macro has been released as part of newer Foswiki versions, this plugin won't be
of use anymore.
WARNING: Using this plugin can potentially break your installation.
If you experience occasional JavaScript errors, enable
{MergeHeadAndScriptZones}
in
configure. This mode will render the HTML page
in a non-optimized way similar to how the standard
ADDTOHEAD
mechanism does.
In any case is it recommended to use
ADDTOHEAD
or
ADDTOZONE
to properly add
this code to the page. It is
not recommended to add JavaScript code otherwise.
If you rely on having JavaScript added to the
page
without using
ADDTOHEAD
or
ADDTOZONE
then you have to enable
{MergeHeadAndScriptZones}
mode most probably. In this case the HTML page cannot
be optimized.
Syntax
ADDTOZONE
%ADDTOZONE{
"zone"
...
}%
Zones are specific places in the output HTML that are marked by calls to the
RENDERZONE macro. Zones are used to collect various content together, such as Javascript and CSS, that must be included in the output HTML in a specific order, and in a specific place.
You may create as many zones in addition to the standard
head
and script
zones as you like. Interesting use cases in wiki applications:
- Create a
sidebar
zone to add widgets,
- Create a
toolbar
zone to add buttons icons
ADDTOZONE adds content identified with the
id
parameter to
zone
, which will later be expanded with
RENDERZONE.
id
identifiers are unique within the zone that they are added to. An
ADDTOZONE call may ensure that its content appears
after the content of some other
ADDTOZONE calls by specifying their
ids
in the
requires
parameter.
requires
may only list
ids
within the specified
zone
, except for the special case of
head
and
script
zones when
{MergeHeadAndScriptZones} is set (
read more).
Parameters:
-
"zone"
optional, comma-separated list of the names of zones that the content should be added to. Defaults to head
.
-
id
optional, identifier
for the text being added with the ADDTOZONE
call, to be used in the requires
parameter of other ADDTOZONE
calls.
- Multiple
ADDTOZONE
calls with the same id
parameter will simply overwrite the earlier ADDTOZONE
call.
-
requires="..."
optional, comma separated string of ids
of text within this zone
that this content should follow when the zone is rendered.
-
text="..."
optional, text to be added to the named zone, mutually exclusive with topic
.
-
topic="..."
optional, full qualified web.topic
name that contains the text to be added, mutually exclusive with text
.
-
section="..."
optional, section of the topic
to be added, defaults to the default section between STARTINCLUDE and STOPINCLUDE.
Note: Foswiki uses the
requires
parameter to resolve the
ordering of dependencies within a zone. It does
not work across zones. If you have an id in
requires
that cannot be resolved during sorting, then
RENDERZONE
will generate an HTML comment to mark the problem.
How to use the head
and script
zones
Web browsers generally process the HTML on a page from top to bottom. When a
<script>
tag is encountered with a URL to some Javascript file,
processing of the page will stop while the file is fetched and executed before
continuing. When a page makes heavy use of Javascript you can get a "blank
screen" effect in the browser while each script is downloaded. To avoid this
effect,
<script>
tags can be moved to the end of the HTML page, so that
the user may view the page content while scripts are being loaded.
Foswiki makes this move possible by providing the
head
and
script
zones.
These are
automatic zones - they do not require a corresponding
RENDERZONE
.
Rendering the script
zone at the end of
the HTML body requires skin template customisation with
%RENDERZONE{"script"}%
Notionally the
head
and
script
zones correspond to a point just before the
HTML
</HEAD>
tag. Normally you should add CSS (and other HTML
<HEAD>
content, such as
<META>
) to the
head
zone, and
Javascript
<script>
markup to the
script
zone. The setting
{MergeHeadAndScriptZones}
in Configure controls what happens when
RENDERZONE is called.
Normally, dependencies between the individual
ADDTOZONE
statements are resolved
within each zone. However, if
{MergeHeadAndScriptZones} is
enabled, then
head
content which
requires
an
id
that only exists in
script
(and vice-versa) will be re-ordered to satisfy any dependency.
{MergeHeadAndScriptZones}
is provided to
maintain compatibility with legacy extensions that use
ADDTOHEAD to add <script>
markup and require content
that is now in the script
zone. {MergeHeadAndScriptZones}
will be removed
from a future version of Foswiki.
Workign with {MergeHeadAndScriptZones}
disabled (default)
In this mode, the
head
and
script
zones are treated separately.
Working with {MergeHeadAndScriptZones}
enabled
In this mode, the
head
and
script
zones are separate when adding to them,
but may be treated as merged when you call
RENDERZONE if
there are any dependencies specified that only exist in the opposite zone. This
allows an
ADDTOZONE{"head"...}
to to successfully require an
id
that has
been added to
script
.
Only add content to the
script
zone
that is also legal in the <HEAD>
.
Example: Adding to a zone with missing dependencies
You must ensure that no
head
content (and no inline Javascript) depends on
script
content, or vice-versa. Any such dependency will be
ignored. However, the HTML comment decoration which normally appears after each id's content in the rendered HTML will contain a small informative text to aid debugging
Example
%ADDTOZONE{
"head"
text="
<script type='text/javascript'>
alert('test');
</script>"
requires="some-id-that-exists-in-script"
id="MY::TEST"
}%
Result
<script type='text/javascript'>
alert('test');
</script>
<!-- MY::TEST: requires= missing ids: some-id-that-exists-in-script -->
On the other hand, as explained earlier - when
{MergeHeadAndScriptZones} is enabled - Foswiki is able resolve such dependencies successfully.
Note that if you
do have an explicit call to
%RENDERZONE{"head"}%
in
your templates then the content expanded at that point will be the same content
as would be inserted before the
</HEAD>
.
Example: Adding Javascript to a page
Example: Adding CSS to a page
%ADDTOZONE{"head"
id="MyCSS"
text="
<style type='text/css' media='all'>
@import url('%PUBURLPATH%/%SYSTEMWEB%/MyCSS/foo.css');
</style>"
}%
See also
RENDERZONE,
Using ADDTOZONE
RENDERZONE
%RENDERZONE{"zone" ...}%
See
ADDTOZONE for an explanation of
zones.
Parameters:
Supports the
standard format tokens in all parameters.
Notes:
-
header
and footer
are not output if there is no content in the zone (nothing has been ADDTOZONEd
). However they are output if the output is the empty string (at least one ADDTOZONE
has been processed).
- Zones are cleared after being rendered; they are only ever rendered once.
-
head
and script
are automatic zones. They don't require a corresponding RENDERZONE
anywhere in the templates - they are automatically inserted before the </head>
tag in the output HTML page.
- Normally, dependencies between individual
ADDTOZONE
statements are resolved within each zone. However, if {MergeHeadAndScriptZones}
is enabled in configure, then head
content which requires an id
that only exists in script
(and vice-versa) will be re-ordered to satisfy any dependency. {MergeHeadAndScriptZones}
will be removed from a future version of Foswiki.
See also
ADDTOZONE for more information on zones.
Perl API
This plugin patches the
Foswiki::Func
API for backwards compatibility.
- New
Foswiki::Func::addToZone($zone, $id, $text, $requires)
- Replaces
Foswiki::Func::addToHEAD() to use the =head
namespace of this plugin instead of Foswiki::_HTMLHEAD
The latter will try to detect
text/javascrtipt
and
move content into the
script
zone. Otherwise, it will be added to the
head
.
Any use of
ADDTOHEAD
or
Foswiki::Func::addToHEAD()
will emit a warning to
the log files (must be switched on with the
Warnings
flag in
configure). This can be used to hunt down
suboptimal use of these APIs.
Installation Instructions
You do not need to install anything in the browser to use this extension. The following instructions are for the administrator who installs the extension on the server.
Open configure, and open the "Extensions" section. "Extensions Operation and Maintenance" Tab -> "Install, Update or Remove extensions" Tab. Click the "Search for Extensions" button.
Enter part of the extension name or description and press search. Select the desired extension(s) and click install. If an extension is already installed, it will
not show up in the
search results.
You can also install from the shell by running the extension installer as the web server user: (Be sure to run as the webserver user, not as root!)
cd /path/to/foswiki
perl tools/extension_installer <NameOfExtension> install
If you have any problems, or if the extension isn't available in
configure
, then you can still install manually from the command-line. See
https://foswiki.org/Support/ManuallyInstallingExtensions for more help.
Change History: |
|
29 Sep 2010 |
Foswikitask:Item9763 revert recent changes and forward port script zone to make it work on old foswiki engines |
06 Sep 2010 |
Foswikitask:Item9588: Update ZonePlugin to match Foswiki 1.1. Removed {OptimizePageLayout} , replaced with {MergeHeadAndScriptZones} . Removed body zone, replaced with script zone. Refer to Foswikitask:Item9588 for more info |
28 Mar 2010 |
fix problem where Foswiki 1.0.x installations would fail with "Undefined subroutine &Foswiki::Func::addToZone" |
26 Mar 2010 |
suppressing plugin initialisation on Foswiki engines >= 1.1; renamed BackwardsCompatible switch to OptimizePageLayout (defaults to off) |
19 Feb 2010 |
added {BackwardsCompatible} switch |
15 Feb 2010 |
be more careful applying the monkey-patch to the Func API; parsing RENDERZONE properly but finally inserting the zone at the end of the rendering pipeline |
12 Feb 2010 |
initial release |
Dependencies: |
None |
Home page: |
Foswiki:Extensions/ZonePlugin |