⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 template.pm

📁 1. 记录每个帖子的访问人情况
💻 PM
📖 第 1 页 / 共 5 页
字号:
        push(@pstacks, $template->{parse_stack});      }    }  }}      # initialize the template buffersub _init_template {  my $self = shift;  my $options = $self->{options};  print STDERR "### HTML::Template Memory Debug ### START INIT_TEMPLATE ", $self->{proc_mem}->size(), "\n"    if $options->{memory_debug};  if (exists($options->{filename})) {        my $filepath = $options->{filepath};    if (not defined $filepath) {      $filepath = $self->_find_file($options->{filename});      confess("HTML::Template->new() : Cannot open included file $options->{filename} : file not found.")        unless defined($filepath);      # we'll need this for future reference - to call stat() for example.      $options->{filepath} = $filepath;       }    confess("HTML::Template->new() : Cannot open included file $options->{filename} : $!")        unless defined(open(TEMPLATE, $filepath));    $self->{mtime} = $self->_mtime($filepath);    # read into scalar, note the mtime for the record    $self->{template} = "";    while (read(TEMPLATE, $self->{template}, 10240, length($self->{template}))) {}    close(TEMPLATE);  } elsif (exists($options->{scalarref})) {    # copy in the template text    $self->{template} = ${$options->{scalarref}};    delete($options->{scalarref});  } elsif (exists($options->{arrayref})) {    # if we have an array ref, join and store the template text    $self->{template} = join("", @{$options->{arrayref}});    delete($options->{arrayref});  } elsif (exists($options->{filehandle})) {    # just read everything in in one go    local $/ = undef;    $self->{template} = readline($options->{filehandle});    delete($options->{filehandle});  } else {    confess("HTML::Template : Need to call new with filename, filehandle, scalarref or arrayref parameter specified.");  }  print STDERR "### HTML::Template Memory Debug ### END INIT_TEMPLATE ", $self->{proc_mem}->size(), "\n"    if $options->{memory_debug};  # handle filters if necessary  $self->_call_filters(\$self->{template}) if @{$options->{filter}};  return $self;}# handle calling user defined filterssub _call_filters {  my $self = shift;  my $template_ref = shift;  my $options = $self->{options};  my ($format, $sub);  foreach my $filter (@{$options->{filter}}) {    croak("HTML::Template->new() : bad value set for filter parameter - must be a code ref or a hash ref.")      unless ref $filter;    # translate into CODE->HASH    $filter = { 'format' => 'scalar', 'sub' => $filter }      if (ref $filter eq 'CODE');    if (ref $filter eq 'HASH') {      $format = $filter->{'format'};      $sub = $filter->{'sub'};      # check types and values      croak("HTML::Template->new() : bad value set for filter parameter - hash must contain \"format\" key and \"sub\" key.")        unless defined $format and defined $sub;      croak("HTML::Template->new() : bad value set for filter parameter - \"format\" must be either 'array' or 'scalar'")        unless $format eq 'array' or $format eq 'scalar';      croak("HTML::Template->new() : bad value set for filter parameter - \"sub\" must be a code ref")        unless ref $sub and ref $sub eq 'CODE';      # catch errors      eval {        if ($format eq 'scalar') {          # call          $sub->($template_ref);        } else {	  # modulate	  my @array = map { $_."\n" } split("\n", $$template_ref);          # call          $sub->(\@array);	  # demodulate	  $$template_ref = join("", @array);        }      };      croak("HTML::Template->new() : fatal error occured during filter call: $@") if $@;    } else {      croak("HTML::Template->new() : bad value set for filter parameter - must be code ref or hash ref");    }  }  # all done  return $template_ref;}# _parse sifts through a template building up the param_map and# parse_stack structures.## The end result is a Template object that is fully ready for# output().sub _parse {  my $self = shift;  my $options = $self->{options};    $options->{debug} and print STDERR "### HTML::Template Debug ### In _parse:\n";    # setup the stacks and maps - they're accessed by typeglobs that  # reference the top of the stack.  They are masked so that a loop  # can transparently have its own versions.  use vars qw(@pstack %pmap @ifstack @ucstack %top_pmap);  local (*pstack, *ifstack, *pmap, *ucstack, *top_pmap);    # the pstack is the array of scalar refs (plain text from the  # template file), VARs, LOOPs, IFs and ELSEs that output() works on  # to produce output.  Looking at output() should make it clear what  # _parse is trying to accomplish.  my @pstacks = ([]);  *pstack = $pstacks[0];  $self->{parse_stack} = $pstacks[0];    # the pmap binds names to VARs, LOOPs and IFs.  It allows param() to  # access the right variable.  NOTE: output() does not look at the  # pmap at all!  my @pmaps = ({});  *pmap = $pmaps[0];  *top_pmap = $pmaps[0];  $self->{param_map} = $pmaps[0];  # the ifstack is a temporary stack containing pending ifs and elses  # waiting for a /if.  my @ifstacks = ([]);  *ifstack = $ifstacks[0];  # the ucstack is a temporary stack containing conditions that need  # to be bound to param_map entries when their block is finished.  # This happens when a conditional is encountered before any other  # reference to its NAME.  Since a conditional can reference VARs and  # LOOPs it isn't possible to make the link right away.  my @ucstacks = ([]);  *ucstack = $ucstacks[0];    # the loopstack is another temp stack for closing loops.  unlike  # those above it doesn't get scoped inside loops, therefore it  # doesn't need the typeglob magic.  my @loopstack = ();  # the fstack is a stack of filenames and counters that keeps track  # of which file we're in and where we are in it.  This allows  # accurate error messages even inside included files!  # fcounter, fmax and fname are aliases for the current file's info  use vars qw($fcounter $fname $fmax);  local (*fcounter, *fname, *fmax);  my @fstack = ([$options->{filename} || "main template",                  1,                  scalar @{[$self->{template} =~ m/(\n)/g]} + 1                ]);  (*fname, *fcounter, *fmax) = \ ( @{$fstack[0]} );  my $NOOP = HTML::Template::NOOP->new();  my $ESCAPE = HTML::Template::ESCAPE->new();  my $URLESCAPE = HTML::Template::URLESCAPE->new();  # all the tags that need NAMEs:  my %need_names = map { $_ => 1 }     qw(TMPL_VAR TMPL_LOOP TMPL_IF TMPL_UNLESS TMPL_INCLUDE);      # variables used below that don't need to be my'd in the loop  my ($name, $which, $escape);  # handle the old vanguard format  $options->{vanguard_compatibility_mode} and     $self->{template} =~ s/%([-\w\/\.+]+)%/<TMPL_VAR NAME=$1>/g;  # now split up template on '<', leaving them in  my @chunks = split(m/(?=<)/, $self->{template});  # all done with template  delete $self->{template};  # loop through chunks, filling up pstack  my $last_chunk =  $#chunks; CHUNK: for (my $chunk_number = 0;	    $chunk_number <= $last_chunk;	    $chunk_number++) {    next unless defined $chunks[$chunk_number];     my $chunk = $chunks[$chunk_number];        # a general regex to match any and all TMPL_* tags     if ($chunk =~ /^<                    (?:!--\s*)?                    (                      \/?[Tt][Mm][Pp][Ll]_                      (?:                         (?:[Vv][Aa][Rr])                         |                         (?:[Ll][Oo][Oo][Pp])                         |                         (?:[Ii][Ff])                         |                         (?:[Ee][Ll][Ss][Ee])                         |                         (?:[Uu][Nn][Ll][Ee][Ss][Ss])                         |                         (?:[Ii][Nn][Cc][Ll][Uu][Dd][Ee])                      )                    ) # $1 => $which - start of the tag                    \s*                     # ESCAPE attribute                    (?:                      [Ee][Ss][Cc][Aa][Pp][Ee]                      \s*=\s*                      (?:                         ( 0 | (?:"0") | (?:'0') ) # $2 => ESCAPE off                         |                         ( 1 | (?:"1") | (?:'1') |                            (?:[Hh][Tt][Mm][Ll]) |                            (?:"[Hh][Tt][Mm][Ll]") |                           (?:'[Hh][Tt][Mm][Ll]') |                           (?:[Uu][Rr][Ll]) |                            (?:"[Uu][Rr][Ll]") |                           (?:'[Uu][Rr][Ll]') |                         )                         # $3 => ESCAPE on                       )                    )* # allow multiple ESCAPEs                    \s*                                        # NAME attribute                    (?:                      (?:                        [Nn][Aa][Mm][Ee]                        \s*=\s*                      )?                      (?:                        "([^">]*)" # $4 => double-quoted NAME value "                        |                        '([^'>]*)' # $5 => single-quoted NAME value                        |                        ([^\s=>]*)  # $6 => unquoted NAME value                      )                    )?                                         \s*                    # ESCAPE attribute                    (?:                      [Ee][Ss][Cc][Aa][Pp][Ee]                      \s*=\s*                      (?:                         ( 0 | (?:"0") | (?:'0') ) # $7 => ESCAPE off                         |                         ( 1 | (?:"1") | (?:'1') |                            (?:[Hh][Tt][Mm][Ll]) |                            (?:"[Hh][Tt][Mm][Ll]") |                           (?:'[Hh][Tt][Mm][Ll]') |                           (?:[Uu][Rr][Ll]) |                            (?:"[Uu][Rr][Ll]") |                           (?:'[Uu][Rr][Ll]') |                         )                         # $8 => ESCAPE on                       )                    )* # allow multiple ESCAPEs                    \s*                    (?:--)?>                                        (.*) # $9 => $post - text that comes after the tag                   $/sx) {      $which = uc($1); # which tag is it      $escape = $3 || $8;      $escape = 0 if $2 || $7; # ESCAPE=0       $escape = 0 unless defined($escape);            # what name for the tag?  undef for a /tag at most, one of the      # following three will be defined      undef $name;      $name = $4 if defined($4);      $name = $5 if defined($5);      $name = $6 if defined($6);      # allow mixed case in filenames, otherwise flatten      $name = lc($name) unless ($which eq 'TMPL_INCLUDE' or $options->{case_sensitive});      my $post = $9; # what comes after on the line      # die if we need a name and didn't get one      die "HTML::Template->new() : No NAME given to a $which tag at $fname : line $fcounter." if (!defined($name) and $need_names{$which});      # die if we got an escape but can't use one      die "HTML::Template->new() : ESCAPE option invalid in a $which tag at $fname : line $fcounter." if ( $escape and ($which ne 'TMPL_VAR'));              # take actions depending on which tag found      if ($which eq 'TMPL_VAR') {	$options->{debug} and print STDERR "### HTML::Template Debug ### $fname : line $fcounter : parsed VAR $name\n";		# if we already have this var, then simply link to the existing	# HTML::Template::VAR, else create a new one.        	my $var;        	if (exists $pmap{$name}) {	  $var = $pmap{$name};	  (ref($var) eq 'HTML::Template::VAR') or	    die "HTML::Template->new() : Already used param name $name as a TMPL_LOOP, found in a TMPL_VAR at $fname : line $fcounter.";	} else {	  $var = HTML::Template::VAR->new();	  $pmap{$name} = $var;	  $top_pmap{$name} = HTML::Template::VAR->new()	    if $options->{global_vars} and not exists $top_pmap{$name};	}		# if ESCAPE was set, push an ESCAPE op on the stack before	# the variable.  output will handle the actual work.	if ($escape) {	  if ($escape =~ /^"?[Uu][Rr][Ll]"?$/) {	    push(@pstack, $URLESCAPE);	  } else {	    push(@pstack, $ESCAPE);	  }	}		push(@pstack, $var);	      } elsif ($which eq 'TMPL_LOOP') {	# we've got a loop start	$options->{debug} and print STDERR "### HTML::Template Debug ### $fname : line $fcounter : LOOP $name start\n";		# if we already have this loop, then simply link to the existing	# HTML::Template::LOOP, else create a new one.	my $loop;	if (exists $pmap{$name}) {	  $loop = $pmap{$name};	  (ref($loop) eq 'HTML::Template::LOOP') or	    die "HTML::Template->new() : Already used param name $name as a TMPL_VAR, TMPL_IF or TMPL_UNLESS, found in a TMP_LOOP at $fname : line $fcounter!";	  	} else {	  # store the results in a LOOP object - actually just a	  # thin wrapper around another HTML::Template object.	  $loop = HTML::Template::LOOP->new();	  $pmap{$name} = $loop;	}		# get it on the loopstack, pstack of the enclosing block	push(@pstack, $loop);	push(@loopstack, [$loop, $#pstack]);		# magic ti

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -