Apache::AxKit::Language::XSP man page on OpenServer

Man page or keyword search:  
man Server   5388 pages
apropos Keyword Search (all sections)
Output format
OpenServer logo
[printable version]

Apache::AxKit::LanguagUserSContributed Perl DocApache::AxKit::Language::XSP(3)

NAME
       Apache::AxKit::Language::XSP - eXtensible Server Pages

SYNOPSIS
	 <xsp:page
	   xmlns:xsp="http://apache.org/xsp/core/v1">

	   <xsp:structure>
	       <xsp:import>Time::Piece</xsp:import>
	   </xsp:structure>

	   <page>
	       <title>XSP Test</title>
	       <para>
	       Hello World!
	       </para>
	       <para>
	       Good
	       <xsp:logic>
	       if (localtime->hour >= 12) {
		   <xsp:content>Afternoon</xsp:content>
	       }
	       else {
		   <xsp:content>Morning</xsp:content>
	       }
	       </xsp:logic>
	       </para>
	   </page>

	 </xsp:page>

DESCRIPTION
       XSP implements a tag-based dynamic language that allows you to develop
       your own tags, examples include sendmail and sql taglibs. It is AxKit's
       way of providing an environment for dynamic pages. XSP is originally
       part of the Apache Cocoon project, and so you will see some Apache
       namespaces used in XSP.

       Also, use only one XSP processor in a pipeline.	XSP is powerful enough
       that you should only need one stage, and this implementation allows
       only one stage.	If you have two XSP processors, perhaps in a pipeline
       that looks like:

	   ... => XSP => XSLT => XSLT => XSP => ...

       it is pretty likely that the functionality of the intermediate XSLT
       stages can be factored in to either upstream or downstream XSLT:

	   ... => XSLT => XSP => XSLT => ...

       This design is likely to lead to a clearer and more maintainable imple-
       mentation, if only because generating code, especially embedded Perl
       code, in one XSP processor and consuming it in another is often confus-
       ing and even more often a symptom of misdesign.

       Likewise, you may want to lean towards using Perl taglib modules
       instead of upstream XSLT "LogicSheets".	Upstream XSLT LogicSheets work
       fine, mind you, but using Perl taglib modules results in a simpler
       pipeline, simpler configuration (just load the taglib modules in
       httpd.conf, no need to have the correct LogicSheet XSLT page included
       whereever you need that taglib), a more flexible coding environment,
       the ability to pretest your taglibs before installing them on a server,
       and better isolation of interface (the taglib API) and implementation
       (the Perl module behind it).  LogicSheets work, and can be useful, but
       are often the long way home.  That said, people used to the Cocoon
       environment may prefer them.

       Result Code

       You can specify the result code of the request in two ways. Both
       actions go inside a <xsp:logic> tag.

       If you want to completely abort the current request, throw an excep-
       tion:

	   throw Apache::AxKit::Exception::Retval(return_code => FORBIDDEN);

       If you want to send your page but have a custom result code, return it:

	   return FORBIDDEN;

       In that case, only the part of the document that was processed so far
       gets sent/processed further.

       Debugging

       If you have PerlTidy installed (get it from <http://perltidy.source-
       forge.net>), the compiled XSP scripts can be formatted nicely to spot
       errors easier. Enable AxDebugTidy for this, but be warned that refor-
       matting is quite slow, it can take 20 seconds or more on each XSP run
       for large scripts.

       If you enable AxTraceIntermediate, your script will be dumped alongside
       the other intermediate files, with an extension of ".XSP". These are
       unnumbered, thus only get one dump per request. If you have more than
       one XSP run in a single request, the last one will overwrite the dumps
       of earlier runs.

Tag Reference
       "<xsp:page>"

       This is the top level element, although it does not have to be. AxKit's
       XSP implementation can process XSP pages even if the top level element
       is not there, provided you use one of the standard AxKit ways to turn
       on XSP processing for that page. See AxKit.

       The attribute "language="Perl"" can be present, to mandate the lan-
       guage.  This is useful if you expect people might mistakenly try and
       use this page on a Cocoon system. The default value of this attribute
       is "Perl".

       XSP normally swallows all whitespace in your output. If you don't like
       this feature, or it creates invalid output, then you can add the
       attribute: "indent-result="yes""

       By default all non-XSP and non-taglib attributes are interpolated in a
       similar way to XSLT attributes - by checking for "{ code }" in the
       attributes. The "code" can be any perl code, and is treated exactly the
       same as having an "<xsp:expr>code</xsp:expr>" in the attribute value.
       In order to turn this off, simply specify the attribute
       "attribute-value-interpolate="no"". The default is "yes" which enables
       the interpolation.

       "<xsp:structure>"

	 parent: <xsp:page>

       This element appears at the root level of your page before any non-XSP
       tags. It defines page-global "things" in the "<xsp:logic"> and
       "<xsp:import"> tags.

       "<xsp:import>"

	 parent: <xsp:structure>

       Use this tag for including modules into your code, for example:

	 <xsp:structure>
	   <xsp:import>DBI</xsp:import>
	 </xsp:structure>

       "<xsp:logic>"

	 parent: <xsp:structure>, any

       The "<xsp:logic"> tag introduces some Perl code into your page.

       As a child of "<xsp:structure">, this element allows you to define page
       global variables, or functions that get used in the page. Placing func-
       tions in here allows you to get around the Apache::Registry closures
       problem (see the mod_perl guide at http://perl.apache.org/guide for
       details).

       Elsewhere the perl code contained within the tags is executed on every
       view of the XSP page.

       Warning: Be careful - the Perl code contained within this tag is still
       subject to XML's validity constraints. Most notably to Perl code is
       that the & and < characters must be escaped into & and < respec-
       tively.	You can get around this to some extent by using CDATA sec-
       tions. This is especially relevant if you happen to think something
       like this will work:

	 <xsp:logic>
	   if ($some_condition) {
	     print "<para>Condition True!</para>";
	   }
	   else {
	     print "<para>Condition False!</para>";
	   }
	 </xsp:logic>

       The correct way to write that is simply:

	 <xsp:logic>
	   if ($some_condition) {
	     <para>Condition True!</para>
	   }
	   else {
	     <para>Condition False!</para>
	   }
	 </xsp:logic>

       The reason is that XSP intrinsically knows about XML!

       "<xsp:content>"

	 parent: <xsp:logic>

       This tag allows you to temporarily "break out" of logic sections to
       generate some XML text to go in the output. Using something similar to
       the above example, but without the surrounding "<para"> tag, we have:

	 <xsp:logic>
	   if ($some_condition) {
	     <xsp:content>Condition True!</xsp:content>
	   }
	   else {
	     <xsp:content>Condition False!</xsp:content>
	   }
	 </xsp:logic>

       "<xsp:element>"

       This tag generates an element of name equal to the value in the
       attribute "name". Alternatively you can use a child element
       "<xsp:name"> to specify the name of the element. Text contents of the
       "<xsp:element"> are created as text node children of the new element.

       "<xsp:attribute>"

       Generates an attribute. The name of the attribute can either be speci-
       fied in the "name="..."" attribute, or via a child element
       "<xsp:name">. The value of the attribute is the text contents of the
       tag.

       "<xsp:comment>"

       Normally XML comments are stripped from the output. So to add one back
       in you can use the "<xsp:comment"> tag. The contents of the tag are the
       value of the comment.

       "<xsp:text>"

       Create a plain text node. The contents of the tag are the text node to
       be generated. This is useful when you wish to just generate a text node
       while in an "<xsp:logic"> section.

       "<xsp:expr>"

       This is probably the most useful, and most important (and also the most
       complex) tag. An expression is some perl code that executes, and the
       results of which are added to the output. Exactly how the results are
       added to the output depends very much on context.

       The default method for output for an expression is as a text node. So
       for example:

	 <p>
	 It is now: <xsp:expr>localtime</xsp:expr>
	 </p>

       Will generate a text node containing the time.

       If the expression is contained within an XSP namespaces, that is either
       a tag in the xsp:* namespace, or a tag implementing a tag library, then
       an expression generally does not create a text node, but instead is
       simply wrapped in a Perl "do {}" block, and added to the perl script.
       However, there are anti-cases to this. For example if the expression is
       within a "<xsp:content"> tag, then a text node is created.

       Needless to say, in every case, "<xsp:expr"> should just "do the right
       thing". If it doesn't, then something (either a taglib or XSP.pm
       itself) is broken and you should report a bug.

Writing Taglibs
       Writing your own taglibs can be tricky, because you're using an event
       based API to write out Perl code. You may want to take a look at the
       Apache::AxKit::Language::XSP::TaglibHelper module, which comes with
       AxKit and allows you to easily publish a taglib without writing XML
       event code. Recently, another taglib helper has been developed,
       Apache::AxKit::Language::XSP::SimpleTaglib. The latter manages all the
       details described under 'Design Patterns' for you, so you don't really
       need to bother with them anymore.

       A warning about character sets: All string values are passed in and
       expected back as UTF-8 encoded strings. So you cannot use national
       characters in a different encoding, like the widespread ISO-8859-1.
       This applies to Taglib source code only. The XSP XML-source is of
       course interpreted according to the XML rules. Your taglib module may
       want to 'use utf8;' as well, see perlunicode and utf8 for more informa-
       tion.

Design Patterns
       These patterns represent the things you may want to achieve when
       authoring a tag library "from scratch".

       1. Your tag is a wrapper around other things.

       Example:

	 <mail:sendmail>...</mail:sendmail>

       Solution:

       Start a new block, so that you can store lexical variables, and declare
       any variables relevant to your tag:

       in parse_start:

	 if ($tag eq 'sendmail') {
	   return '{ my ($to, $from, $sender);';
	 }

       Often it will also be relevant to execute that code when you see the
       end tag:

       in parse_end:

	 if ($tag eq 'sendmail') {
	   return 'Mail::Sendmail::sendmail(
		   to => $to,
		   from => $from,
		   sender => $sender
		   ); }';
	 }

       Note there the closing of that original opening block.

       2. Your tag indicates a parameter for a surrounding taglib.

       Example:

	 <mail:to>...</mail:to>

       Solution:

       Having declared the variable as above, you simply set it to the empty
       string, with no semi-colon:

       in parse_start:

	 if ($tag eq 'to') {
	   return '$to = ""';
	 }

       Then in parse_char:

       sub parse_char {
	 my ($e, $text) = @_;
	 $text =~ s/^\s*//;
	 $text =~ s/\s*$//;

	 return '' unless $text;

	 $text = Apache::AxKit::Language::XSP::makeSingleQuoted($text);
	 return ". $text";
       }

       Note there's no semi-colon at the end of all this, so we add that:

       in parse_end:

	 if ($tag eq 'to') {
	   return ';';
	 }

       All of this black magic allows other taglibs to set the thing in that
       variable using expressions.

       3. You want your tag to return a scalar (string) that does the right
       thing depending on context.

       For example, generates a Text node in one place or generates a scalar
       in another context.

       Solution:

       use $e->start_expr(), $e->append_to_script(), $e->end_expr().

       Example:

	 <example:get-datetime format="%Y-%m-%d %H:%M:%S"/>

       in parse_start:

	 if ($tag eq 'get-datetime') {
	   $e->start_expr($tag); # creates a new { ... } block
	   my $local_format = lc($attribs{format}) || '%a, %d %b %Y %H:%M:%S %z';
	   return 'my ($format); $format = q|' . $local_format . '|;';
	 }

       in parse_end:

	 if ($tag eq 'get-datetime') {
	   $e->append_to_script('use Time::Piece; localtime->strftime($format);');
	   $e->end_expr();
	   return '';
	 }

       Explanation:

       This is more complex than the first 2 examples, so it warrants some
       explanation. I'll go through it step by step.

	 $e->start_expr($tag)

       This tells XSP that this really generates a <xsp:expr> tag. Now we
       don't really generate that tag, we just execute the handler for it. So
       what happens is the <xsp:expr> handler gets called, and it looks to see
       what the current calling context is. If its supposed to generate a text
       node, it generates some code to do that. If its supposed to generate a
       scalar, it does that too. Ultimately both generate a do {} block, so
       we'll summarise that by saying the code now becomes:

	 do {

       (the end of the block is generated by end_expr()).

       Now the next step (ignoring the simple gathering of the format vari-
       able), is a return, which appends more code onto the generated perl
       script, so we get:

	 do {
	   my ($format); $format = q|%a, %d %b %Y %H:%M:%S %z|;

       Now we immediately receive an end_expr, because this is an empty ele-
       ment (we'll see why we formatted it this way in #5 below). The first
       thing we get is:

	 $e->append_to_script('use Time::Piece; localtime->strftime($format);');

       This does exactly what it says, and the script becomes:

	 do {
	   my ($format); $format = q|%a, %d %b %Y %H:%M:%S %z|;
	   use Time::Piece; localtime->strftime($format);

       Finally, we call:

	 $e->end_expr();

       which closes the do {} block, leaving us with:

	 do {
	   my ($format); $format = q|%a, %d %b %Y %H:%M:%S %z|;
	   use Time::Piece; localtime->strftime($format);
	 }

       Now if you execute that in Perl, you'll see the do {} returns the last
       statement executed, which is the "localtime-"strftime()> bit there,
       thus doing exactly what we wanted.

       4. Your tag can take as an option either an attribute, or a child tag.

       Example:

	 <util:include-uri uri="http://server/foo"/>

       or

	 <util:include-uri>
	   <util:uri><xsp:expr>$some_uri</xsp:expr></util:uri>
	 </util:include-uri>

       Solution:

       There are several parts to this. The simplest is to ensure that white-
       space is ignored. We have that dealt with in the example parse_char
       above. Next we need to handle that variable. Do this by starting a new
       block with the tag, and setting up the variable:

       in parse_start:

	 if ($tag eq 'include-uri') {
	   my $code = '{ my ($uri);';
	   if ($attribs{uri}) {
	     $code .= '$uri = q|' . $attribs{uri} . '|;';
	   }
	   return $code;
	 }

       Now if we don't have the attribute, we can expect it to come in the
       "<util:uri"> tag:

       in parse_start:

	 if ($tag eq 'uri') {
	   return '$uri = ""'; # note the empty string!
	 }

       Now you can see that we're not explicitly setting $uri, that's because
       the parse_char we wrote above handles it by returning '. q|$text|'. And
       if we have a "<xsp:expr"> in there, that's handled automagically too.

       Now we just need to wrap things up in the end handlers:

       in parse_end:

	 if ($tag eq 'uri') {
	   return ';';
	 }
	 if ($tag eq 'include-uri') {
	   return 'Taglib::include_uri($uri); # execute the code
		   } # close the block
	   ';
	 }

       5. You want to return a scalar that does the right thing in context,
       but also can take a parameter as an attribute or a child tag.

       Example:

	 <esql:get-column column="user_id"/>

       vs

	 <esql:get-column>
	   <esql:column><xsp:expr>$some_column</xsp:expr></esql:column>
	 </esql:get-column>

       Solution:

       This is a combination of patterns 3 and 4. What we need to do is change
       #3 to simply allow our variable to be added as in #4 above:

       in parse_start:

	 if ($tag eq 'get-column') {
	   $e->start_expr($tag);
	   my $code = 'my ($col);'
	   if ($attribs{col}) {
	     $code .= '$col = q|' . $attribs{col} . '|;';
	   }
	   return $code;
	 }
	 if ($tag eq 'column') {
	   return '$col = ""';
	 }

       in parse_end:

	 if ($tag eq 'column') {
	   return ';';
	 }
	 if ($tag eq 'get-column') {
	   $e->append_to_script('Full::Package::get_column($col)');
	   $e->end_expr();
	   return '';
	 }

       6. You have a conditional tag

       Example:

	 <esql:no-results>
	   No results!
	 </esql:no-results>

       Solution:

       The problem here is that taglibs normally recieve character/text events
       so that they can manage variables. With a conditional tag, you want
       character events to be handled by the core XSP and generate text
       events.	So we have a switch for that:

	 if ($tag eq 'no-results') {
	   $e->manage_text(0);
	   return 'if (AxKit::XSP::ESQL::get_count() == 0) {';
	 }

       Turning off manage_text with a zero simply ensures that immediate chil-
       dren text nodes of this tag don't fire text events to the tag library,
       but instead get handled by XSP core, thus creating text nodes (and
       doing the right thing, generally).

       <xsp:expr> (and start_expr, end_expr) Notes

       Do not consider adding in the 'do {' ... '}' bits yourself. Always
       leave this to the start_expr, and end_expr functions. This is because
       the implementation could change, and you really don't know better than
       the underlying XSP implementation. You have been warned.

perl v5.8.8			  2005-07-14   Apache::AxKit::Language::XSP(3)
[top]
                             _         _         _ 
                            | |       | |       | |     
                            | |       | |       | |     
                         __ | | __ __ | | __ __ | | __  
                         \ \| |/ / \ \| |/ / \ \| |/ /  
                          \ \ / /   \ \ / /   \ \ / /   
                           \   /     \   /     \   /    
                            \_/       \_/       \_/ 
More information is available in HTML format for server OpenServer

List of man pages available for OpenServer

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net