Interchange Reference Pages: Pragmas


For a complete introduction to Interchange pragmas, please see the pragma glossary entry.

Table of Contents

cache_control
dml — control behavior of Vend::Data::update_data()
download — disable any output interpolation not to corrupt verbatim content download
dynamic_variables — dynamically update configuration directives from files and databases
dynamic_variables_file_only — dynamically update configuration directives from files only
init_page — custom subroutine to run before page Variable processing
interpolate_itl_references — allow ITL interpolation of reference-based ITL attributes
max_matches
no_default_reparse — do not reparse Interchange output by default
no_html_comment_embed — do not treat specially formed HTML comments as ITL code
no_image_rewrite — prevent image locations from being altered
no_locale_parse — do not parse [L] or [LC] tags
no_negative_tax — disallow tax calculations to apply negative value
perl_warnings_in_page — display Perl "warnings" for Interchange pages
post_page — custom subroutine to run before image paths substitution on a page
pre_page — custom subroutine to run after Variable substitution, before interpolation
safe_data — allow interpolation of database values in search for Interchange tags
set_httponly
strip_white — strip whitespace from the top of Interchange-served HTML pages
url_no_session_id

Name

cache_control

VALUE

DEFAULT

DESCRIPTION

EXAMPLES

No examples are available at this time. We do consider this a problem and will try to supply some.

NOTES

AVAILABILITY

cache_control is available in Interchange versions:

5.8.0, 5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (2/2 contexts shown):

Source: lib/Vend/Server.pm
Line 596 (context shows lines 586-600 in get_cache_headers():593)

$_ = shift;
s:^\s+::;
s:\s+$::;
s:\s*\n\s*:\r\n:g;
return "$_\r\n";
}

sub get_cache_headers {
my @headers;

my $cc = $::Pragma->{cache_control};
push @headers, "Cache-Control: $cc" if $cc;

push @headers, "Pragma: no-cache" if delete $::Scratch->{mv_no_cache};


Source: lib/Vend/Server.pm
Line 760 (context shows lines 750-764 in respond():612)


# We ensure that POSTs are never suppressed (i.e., cacheable), and
# we also allow this option to be configured per catalog, as not
# every catalog may be be setup to properly handle these
# assumptions and affects.

$Vend::suppress_cookies =
  $CGI::request_method !~ /POST/i &&
  $Vend::Cfg->{SuppressCachedCookies} &&
  (
    (defined $::Pragma->{cache_control} && ($::Pragma->{cache_control} !~ /no-cache/i)) ||
    ($Vend::StatusLine =~ /^Cache-Control:\s+(?!no-cache)\s*$/im)
  )
;


SEE ALSO


Name

dml — control behavior of Vend::Data::update_data()

VALUE

none | preserve | strict

DEFAULT

none

DESCRIPTION

This pragma controls the behavior of Vend::Data::update_data() function in regard to manipulating database records.

No value implies the traditional and backward-compatible Interchange behavior of "update or insert" (upsert).

Value 'preserve' restricts inserts to insert-only, but allows the fall-through behavior from update to insert. As the name preserve implies, it means records can be inserted, but no existing data can be clobbered.

Value 'strict' forces update or insert to only perform the requested action.

EXAMPLES

Example: dml strict

Pragma dml=strict

NOTES

AVAILABILITY

dml is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Data.pm
Line 2278 (context shows lines 2268-2282 in update_data():1804)

  }

  push(@email_rows, [$f, $value])
    if $CGI::values{mv_data_email};
#::logDebug("update_data:db=$d key=$key field=$f value=$value");
  $brec->{$f} = $value if $brec;
}

my $dml = { dml => 'upsert' };
$dml->{dml} = $function
  if $::Pragma->{dml} eq 'strict'
    || $function eq 'insert' && $::Pragma->{dml} eq 'preserve';

for(keys %$qd) {
#::logDebug("update_data: Getting ready to set_slice");

AUTHORS

Mark Johnson

SEE ALSO


Name

download — disable any output interpolation not to corrupt verbatim content download

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

The main function of this pragma is to prevent any interpolation of the output (see the interpolate glossary entry). It helps to preserve the downloads intact if they happen to contain constructs similar to __VAR__ or [tag].

In practice, this pragma is only used internally. If you wanted to make Interchange a content-delivery engine only, you could set it in catalog.cfg, and only undefine it for a few pages where you want standard page processing.

You might take a look at the deliver tag which uses this pragma.

EXAMPLES

Example: Disable download pragma on a page

Put the following anywhere on your specific page:

[pragma download 0]

NOTES

AVAILABILITY

download is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (5/5 contexts shown):

Source: code/SystemTag/deliver.coretag
Line 96 (context shows lines 86-100)

if($opt->{extra_headers}) {
  my @lines = grep /\S/, split /[\r\n]+/, $opt->{extra_headers};
  for(@lines) {
    my ($header, $val) = split /:/, $_;
    $Tag->tag( {  op => 'header',
          name => $header,
          content => $val,
        } );
  }
}
$::Pragma->{download} = 1;
::response($out);
$Vend::Sent = 1;
return 1;
}

Source: lib/Vend/Interpolate.pm
Line 536 (context shows lines 526-540 in substitute_image():532)

elsif($joiner =~ m{\\}) {
  $joiner = $safe_safe->reval("qq{$joiner}");
}
return length($joiner) ? $joiner : $default;
}

sub substitute_image {
my ($text) = @_;

## Allow no substitution of downloads
return if $::Pragma->{download};

## If post_page routine processor returns true, return. Otherwise,
## continue image rewrite
if($::Pragma->{post_page}) {

Source: lib/Vend/Parse.pm
Line 774 (context shows lines 764-778 in start():594)

Status: $attr->{status}
Location: $attr->{href}
EOF
#::logDebug("bouncing...status line=\n$Vend::StatusLine");
$$buf = '';
$Initialized->{_buf} = '';

      my $body = qq{Redirecting to <a href="%s">%s</a>.};
      $body = errmsg($body, $attr->{href}, $attr->{href});
#::logDebug("bouncing...body=$body");
$::Pragma->{download} = 1;
::response($body);
$Vend::Sent = 1;
$self->{SEND} = 1;
return 1;

Source: lib/Vend/Dispatch.pm
Line 74 (context shows lines 64-78 in response():70)


my $H;
sub http {
return $H;
}

sub response {
my $possible = shift;
return if $Vend::Sent;

if (defined $possible and ! $::Pragma->{download}) {
  push @Vend::Output, (ref $possible ? $possible : \$possible);
}

if($::Pragma->{download}) {

Source: lib/Vend/Dispatch.pm
Line 78 (context shows lines 68-82 in response():70)

}

sub response {
my $possible = shift;
return if $Vend::Sent;

if (defined $possible and ! $::Pragma->{download}) {
push @Vend::Output, (ref $possible ? $possible : \$possible);
}

if($::Pragma->{download}) {
  $H->respond(ref $possible ? $possible : \$possible);
}
elsif($Vend::MultiOutput) {
  for my $space (keys %Vend::OutPtr) {

SEE ALSO

deliver(7ic)


Name

dynamic_variables — dynamically update configuration directives from files and databases

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

This pragma enables configuration directives (Variables, most notably) to be dynamically updated from system files and databases.

It only makes sense to use this in combination with the DirConfig or VariableDatabase directives, so check their reference pages for more information.

EXAMPLES

Example: Enable dynamic_variables pragma catalog-wide

Put the following in your catalog.cfg:

Pragma dynamic_variables

NOTES

AVAILABILITY

dynamic_variables is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (2/2 contexts shown):

Source: code/UserTag/var.tag
Line 25 (context shows lines 15-29)

my ($key, $global, $filter) = @_;
my $value;
if ($global and $global != 2) {
  $value = $Global::Variable->{$key};
}
elsif ($Vend::Session->{logged_in} and defined $Vend::Cfg->{Member}{$key}) {
  $value = $Vend::Cfg->{Member}{$key};
}
else {
  $value = (
    $::Pragma->{dynamic_variables}
    ? Vend::Interpolate::dynamic_var($key)
    : $::Variable->{$key}
  );
  $value ||= $Global::Variable->{$key} if $global;

Source: lib/Vend/Interpolate.pm
Line 613 (context shows lines 603-617 in vars_and_comments():595)

$::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);
}

# Substitute in Variable values
$$html =~ s/$Gvar/$Global::Variable->{$1}/g;
if($::Pragma->{dynamic_variables}) {
  $$html =~ s/$Evar/dynamic_var($1) || $Global::Variable->{$1}/ge
    and
  $$html =~ s/$Evar/dynamic_var($1) || $Global::Variable->{$1}/ge;
  $$html =~ s/$Cvar/dynamic_var($1)/ge;


Name

dynamic_variables_file_only — dynamically update configuration directives from files only

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

If this pragma is set, it prevents opening of Interchange databases in search for dynamic content of the directives, so that only files are checked.

It only makes sense to use this in combination with the <pragma>dynamic_variables</pragma> pragma, and DirConfig and VariableDatabase directives, so check their reference pages for more information.

EXAMPLES

Example: Enable dynamic_variables_file_only pragma catalog-wide

Put the following in your catalog.cfg:

Pragma dynamic_variables
Pragma dynamic_variables_file_only

NOTES

AVAILABILITY

dynamic_variables_file_only is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Interpolate.pm
Line 580 (context shows lines 570-584 in dynamic_var():572)

}

sub dynamic_var {
my $varname = shift;

return readfile($Vend::Cfg->{DirConfig}{Variable}{$varname})
  if $Vend::Cfg->{DirConfig}
    and defined $Vend::Cfg->{DirConfig}{Variable}{$varname};

VARDB: {
  last VARDB if $::Pragma->{dynamic_variables_file_only};
  last VARDB unless $Vend::Cfg->{VariableDatabase};
  if($Vend::VarDatabase) {
    last VARDB unless $Vend::VarDatabase->record_exists($varname);
    return $Vend::VarDatabase->field($varname, 'Variable');


Name

init_page — custom subroutine to run before page Variable processing

VALUE

subroutine_name

DEFAULT

None

DESCRIPTION

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.

EXAMPLES

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.


NOTES

AVAILABILITY

init_page is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Interpolate.pm
Line 605 (context shows lines 595-609 in vars_and_comments():595)

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);
}


Name

interpolate_itl_references — allow ITL interpolation of reference-based ITL attributes

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

When the pragma is enabled, ITL interpolation of reference-based ITL attributes is enabled.

In other words, suppose that you execute the following code:

EXAMPLES

Example: Enable interpolate_itl_references

The pragma allows the following type of code:

[pragma interpolate_itl_references]

[tmp testing]foobar'ed[/tmp]

[record
  table=inventory
  key=newkey
  col.quantity=300
  col.stock_message="[scratch testing]"
]

NOTES

AVAILABILITY

interpolate_itl_references is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Parser.pm
Line 210 (context shows lines 200-214)


}
next if $old;
if(! $attr) {
  $attr->{OLD} = $val if defined $attr;
  next;
}
if(defined $element) {
#::logDebug("Found element: $element val=$val");
  $val = Vend::Interpolate::interpolate_html($val)
    if  $::Pragma->{interpolate_itl_references}
    and $val =~ /\[\w[-\w]*\s+.*]/s;
  if(! ref $attr{$attr}) {
    if ($element =~ /[A-Za-z]/) {
      $attr{$attr} = { $element => $val };

SEE ALSO


Name

max_matches

VALUE

DEFAULT

DESCRIPTION

EXAMPLES

No examples are available at this time. We do consider this a problem and will try to supply some.

NOTES

AVAILABILITY

max_matches is available in Interchange versions:

5.8.0, 5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/DbSearch.pm
Line 241 (context shows lines 231-245 in search():116)

  $qual .= join $joiner, @{$s->{eq_specs_sql}};
}

$s->save_specs();

# set max_matches based on the lower of the pragma & the search parameter
# (so end-users can further restrict the size of the result set, but not increase it)
my $max_matches;
{
  no warnings 'uninitialized';
  $max_matches = $::Pragma->{max_matches};
  undef $max_matches if $max_matches < 1;
  my $search_mm = $s->{mv_max_matches};
  $max_matches = $search_mm
    if $search_mm > 0 and (!$max_matches or $search_mm < $max_matches);

SEE ALSO


Name

no_default_reparse — do not reparse Interchange output by default

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

This pragma disables default reparse of Interchange output from container tags.

Reparsing can, of course, still be requested using the Reparse setting in individual ITL tag definition, or by providing the universal reparse=1 attribute to any container tag.

EXAMPLES

Example: Enable no_default_reparse pragma page-wide

Put the following anywhere on your page:

[pragma no_default_reparse]

NOTES

AVAILABILITY

no_default_reparse is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Parse.pm
Line 702 (context shows lines 692-706 in start():594)

#::logDebug("using default $k = $v");
    $attr->{$k} = $v;
  }
}

$attr->{enable_html} = 1 if $Vend::Cfg->{Promiscuous};
$attr->{reparse} = 1
  unless (
    defined $NoReparse{$tag}
    || defined $attr->{reparse}
    || $::Pragma->{no_default_reparse}
  );

my ($routine,@args);


SEE ALSO


Name

no_html_comment_embed — do not treat specially formed HTML comments as ITL code

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

Many HTML editing applications do not support ITL directly, and some (thinking it doesn't belong to the page) ruin your work. This is understandable to an extent, because some ITL tags (such as list) appear in places that raise errors with HTML syntax checking algorithms.

So in order to help that, Interchange allows you to wrap ITL code into HTML comments, which the editing applications leave alone in most cases.

When such HTML comment is found, it is stripped away, ITL tags are interpolated and the output is displayed as if HTML comment was never there.

To make use of this arcane feature, simply leave no space between the HTML comment and ITL tags:


The time is now <!--[time]-->.

Setting the <pragma>no_html_comment_embed</pragma> pragma instructs Interchange not to parse and interpolate any HTML comments. With this pragma enabled, the above example would not display the current time.

EXAMPLES

Example: Enable no_html_comment_embed pragma page-wide

Put the following anywhere on your page:

[pragma no_html_comment_embed]

NOTES

Although this feature existed in Interchange for a very long time, the pragma to control its behavior was added in September 2004, after someone stumbled on it by accident.

AVAILABILITY

no_html_comment_embed is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Interpolate.pm
Line 634 (context shows lines 624-638 in vars_and_comments():595)

}

if($::Pragma->{pre_page}) {
Vend::Dispatch::run_macro($::Pragma->{pre_page}, $html);
}

# Strip out [comment] [/comment] blocks
1 while $$html =~ s%$QR{comment}%%go;

# Translate Interchange tags embedded in HTML comments like <!--[tag ...]-->
! $::Pragma->{no_html_comment_embed}
and
  $$html =~ s/<!--+\[/[/g
    and $$html =~ s/\]--+>/]/g;


SEE ALSO


Name

no_image_rewrite — prevent image locations from being altered

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

This pragma prevents image locations in Interchange pages from being altered.

Interchange normally rewrites image locations to point to ImageDir (or ImageDirSecure). This applies to image locations mentioned in <img src="">, <input src="">, <body background="">, <table background=""> and table subelements (<th>, <tr> and <td>).

EXAMPLES

Example: Image path rewriting example

If the <pragma>no_image_rewrite</pragma> pragma is disabled and ImageDir is set to "/standard/images", an image URL like:

<img src="fancy.gif">

would be changed to:

<img src="/standard/images/fancy.gif">

With the directive enabled, the image URLs would be left intact.


NOTES

AVAILABILITY

no_image_rewrite is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (4/4 contexts shown):

Source: code/SystemTag/unpack.coretag
Line 40 (context shows lines 30-44)

      }
    }
  }
}
else {
  for(@Vend::Output) {
    Vend::Interpolate::substitute_image($_);
  }
}
undef $Vend::MultiOutput;
$::Pragma->{no_image_rewrite} = 1;
Vend::Page::templatize($template);
return;
}
EOR

Source: lib/Vend/Interpolate.pm
Line 545 (context shows lines 535-549 in substitute_image():532)

## Allow no substitution of downloads
return if $::Pragma->{download};

## If post_page routine processor returns true, return. Otherwise,
## continue image rewrite
if($::Pragma->{post_page}) {
Vend::Dispatch::run_macro($::Pragma->{post_page}, $text)
and return;
}

unless ( $::Pragma->{no_image_rewrite} ) {
  my $dir = $CGI::secure                      ?
    ($Vend::Cfg->{ImageDirSecure} || $Vend::Cfg->{ImageDir})  :
    $Vend::Cfg->{ImageDir};


Source: lib/Vend/Parse.pm
Line 342 (context shows lines 332-346 in destination():309)

return unless $attr;
#::logDebug("destination extended output settings");

my $fary = $Vend::OutFilter{$name};

if ($name) {
  $Vend::MultiOutput = 1;
  if(! $Vend::OutFilter{''}) {
    my $ary = [];
    push @$ary, \&Vend::Interpolate::substitute_image
      unless $::Pragma->{no_image_rewrite};
    $Vend::OutFilter{''} = $ary;
  }

  if(! $fary) {

Source: lib/Vend/Parse.pm
Line 356 (context shows lines 346-360 in destination():309)

if(! $fary) {
    $fary = $Vend::OutFilter{$name} = [];
    if($attr->{output_filter}) {
      my $filt = $attr->{output_filter};
      push @$fary, sub {
        my $ref = shift;
        $$ref = Vend::Interpolate::filter_value($filt, $$ref);
        return;
      };
    }
    if (! $attr->{no_image_parse} and ! $::Pragma->{no_image_rewrite}) {
      push @$fary, \&Vend::Interpolate::substitute_image;
    }
    if ($attr->{output_extended}) {
      $Vend::OutExtended{$name} = $attr;


Name

no_locale_parse — do not parse [L] or [LC] tags

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

This pragma disables parsing of L and LC pseudo tags.

EXAMPLES

Example: enable pragma catalog wide

Pragma no_locale_parse


NOTES

Applying this pragma on the page level isn't really helpful, as pseudo tags contained in the page are parsed before the pragma directive.

AVAILABILITY

no_locale_parse is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (2/2 contexts shown):

Source: code/UserTag/loc.tag
Line 23 (context shows lines 13-27)

# it works with contained tags
#
UserTag loc Order       locale
UserTag l   Alias       loc
UserTag loc hasEndTag   1
UserTag loc Interpolate 1
UserTag loc Version     $Revision: 1.7 $
UserTag loc Routine     <<EOF
sub {
my ($locale, $message) = @_;
if($::Pragma->{no_locale_parse}) {
## Need to do this but might have side-effects in PreFork mode
undef $Vend::Parse::myRefs{Alias}{l};
my $begin = '[L';
$begin .= " $locale" if $locale;

Source: lib/Vend/Util.pm
Line 1113 (context shows lines 1103-1117 in parse_locale():1110)

}
$text =~ m{\[$Lang\](.*)\[/$Lang\]}s
  and return $1;
$text =~ s{\[(\w+)\].*\[/\1\].*}{}s;
return $text;
}

sub parse_locale {
my ($input) = @_;

return if $::Pragma->{no_locale_parse};

# avoid copying big strings
my $r = ref($input) ? $input : \$input;


SEE ALSO


Name

no_negative_tax — disallow tax calculations to apply negative value

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

When the pragma is enabled and the tax calculation yields a negative number, the tax amount applied will be reset to zero.

EXAMPLES

Example: Enable no_negative_tax

Put the following in catalog.cfg:

Pragma no_negative_tax

NOTES

AVAILABILITY

no_negative_tax is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (2/2 contexts shown):

Source: lib/Vend/Interpolate.pm
Line 5724 (context shows lines 5714-5728 in salestax():5681)

}
else {
  $tax_hash = $Vend::Cfg->{SalesTaxTable};
#::logDebug("looking for tax function: " . uneval($tax_hash));
}

# if we have a cost from previous routines, return it
if(defined $cost) {
  $Vend::Items = $save if $save;
  switch_discount_space($oldspace) if defined $oldspace;
  if($cost < 0 and $::Pragma->{no_negative_tax}) {
    $cost = 0;
  }
  return Vend::Util::round_to_frac_digits($cost);
}

Source: lib/Vend/Interpolate.pm
Line 5781 (context shows lines 5771-5785 in salestax():5681)

        {  mv_price  => $amount, 
          code    => $code,
          quantity  => $amount, }, $tax);
  }
#::logDebug("salestax: final tax='$r' for code='$code'");
  last;
}

$Vend::Items = $save if defined $save;

if($r < 0 and ! $::Pragma->{no_negative_tax}) {
  $r = 0;
}

return Vend::Util::round_to_frac_digits($r);

SEE ALSO

tax


Name

perl_warnings_in_page — display Perl "warnings" for Interchange pages

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

If it is desirable to turn on Perl warnings for pages, you can use [pragma perl_warnings_in_page] and see warnings for that page (or all pages by default if you put in catalog.cfg).

EXAMPLES

Example: Enable perl_warnings_in_page catalog-wide

Put the following in catalog.cfg:

Pragma perl_warnings_in_page

Example: Enable perl_warnings_in_page page-wide

[pragma perl_warnings_in_page]

NOTES

AVAILABILITY

perl_warnings_in_page is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Interpolate.pm
Line 665 (context shows lines 655-669 in interpolate_html():642)

and $html =~ s/^/$::Variable->{MV_AUTOLOAD}/;
defined $::Variable->{MV_AUTOEND}
and $html =~ s/$/$::Variable->{MV_AUTOEND}/;
$toplevel = 1;
}
#::logDebug("opt=" . uneval($opt));

vars_and_comments(\$html)
  unless $opt and $opt->{onfly};

$^W = 1 if $::Pragma->{perl_warnings_in_page};

  # Returns, could be recursive
my $parse = new Vend::Parse $wantref;
$parse->parse($html);

SEE ALSO


Name

post_page — custom subroutine to run before image paths substitution on a page

VALUE

subroutine_name

DEFAULT

None

DESCRIPTION

This pragma defines a Sub or GlobalSub to run before image paths substitution on a page. A reference to the page contents is passed to the subroutine.

EXAMPLES

Example: Treat URLs relative to current directory

It is possible to have URL links treated as being relative to the current directory. The following is needed in catalog.cfg:

Pragma   post_page=relative_urls

### Take hrefs like <A HREF="about.html"> and make relative to current
### directory
Sub <<EOR
  sub relative_urls {
    my $page = shift;
    my @dirs = split "/", $Tag->var('MV_PAGE', 1);
    pop @dirs;
    my $basedir = join  "/", @dirs;
    $basedir ||= '';
    $basedir .= '/' if $basedir;

    my $sub = sub {
      my ($entire, $pre, $url) = @_;
      return $entire if $url =~ /^\w+:/;
      my($page, $form) = split /\?/, $url, 2;
      my $u = $Tag->area({
        href => "$basedir$page",
        form => $form,
      });
      return qq{$pre"$u"};
    };
    $$page =~ s{(
        (
        <a \s+ (?:[^>]+?\s+)?
          href \s*=\s*
        )
        (["']) ([^\s"'>]+) \3
      )}
      {
        $sub->($1,$2,$4)
      }gsiex;

    return;
  }
EOR

NOTES

The old documentation system improperly describes the phase at which the <pragma>post_page</pragma> pragma takes effect (it states it happens after Variable processing and before tags are interpolated).

AVAILABILITY

post_page is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Interpolate.pm
Line 540 (context shows lines 530-544 in substitute_image():532)

}

sub substitute_image {
my ($text) = @_;

## Allow no substitution of downloads
return if $::Pragma->{download};

## If post_page routine processor returns true, return. Otherwise,
## continue image rewrite
if($::Pragma->{post_page}) {
  Vend::Dispatch::run_macro($::Pragma->{post_page}, $text)
    and return;
}



Name

pre_page — custom subroutine to run after Variable substitution, before interpolation

VALUE

subroutine_name

DEFAULT

None

DESCRIPTION

This pragma defines a Sub or GlobalSub to run after Variable substitution and before tags are interpolated on a page. A reference to the page contents is passed to the subroutine.

EXAMPLES

No examples are available at this time. We do consider this a problem and will try to supply some.

NOTES

AVAILABILITY

pre_page is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Interpolate.pm
Line 626 (context shows lines 616-630 in vars_and_comments():595)

$$html =~ s/$Evar/dynamic_var($1) || $Global::Variable->{$1}/ge;
$$html =~ s/$Cvar/dynamic_var($1)/ge;
}
else {
  $$html =~ s/$Evar/$::Variable->{$1} || $Global::Variable->{$1}/ge
    and
  $$html =~ s/$Evar/$::Variable->{$1} || $Global::Variable->{$1}/ge;
  $$html =~ s/$Cvar/$::Variable->{$1}/g;
}

if($::Pragma->{pre_page}) {
  Vend::Dispatch::run_macro($::Pragma->{pre_page}, $html);
}

# Strip out [comment] [/comment] blocks


Name

safe_data — allow interpolation of database values in search for Interchange tags

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

By default, Interchange does not allow data returned from the databases to be interpolated (all the [s are converted to an HTML entity &#91; and displayed literally). Setting this pragma eliminates the restriction and passes [s through for interpolation.

If you want to have tags in your database and display them in Interchange pages (to say, display page links for internal hyperlinks in your product descriptions), you need to enable this pragma. Some things to consider, though:

It might be better to use the safe_data attribute available to certain tags, or perhaps the pragma for a whole page or tag pragma safe_data/tag for a small block of ITL code on a page, instead of setting a catalog-wide <pragma>safe_data</pragma> pragma.

In any case, it is strongly recommended that you surround the area in a restrict tag to only allow specific set of tags to appear "in-band" (which should be relatively safe), such as page or area. Expect security compromises if you allow calc, perl or any other extremely powerful tags.

Be certain that you absolutely know where the data from your databases will be used. Consider the following:

  • Will it always be possible to interpolate?

  • What about e-mailed plain-text receipts? Will literal "page " tags show up in product descriptions on the receipt?

  • Would the desired output of <a href="..."> be any better than a simple plain text?

  • What if you access your database from applications other than Interchange? You'd then have to decide what to do with such tags; perhaps you could simply strip them, but will the missing output cause trouble?

To sum up, <pragma>safe_data</pragma> is disabled by default for a reason, and you should be very careful if you decide to enable it.

EXAMPLES

Example: Enabling safe_data catalog-wide

Add the following to catalog.cfg:

Pragma safe_data

Example: Enabling safe_data block-wide

We'll restrict the available tags to area and page, and enclose the critical section in [tag pragma ...]:

[tag pragma safe_data]1[/tag]
  ...critical section...
  [restrict area page]
  ...critical section...
  [/restrict]
  ...critical section...
[tag pragma safe_data]0[/tag]

Example: Enabling safe_data page-wide

Add the following anywhere on an Interchange page:

[pragma safe_data]

NOTES

Watch out for parse order with tag pragma or restrict when used with lists that retrieve data from the database (such as PREFIX-*, loop, or the flypage). Loops parse before regular tags like tag, and are thus not affected by them (so you must include the whole loop code in the "critical section").

AVAILABILITY

safe_data is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Interpolate.pm
Line 1748 (context shows lines 1738-1752 in ed():1747)

if ($opt->{no_return}) {
  $Vend::Session->{mv_perl_result} = $result;
  $result = join "", @Vend::Document::Out;
  @Vend::Document::Out = ();
}
#::logDebug("tag_perl succeeded result=$result\nEND");
return $result;
}

sub ed {
return $_[0] if ! $_[0] or $Safe_data or $::Pragma->{safe_data};
$_[0] =~ s/\[/&#91;/g;
return $_[0];
}


SEE ALSO


Name

set_httponly

VALUE

DEFAULT

DESCRIPTION

EXAMPLES

No examples are available at this time. We do consider this a problem and will try to supply some.

NOTES

AVAILABILITY

set_httponly is available in Interchange versions:

5.8.0, 5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Server.pm
Line 578 (context shows lines 568-582 in create_cookie():523)

    elsif($expire =~ /\s\S+\s/) {
      $expstring = $expire;
    }
    $expstring = strftime "%a, %d-%b-%Y %H:%M:%S GMT ", gmtime($expire)
      unless $expstring;
    $expstring = "expires=$expstring" if $expstring !~ /^\s*expires=/i;
    $expstring =~ s/^\s*/ /;
    $out .= $expstring;
  }
  $out .= '; secure' if $secure;
  $out .= '; HttpOnly' if $::Pragma->{set_httponly};
  $out .= "\r\n";
}
return $out;
}

SEE ALSO


Name

strip_white — strip whitespace from the top of Interchange-served HTML pages

VALUE

0 | 1

DEFAULT

0

DESCRIPTION

This pragma strips whitespace from the top of HTML pages output by Interchange. Such whitespace usually comes from Interchange tags which get processed and leave empty space behind them. The purpose of this pragma is to make View source option in your web browser a more tolerable experience.

EXAMPLES

Example: Strip whitespace from the top of Interchange-served pages

Simply add the following to catalog.cfg

Pragma strip_white

NOTES

AVAILABILITY

strip_white is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (2/2 contexts shown):

Source: lib/Vend/Page.pm
Line 275 (context shows lines 265-279 in output_cat():265)

sub output_cat {
my ($tag) = @_;
my $ary;
return '' unless $ary = $Vend::OutPtr{lc $tag};
my $out = '';
for(@$ary) {
  next unless $Vend::Output[$_];
  $out .= ${$Vend::Output[$_]};
  undef $Vend::Output[$_];
}
$out =~ s/^\s+// if $::Pragma->{strip_white};
return $out;
}

sub output_ary {

Source: lib/Vend/Server.pm
Line 636 (context shows lines 626-640 in respond():612)

      ? "$1"
      : "200 OK";
}

if($CGI::redirect_status and ! $Vend::StatusLine) {
  $status = "200 OK";
  $Vend::StatusLine = "Status: 200 OK\nContent-Type: text/html";
}

$$body =~ s/^\s+//
  if ! $Vend::ResponseMade and $::Pragma->{strip_white};

$Vend::StatusLine =~ s/\s*$/\r\n/ if $Vend::StatusLine;

# NOTE: if we're supporting arbitrary encodings here in the

SEE ALSO


Name

url_no_session_id

VALUE

DEFAULT

DESCRIPTION

EXAMPLES

No examples are available at this time. We do consider this a problem and will try to supply some.

NOTES

AVAILABILITY

url_no_session_id is available in Interchange versions:

5.8.0, 5.9.0 (git-head)

SOURCE

Interchange 5.9.0 (1/1 contexts shown):

Source: lib/Vend/Util.pm
Line 1366 (context shows lines 1356-1370 in vendUrl():1316)

  push @parms, Vend::Interpolate::escape_form($opt->{form});
}

my($id, $ct);
$id = $Vend::SessionID
  unless $opt->{no_session_id}
  or     ($Vend::Cookie and $::Scratch->{mv_no_session_id});
$ct = ++$Vend::Session->{pageCount}
  unless $opt->{no_count};

if($opt->{no_session} or $::Pragma->{url_no_session_id}) {
  undef $id;
  undef $ct;
}


SEE ALSO

DocBook!Interchange!