Web-XDO
view release on metacpan or search on metacpan
lib/Web/XDO.pm view on Meta::CPAN
=cut
#------------------------------------------------------------------------------
# new
#
=head3 Web::XDO::Page->new()
Web::XDO::Page->new() takes four parameters plus one optional parameter:
=over 1
=item *
$class: The name of the page class. For this release it's always
"Web::XDO::Page".
=item *
$url_root: The base page against which an absoulte URL path should be
calculated from $url_rel_path. Yes, this variable should actually be called
$url_base. That will be fixed in subsequent releases.
=item *
$url_rel_path: The relative URL path from $url_root.
=item *
$xdo: The Web::XDO object that is handling the entire process.
=item *
caller=>$page
If a page is being included in another page then the included page needs to
know its "caller" page. That information is set with the caller option. So,
for example, the L<E<lt>includedE<gt>|/Web::XDO::Token::Tag::Include> tag
creates the included page object with a call like this:
$included = $xdo->page_class->new($url_base, $atts->{'src'}, $xdo, 'caller'=>$caller);
If a caller is sent then that object is stored in the included page in the
$page->{'caller'} property.
=back
=cut
sub new {
my ($class, $url_root, $url_rel_path, $xdo, %opts) = @_;
my ($tokens, $token_idx, $page);
# TESTING
# println $class, '->new()'; ##i
# create page object
$page = $class->SUPER::new();
# don't recognize cdata tags
$page->xml_mode(1);
# must either designate a caller or explicitly set as top page
if (my $caller = $opts{'caller'}) {
if (UNIVERSAL::isa($caller, 'Web::XDO::Page')) {
$page->{'caller'} = $caller;
}
else {
croak q|caller is not a page object|;
}
}
else {
$page->{'props'} = {};
}
# hold on to xdo object
$page->{'xdo'} = $xdo;
# build path to file
$page->set_paths($url_root, $url_rel_path) or return 0;
# initialize token array
$tokens = $page->{'tokens'} = [];
# parse
$page->parse_file("$page->{'local_path'}");
# initialize $token_idx to 0
$token_idx = 0;
# set page properties
# NOTE: This rather odd construction for iterating through the tokens is
# based on the fact that set_page_prop tokens are removed from the token
# array, and they might remove other tokens after them. Therefore the
# length of the array can change during the loop.
while ($token_idx < @$tokens) {
my $token = $tokens->[$token_idx];
if (UNIVERSAL::isa($token, 'Web::XDO::Token::Tag')) {
if (UNIVERSAL::can($token, 'set_page_prop')) {
$token->set_page_prop($page, $token_idx);
}
}
# increment to next token
$token_idx++;
}
# return
return $page;
}
#
# new
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# top
#
lib/Web/XDO.pm view on Meta::CPAN
$tokens = $page->{'tokens'};
# check if this page has already been output
if ($nested->{$local_path}) {
return 0;
}
# note as output
$nested->{$local_path} = 1;
# loop through tokens
while ($token_idx <= $#$tokens) {
my $token = $tokens->[$token_idx];
# if object, call output method
# else just print
if (ref $token) {
$token->output($page, $token_idx);
}
else {
print $token;
}
# increment
$token_idx++;
}
# note not longer output
delete $nested->{$local_path};
}
#
# output
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# start
#
=head3 $page->start()
Web::XDO::Page superclasses
L<HTML::Parser|http://search.cpan.org/dist/HTML-Parser/Parser.pm>.
start() handles HTML::Parser's event when a start tag is parsed.
start() creates a new tag object using the class returned by
L<$xdo-E<gt>tag_class()|/$xdo-E<gt>tag_class()>.
=cut
sub start {
my ($page, $tag_name, $atts, $att_order, $raw) = @_;
my ($self_ender, $def, $token, $xdo);
$xdo = $page->{'xdo'};
# TESTING
# println $tag_name, '->start'; ##i
# normalize tag name
# NOTE: We need to normalize here because the parser is in xml_mode. That
# mode is on so that content of cdata tags (specificall <title>) are
# parsed. It has the side-effect that tag names are sent as they appear
# in the document being parsed. If anybody knows a more global way to send
# lowercased tag names I'll be glad to hear about it. - Miko
$tag_name = lc($tag_name);
# if the tag has a trailing slash then it's a self-ender
if ($raw =~ m|/\s*\>$|s)
{ $self_ender = 1 }
# NOTE: Funky code ahead. The following few lines take into account several
# different possibilities of how the tag definition might be structured.
# It might be:
# - a hashref with a class name
# - a hashref without a class name
# - just a class name
#
# The following code ensures that the definition is a hashref with a
# class name.
# get tag definition
$def = $page->{'xdo'}->{'tags'}->{$tag_name} || $xdo->default_tag_class();
# ensure tag definition is a hashref
ref($def) or $def = {class=>$def};
# ensure definition has a tag class
$def->{'class'} ||= $xdo->default_tag_class();
# create token object
$token = $def->{'class'}->new();
$token->{'type'} = 'tag';
$token->{'name'} = $tag_name;
$token->{'atts'} = $atts;
$token->{'raw'} = $raw;
# note if self-ender
if ($self_ender)
{ $token->{'self_ender'} = 1 }
# hold on to token
push @{$page->{'tokens'}}, $token;
}
#
# start
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# end
#
=head3 $page->end()
end() handles HTML::Parser's event when an end tag is parsed.
end() creates a new end tag object with the
Web::XDO::Token::EndTag class.
=cut
sub end {
my ($page, $tag_name, $raw) = @_;
my ($token);
# normalize tag name
# NOTE: We need to normalize here because the parser is in xml_mode. That
# mode is on so that content of cdata tags (specificall <title>) are
# parsed. It has the side-effect that tag names are sent as they appear
# in the document being parsed. If anybody knows a more global way to send
# lowercased tag names I'll be glad to hear about it. - Miko
$tag_name = lc($tag_name);
# create token object
$token = Web::XDO::Token::EndTag->new();
$token->{'type'} = 'end_tag';
$token->{'name'} = $tag_name;
$token->{'raw'} = $raw;
# hold on to token
push @{$page->{'tokens'}}, $token;
}
#
# end
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# text
#
=head3 $page->text()
text() handles HTML::Parser's event when an end tag is parsed.
text() creates a new text object with the
Web::XDO::Token::Text class.
=cut
sub text {
my ($page, $raw) = @_;
my ($token);
# create text object
$token = Web::XDO::Token::Text->new();
$token->{'type'} = 'text';
$token->{'raw'} = $raw;
# hold on to token
push @{$page->{'tokens'}}, $token;
}
#
# text
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# is_directory_index
#
=head3 $page->is_directory_index()
is_directory_index() returns true if the XDO page is a
L<directory index|http://httpd.apache.org/docs/2.2/mod/mod_dir.html#directoryindex>
file. Generally you should
L<configure your server|http://idocs.com/xdo/guides/version-0-10/install/configure-web-server.xdo>
so that the directory index file is named index.xdo.
( run in 2.838 seconds using v1.01-cache-2.11-cpan-524268b4103 )