init_page — custom subroutine to run before page Variable processing
This pragma defines a Sub
or GlobalSub
to run
before page Variable
processing.
A reference to the contents of the
page is passed to the subroutine.
Example: Auto-wrapping pages in templates
We check the page to see if it contains any @_VARIABLE_@
strings.
If it does not, we consider it not to have a template and add the
definitions ourselves.
The following is needed in catalog.cfg
:
Pragma init_page=wrap_page Sub <<EOS sub wrap_page { my $pref = shift; return if $$pref =~ m{\@_[A-Z]\w+_\@}; $$pref =~ m{<!--+ title:\s*(.*?)\s+-->} and $Scratch->{page_title} = $1; $$pref = <<EOF; \@_MYTEMPLATE_TOP_\@ <!--BEGIN CONTENT --> $$pref <!-- END CONTENT --> \@_MYTEMPLATE_BOTTOM_\@ EOF return; } EOS
Example: Auto-wrapping pages in templates, deciding about a template depending on page path
In this real-life example, we want to automatically attach header and footer to every served page. We also have four different templates, and want to include them depending on the path of the page being served.
Pragma init_page=wrap_page Sub <<EOS sub wrap_page { my $pref = shift; my $tmpl; if ( $Session->{last_url} =~ m#^/www(/|$)# ) { $tmpl = "www" } elsif ( $Session->{last_url} =~ m#^/plus(/|$)# ) { $tmpl = "plus" } elsif ( $Session->{last_url} =~ m#^/hp(/|$)# ) { $tmpl = "hp" } elsif ( $Session->{last_url} =~ m#^/adm(/|$)# ) { $tmpl = "adm" } $Scratch->{subsite} = $tmpl || $Scratch->{subsite} || "plus"; $$pref = "[include templates/$Scratch->{subsite}-top]" . $$pref . "[include templates/$Scratch->{subsite}-bottom]"; return; } EOS
Note that we explicitly check for supported template types
(www
, plus
, hp
or adm
) to minimize the chance of abuse.
Invalid or unmatched templates default to the previously used template, or
plus
as a bottom line and
the files templates/plus-top
and
templates/plus-bottom
are included then.
You might wonder in what cases would the code fail to match the template?
Well, obviously, users could simply try to access non-existent pages.
The other common issue are ActionMaps such as
/scan
or /process
.
Interchange 5.9.0 (1/1 contexts shown):
Source: lib/Vend/Interpolate.pm
Line 603 (context shows lines 593-607 in vars_and_comments():593)
sub vars_and_comments { my $html = shift; ## We never want to interpolate vars if in restricted mode return if $Vend::restricted; local($^W) = 0; # Set whole-page pragmas from [pragma] tags 1 while $$html =~ s/\[pragma\s+(\w+)(?:\s+(\w+))?\]/ $::Pragma->{$1} = (length($2) ? $2 : 1), ''/ige; undef $Vend::PageInit unless $::Pragma->{init_page}; if(defined $Vend::PageInit and ! $Vend::PageInit++) { Vend::Dispatch::run_macro($::Pragma->{init_page}, $html); }