4.38. if

4.38.1. Summary

Parameters: type term op compare

THIS TAG HAS SPECIAL POSITIONAL PARAMETER HANDLING.

Pass attribute hash as last to subroutine: no

Must pass named parameter interpolate=1 to cause interpolation.

This is a container tag, i.e. [if] FOO [/if]. Nesting: NO

Invalidates cache: YES

Called Routine:

Called Routine for positional:

ASP-like Perl call:

Not applicable. Any [if ...] call can be better and more efficiently done with Perl.

Attribute aliases

            base ==> type
            comp ==> compare
            condition ==> compare
            operator ==> op
Parameters Description Default
base Alias for type DEFAULT_VALUE
comp Alias for compare DEFAULT_VALUE
compare   DEFAULT_VALUE
condition Alias for compare DEFAULT_VALUE
op   DEFAULT_VALUE
operator Alias for op DEFAULT_VALUE
term   DEFAULT_VALUE
type   DEFAULT_VALUE
Attributes Default
interpolate No
reparse Yes
Other_Characteristics  
Invalidates cache YES
Container tag Yes
Has Subtags No
Nests No

Tag expansion example:

    [if type term op compare]
---
    TODO: (tag result)

ASP-like Perl call:

   $Tag->if(  { compare => VALUE_compare
                 op => VALUE_op
                 term => VALUE_term
                 type => VALUE_type
}, $body  );

or similarly with positional parameters,

    $Tag->if(type,term,op,compare, $attribute_hash_reference, $body);

4.38.2. Description

Named call example: [if type="type" term="field" op="op" compare="compare"]

Positional call example: [if type field op compare]

negated: [if type="!type" term="field" op="op" compare="compare"]

Positional call example: [if !type field op compare]

Allows conditional building of HTML based on the setting of various Interchange session and database values. The general form is:

    [if type term op compare]
    [then]
                                If true, this is printed on the document.
                                The [then] [/then] is optional in most
                                cases. If ! is prepended to the type
                                setting, the sense is reversed and
                                this will be output for a false condition.
    [/then]
    [elsif type term op compare]
                                Optional, tested when if fails
    [/elsif]
    [else]
                                Optional, printed when all above fail
    [/else]
    [/if]

The [if] tag can also have some variants:

    [if type=explicit compare=`$perl_code`]
        Displayed if valid Perl CODE returns a true value.
    [/if]

You can do some Perl-style regular expressions:

    [if value name =~ /^mike/]
                                This is the if with Mike.
    [elsif value name =~ /^sally/]
                                This is an elsif with Sally.
    [/elsif]
    [elsif value name =~ /^pat/]
                                This is an elsif with Pat.
    [/elsif]
    [else]
                                This is the else, no name I know.
    [/else]
    [/if]

While named parameter tag syntax works for [if ...], it is more convenient to use positional calls in most cases. The only exception is if you are planning on doing a test on the results of another tag sequence:

    [if value name =~ /[value b_name]/]
        Shipping name matches billing name.
    [/if]

Oops! This will not work. You must do instead

    [if base=value term=name op="=~" compare="/[value b_name]/"]
        Shipping name matches billing name.
    [/if]

or better yet

    [if type=explicit compare=`
                        $Values->{name} =~ /$Values->{b_name}/
                        `]
        Shipping name matches billing name.
    [/if]

Interchange also supports a limited [and ...] and [or ...] capability:

    [if value name =~ /Mike/]
    [or value name =~ /Jean/]
    Your name is Mike or Jean.
    [/if]

    [if value name =~ /Mike/]
    [and value state =~ /OH/]
    Your name is Mike and you live in Ohio.
    [/if]

If you wish to do very complex AND and OR operations, you will have to use [if explicit] or better yet embedded Perl/ASP. This allows complex testing and parsing of values.

There are many test targets available:

4.38.2.1. config Directive

The Interchange configuration variables. These are set by the directives in your Interchange configuration file (or the defaults).

    [if config CreditCardAuto]
    Auto credit card validation is enabled.
    [/if]

4.38.2.2. data database::field::key

The Interchange databases. Retrieves a field in the database and returns true or false based on the value.

    [if data products::size::99-102]
    There is size information.
    [else]
    No size information.
    [/else]
    [/if]

    [if data products::size::99-102 =~ /small/i]
    There is a small size available.
    [else]
    No small size available.
    [/else]
    [/if]

4.38.2.3. discount

Checks to see if a discount is present for an item.

    [if discount 99-102]
    Item is discounted.
    [/if]

4.38.2.4. explicit

A test for an explicit value. If Perl code is placed between a [condition] [/condition] tag pair, it will be used to make the comparison. Arguments can be passed to import data from user space, just as with the [perl] tag.

    [if explicit]
    [condition]
        $country = '[value country]';
        return 1 if $country =~ /u\.?s\.?a?/i;
        return 0;
    [/condition]
    You have indicated a US address.
    [else]
    You have indicated a non-US address.
    [/else]
    [/if]

This example is a bit contrived, as the same thing could be accomplished with [if value country =~ /u\.?s\.?a?/i], but you will run into many situations where it is useful.

This will work for Variable values:

    [if type=explicit compare="__MYVAR__"] .. [/if]

However, note that the 'compare' option is equivalent to the [condition] block in that both evaluate as Perl code. That means you need to watch out when you put in user-supplied values (so that users can't inject Perl code on your server) and data from your own variables or tables which may look different than you expected.

For example, say you're in a loop checking whether at least one of the fields 'foo' and 'bar' has a value ("true" according to Perl):

    [if type=explicit compare="[loop-param foo][loop-param bar]"]

Most of the time this works fine. But if 'foo' contains a string beginning with '0', such as '0009', Perl will try to interpret it as an octal number, where the digit '9' is invalid, resulting in this unexpected error in the catalog error log:

    Bad if 'explicit   0009': Illegal octal digit '9' at (eval 155) line 1, at end of line

A safer way to check is:

    [if type=explicit compare="q{[loop-param foo][loop-param bar]}"]

Although then your data should not contain a '}'. To be extra safe you can surround your interpolated data with a [filter X] ... [/filter] tag pair appropriate for the quoting method you've used.

4.38.2.5. file

Tests for existence of a file. Useful for placing image tags only if the image is present.

    [if type=file term="/home/user/www/images/[item-code].gif"]
    <IMG SRC="[item-code].gif">
    [/if]

The file test requires that the SafeUntrap directive contains ftfile (which is the default).

4.38.2.6. items

The Interchange shopping carts. If not specified, the cart used is the main cart. Usually used as a litmus test to see if anything is in the cart, for example:

  [if items]You have items in your shopping cart.[/if]

  [if items layaway]You have items on layaway.[/if]

4.38.2.7. ordered

Order status of individual items in the Interchange shopping carts. If not specified, the cart used is the main cart. The following items refer to a part number of 99-102.

  [if ordered 99-102] Item 99-102 is in your cart. [/if]
    Checks the status of an item on order, true if item
    99-102 is in the main cart.

  [if ordered 99-102 layaway] ... [/if]
    Checks the status of an item on order, true if item
    99-102 is in the layaway cart.

  [if ordered 99-102 main size] ... [/if]
    Checks the status of an item on order in the main cart,
    true if it has a size attribute.

  [if ordered 99-102 main size =~ /large/i] ... [/if]
    Checks the status of an item on order in the main cart,
    true if it has a size attribute containing 'large'.

    To make sure it is exactly large, you could use:

  [if ordered 99-102 main size eq 'large'] ... [/if]

4.38.2.8. pragma

The Interchange Pragma settings, set with the the catalog.cfg manpage directive Pragma or with [pragma name].

    [if pragma dynamic_variables]
    __THE_VARIABLE__
    [else]
    [data table=variable column=Variable key=THE_VARIABLE]
    [/else]
    [/if]

4.38.2.9. scratch

The Interchange scratchpad variables, which can be set with the [set name]value[/set] element.

    [if scratch mv_separate_items]
    ordered items will be placed on a separate line.
    [else]
    ordered items will be placed on the same line.
    [/else]
    [/if]

4.38.2.10. session

the Interchange session variables. of particular interest are login, frames, secure, and browser.

4.38.2.11. validcc

a special case, takes the form [if validcc no type exp_date]. evaluates to true if the supplied credit card number, type of card, and expiration date pass a validity test. does a Luhn-10 calculation to weed out typos or phony card numbers. Uses the standard CreditCardAuto variables for targets if nothing else is passed.

4.38.2.12. value

the Interchange user variables, typically set in search, control, or order forms. Variables beginning with mv_ are Interchange special values, and should be tested/used with caution.

The field term is the specifier for that area. For example, [if session logged_in] would return true if the logged_in session parameter was set.

As an example, consider buttonbars for frame-based setups. It would be nice to display a different buttonbar (with no frame targets) for sessions that are not using frames:

    [if scratch frames]
        __BUTTONBAR_FRAMES__
    [else]
        __BUTTONBAR__
    [/else]
    [/if]

Another example might be the when search matches are displayed. If you use the string '[value mv_match_count] titles found', it will display a plural for only one match. Use:

    [if value mv_match_count != 1]
        [value mv_match_count] matches found.
    [else]
        Only one match was found.
    [/else]
    [/if]

The op term is the compare operation to be used. Compare operations are as in Perl:

    ==  numeric equivalence
    eq  string equivalence
    >   numeric greater-than
    gt  string greater-than
    <   numeric less-than
    lt  string less-than
    !=  numeric non-equivalence
    ne  string non-equivalence

Any simple perl test can be used, including some limited regex matching. More complex tests are best done with [if explicit].

4.38.2.13. [then] text [/then]

This is optional if you are not nesting if conditions, as the text immediately following the [if ..] tag is used as the conditionally substituted text. If nesting [if ...] tags you should use a [then][/then] on any outside conditions to ensure proper interpolation.

4.38.2.14. [elsif type field op* compare*]

named attributes: [elsif type="type" term="field" op="op" compare="compare"]

Additional conditions for test, applied if the initial [if ..] test fails.

4.38.2.15. [else] text [/else]

The optional else-text for an if or [if-field] conditional.

4.38.2.16. [condition] text [/condition]

Only used with the [if explicit] tag. Allows an arbitrary expression in Perl to be placed inside, with its return value interpreted as the result of the test. If arguments are added to [if explicit args], those will be passed as arguments are in the [perl] construct.

4.38.2.17. compare

4.38.2.18. op

4.38.2.19. term

4.38.2.20. type