All features are available in Hazel 3.2, unless otherwise noted. Post-3.2 features are included at the bottom of the file. An %HZM_FOO token referenced in a writable context refers to setting a hazel.config field named FOO. ---------------------------------------------------------------------- Misc enhancements: * Boosted maximum length of a config or products file line to 4,096. * Removed case sensitivity from all HZML tags. * Most HZML tag attributes are now HZML-ified. * HZML element names may now use dashes instead of underscores. For example, HAZEL_TRUE can now be written as HAZEL-TRUE. -- As of Hazel 3.1, the Hazel "choice" tags (HAZEL_CHOICE, HAZEL_TRUE, HAZEL_FALSE) allow you to specify an expression in the form of a Hazel search engine spec. (See the search engine documentation.) Here's an example useful for goading your customers.

You hear that noise? That was my six-year-old daugher's tummy grumbling. Please spend a little more than the $%HZT_MERCH you've spent so far so I can buy her some gorditas. She's eying my toddler and grunting "Yo quiero newborn!" FOR THE LOVE OF GOD, SPEND!

Here's a more practical example intended for the error template. If the word "credit" is in the error message, an option to re-enter credit info is supplied.

Click here to re-enter your credit information.

If the search expressions confuse you, use the following new attributes of the Hazel choice tags instead. SEQ="string" # Equal to string. SNE="string" # Not equal to string. SIN="string" # Token contains string. SNI="string" # Token does not contain string. GT="integer" # Token is greater than integer. GE="integer" # Token is greater than or equal to integer. LT="integer" # Token is less than integer. LE="integer" # Token is less than integer. EQ="integer" # Token is equal to integer. NE="integer" # Token is not equal to integer. MOD="integer" # Token is not evenly divisible by integer. -- Complex Tokens Hazel 3.1 introduces a new syntax for the HZML token. It can be used to construct complex tokens with names composed of other HZML tokens and/or containing otherwise invalid characters. The syntax of a "complex" token is %HZ{...} where "..." is any sequence of text or HZML tokens (including other complex tokens). A few points to remember when constructing complex tokens: * Whitespace is ignored within the braced text. * The entire complex token must be contained within a single line. * Newlines are replaced with spaces in the final result. A simple example is "%HZ{ E_BILL_FNAME }", which is equivalent to "%HZE_BILL_FNAME". (Except that any newlines in the value are replaced with spaces.) Here's a more interesting (and useful) example which enables us to save customization notes for each SKUID. Say all of your products could be monogrammed; you need to provide a space for the shopper to enter their initials. You could add the following to your checkout template, within your main selected loop. Because the '%' in "%HZI_SKUID" is not a valid HZML token, you couldn't use "%HZE_INITIALS_%HZI_SKUID". Hazel would interpret that as two separate HZML tokens to be evaluated -- "%HZE_INITIALS_" and "%HZI_SKUID". By using the braces of the complex token, you can construct the meat of a single HZML token by using other HZML tokens. -- If HTTPS_AUTO is set true, automatically switch to secure mode for the CHECKOUT and CONFIRM actions. If HTTPS_ALWAYS is set true, always serve the catalog in secure mode. HTTP_DOC_ROOT and HTTP_CGI_BIN should be set same as HTTPS_DOC_ROOT and HTTPS_CGI_BIN. (Same behaviour as old HTTPS_ENABLED:2.) -- The subst.rules file can define KEY:VAL pairs where "KEY" in any served page will be replaced with the HZML-ified value of "VAL". By editing the custom.rules file, you can change most of the messages output by Hazel. In conjunction with Hazel's templates, these rules allow you to customize Hazel to suit any audience. (Especially useful if your catalog is not intended for english-speaking shoppers.) (Both of these files can be plucked from the current unrolled distribution archive at ftp://ftp.netsville.com/pub/hazel/dist.) -- If a product has a MINQ field, its value is the minimum quantity of that product required for order completion, enforced at the CONFIRM stage. Likewise, a MAXQ field is the maximum quantity of that product selectable per order. -- If ORDER_ID_FORMAT is present in the config file, use it to create each order-id. %HZM_ORDER_SEQ can be used as a sequential order number, incremented each time an order-id is assigned. It will not necessarily be a count of the total orders the merchant has received, as some orders with an order-id may not ultimately be submitted and processed. If ORDER_ID_FORMAT is missing, the 3.0 style of "%HZM_DATE-%HZE_CLIENT" is used. To have it as a simple number incremented for each shopper who reaches the checkout stage, use the special token %HZM_ORDER_SEQ like so: ORDER_ID_FORMAT:%HZM_ORDER_SEQ Or to prefix it with some identifier: ORDER_ID_FORMAT:%HZM_STORE_ID-%HZM_ORDER_SEQ If width specifiers are used in %HZM_ORDER_SEQ (ie. "%HZM_08R_ORDER_SEQ"), the padding character will be zero ('0') rather than the usual space. -- Added STRBEG (^) and STREND ($) search operands to match text at the beginning or end of a product field value. -- Special token %HZM_SHIP_TO_BILL will be set true if all SHIP_FOO field values have a corresponding and equal BILL_FOO value. -- Refuse orders from shoppers with e-mail addresses from semicolon-delimited hosts in BOGUS_EMAIL_DOMAINS config field. -- New SUBST_FORMS, SUBST_LINKS, SUBST_HZ_CMT, SUBST_FP_PCT, SUBST_FP_HZU, SUBST_BASE and SUBST_HARD_BASE fields are preferred replacements for words within the CONTEXT_SUBS config field. -- Added %HZM_PRODUCT_LOOP_COUNT and %HZM_NOTE_LOOP_COUNT, each returning the index of iteration. Useful for numbering lists of products within a loop, or in conjunction with the MOD of a Hazel choice to (eg.) alternate table row colors. --- If the ORDERS_DB_FORMAT config file field has a value of `file', each order is saved to a file with a basename of its order-id and a `txt' extension in an `orders' subdirectory of your CAT_DIR. --- Currency Conversion Hazel 3.1 introduces currency conversion tools. They depend on your keeping a current currency.rules file with the latest conversion rates. The prices in your products file should be entered in the same base currency used with conversion rates in your currency.rules file. You may use only one base currency for your catalog! To convert from your base currency to another, use the HAZEL_CURRENCY tag: For example, if your base currency was "usd" (United States Dollars) and you wanted to list the price of an item in Japanese Yen, you'd use the following tag. Hazel will look for a "jpy" line in your currency.rules file and apply the proper equation to the given amount. Another, more practical usage of the HAZEL_CURRENCY tag would use a CURRENCY field value previously entered by the shopper to display checkout prices in their preferred currency. Try this within a products loop: To list all currencies available in your currency.rules file, use the CURRENCY loop described below. Within each iteration, %HZM_WORD1 is the three-letter code for the currency, %HZM_WORD2 is the exchange rate, and %HZM_WORD3 is its description. Be sure to make it clear to your customers that these rates are approximations for their convenience! The currency tools are only as accurate and current as your currency.rules updates. -- Added ..., which wraps all text within its body to the given WRAPCOL characters. SPACECOL is an optional argument specifying the leftmost column at which a space will be accepted as a soft line break. If no space exists to the right of that column, chop the line in the middle of a word. It defaults to 75% of the wrap column. Other attributes are PREFIX and POSTFIX (strings to be placed at the beginning and end of each line), FIXWIDTH (if true, force this width for all lines), PADCHAR (padding for FIXWIDTH, defaults to a the PADCHAR tweak, then a space). -- %HZG_FOO returns the total selected quantity of items with a GROUP field with a value of "FOO". This is most useful in shipping rules files which need to (eg.) add extra shipping costs for bulky items. -- Sets the fill character for fixed-width tokens. -- New THEMES feature allows customizable products, options, loops/, rules/, templates/ for (eg.) users of different nationalities. Just pass a field named THEME with the value of a directory name under hazel-cat/themes which you want to use. For example, if your directories were called "en" and "de", you could do something like this: English Catalog Deutscher Katalog Those assume you have en/ and de/ directories underneath your main hazel-doc where catalog text in each language is kept. %HZM_DEFAULT_THEME controls which theme is used by default, which can be used to easily switch between themed catalogs. (One application would be an "April fool's" or Christmas theme which could be easily toggled with that field.) -- If a `custom' templates subdirectory exists, Hazel will optionally output a file there with the (lowercased) basename of a particular CUSTOM message. For example, one could add a templates/custom/cart_emptied.html template to be displayed when the shopping cart is emptied. -- If a `pending' hazel-cat subdirectory exists, Hazel will save a file there with the basename of the order-id and a `.txt' extension when a shopper reaches the CONFIRM stage of checkout. This is especially useful in conjunction with payment methods which sometimes fail midway and capture funds before recording any order info. The file is deleted when an order is finished. -- Hazel will now complain if a SHIP_METHOD without a corresponding shipping rules file is passed. Be sure to offer a shipping rules file, even if you don't want any shipping charges applied. (Alternatively, add ALLOW_MISSING_SHIPPING_RULES with a true value to your config file.) Shouldn't be a problem with softgoods-only catalogs, since they force an early return from tally_shipping. -- Discount rules now accept action `-NUM', interpreted by adding NUM to the total discount. It is not recommended for use if any of your items are tax exempt, as Hazel cannot reliably calculate what part of that flat discount is taxable if tax-free items were ordered. -- Added %HZI_UNOPTIONED_* fields corresponding to the original SKUID, NAME, PRICE, and WEIGHT values of a product, before it is "optioned." Added %HZI_OPTIONED_NOTES containing a description of the options assigned, and %HZM_VIRGIN_OPTIONED_NAMES which if true prevents Hazel from adding the parenthetical description to an optioned product, allowing the merchant to use %HZI_OPTIONED_NOTES emself. -- One can now pass BATCH_PRODUCT_XYZ and BATCH_QUANTITY_XYZ fields, where XYZ is any unique code (eg. sequences of numbers), and Hazel will interpret each pair as a particular SKUID and its quantity to be added to the shopping cart. If BATCH_QUANTITY_XYZ is missing for its corresponding BATCH_PRODUCT_XYZ, then add one of the SKUID indicated by BATCH_QUANTITY_XYZ's value. -- Added %HZS tokens of the form %HZ{ S_ ~ } which return the sum of all enum_fields in all selected items with an idx_field value which search-engine compares `comp' true with string. For example: %HZS_PRICE~GROUP=books -- Products file field PICKUP_FN is now HZMLified. -- %HZM_MINMAX_ACTIONS should be a semicolon-delimited list of actions in which Hazel should check min/max quantities specified by MINQ/MAXQ. Hazel will always check at CONFIRM and FINISH. -- One can now specify alternate options and products filenames with the %HZM_OPTIONS_FILE and %HZM_PRODUCTS_FILE config fields. -- Added action BACK, which will attempt to redirect to the page from which the shopper actually originated, even if not served by Hazel. If %HZM_RETURN_BACK is true, RETURN becomes BACK and does the same. -- CHECK_EMAIL is a bit more intelligent. -- If %HZI_PICKUP_INLINE is true, Hazel suggests the browser display the softgood in the browser window rather than attempting to download and save to a file. -- The ADD action now HTTP-redirects to the VIEW action once the item is added, avoiding problem with reload adding multiple items. -- HTTP_DOC_ROOT/CGI_BIN are set to their HTTPS counterparts if HTTPS_ALWAYS is set true. -- When dying due to MINQ/MAXQ quantity limits, Hazel sets the quantities to sane parameters, avoiding the need for the shopper to correct them. -- One may now include option weight modification as a semicolon-delimited value after the price mod in your options file. For example: LIGHT:+0.00;+1.00 @ 1kg HEAVY:+0.00;+9.00 @ 9kg -- Added support for a SIZE attribute in all product and note loops which displays only that many (randomly selected) items. If an integer, choose a straight number. If a percent (eg. "75%"), choose that percentage of the total matches. -- If you want to include a pound sign (`#') in a product field value, escape it with a leading backslash. -- CHECK_CCN and CHECK_CCD now occur in line with the rest of the field validation checks. As such, their failure messages are displayed along with other input problems. You may want to edit your CCN_INVALID and CCD_EXPIRED custom.rules fields to fit with this new context. [3.162] -- Hazel products loops accept MIN and MAX attributes, forcing a certain number if iterations. With MIN, iterations over the actual number of available products will use a NULL current product, so all %HZI will come up blank. MAX takes precedence over MIN, so if MIN is higher than MAX, you'll still only get MAX. [3.167] -- Added %HZU_ACTION_NONSECURE, never mutated into its secure counterpart. [3.169] --3.161 Added FORGETME action, which deletes the cookie and any other record Hazel has for remembering the shopper. Primarily for debugging. --3.201 Added new "dump" loop which dumps all input entered by the shopper (and thus stored by Hazel). You can use it to display a list of fields matching a particular pattern. For example, this HZML shows fields which contain "HTTP" in their name, along with their values. %HZH_DUMP_KEY = "%HZH_DUMP_VAL"
As shown, use %HZH_DUMP_KEY and %HZH_DUMP_VAL to retrieve the field name and value. --3.202 %HZ{ S_ FOO } %HZ{ S_ FOO? } Returns sum of all FOO product field values for all selected items. The question mark is optional. %HZ{ S_ FOO ~ BAR } %HZ{ S_ FOO ~ BAR = BAZ } Returns sum of all FOO product field values for all selected items, iff field BAR has a true value or BAR=BAZ. (`=' can be any search comparison character.) %HZ{ S_ FOO ! BAR } %HZ{ S_ FOO ! BAR = BAZ } As above, but reversed logic. Sum if BAR does _not_ exist or does not satisfy the comparison expression. If TOTAL_FOO is used instead of FOO, then the value for each item is multiplied by its selected quantity. All sums are floating point decimal mumbers. (The curly braces are not part of the %HZS tokens per se, but they allow the otherwise illegal characters required by %HZS comparisons.) Use `*' or `TOTAL_*' in place of a field name FOO if all you want is a sum of distinct SKUID or the total items (quantity) selected. If you want the sum returned to be a round integer rather than the default floating point decimal number, use Hazel-Tweak to turn on `RoundSums': If you want floats again, simply set RoundSums=0. --3.204 Hacked the FILE loop to accept new-style SIZE attribute, including percentages. The new style is also much more random than the old. --3.205 Added SIZE attribute support to the WORD loop. --3.205 Added MY_LOGIN hazel.config field: a script called just before Hazel gives up and allocates a new client-id to a visiting shopper. If hacked, it should assign %HZE_* fields for all stored client information. Allows merchants to develop their own customer tracking and data warehousing mechanisms. --3.209 Added a PROXIED_BROWSERS hazel.config field, for semicolon-delimited substrings of user agents known to proxy their requests. Specifically, 'WebTV'! --3.211 Set %HZM_HTTPS_FAITH true if your secure server cannot reliable indicate its secure state via environmental variables. Set this if Hazel switches your URL to their insecure counterpart, even though the request seems secure. (Observed in AOLServer 2.3.2.) --3.213 Hacked so MY_LOGIN is called whenever Hazel fails to find an existing user file, rather than when she assigns a userid. So, the first time a shopper enters (or re-enters) a catalog, MY_LOGIN gets a chance to set some %HZE fields good for the entire session. --3.214 %HZM_MY_LOGIN is now called only when an explicit LOGIN action is issued. That action dies with a LOGIN_FAILURE custom.rules message if %HZH_LOGIN_FAILED was set in the script. Otherwise, succeeds with a LOGIN_SUCCESS. %HZM_MY_WELCOME is now called when %HZM_MY_LOGIN used to be: right before Hazel assigns a new user file to an incoming shopper. Fixed problem with product loops which used both the SIZE and MAX attributes. --3.215 If %HZM_LOGIN_ACTION is set to "checkout", perform the checkout action when a login succeeds, rather than speaking the LOGIN_SUCCESS message. --3.216 Removed support for %HZM_ALLOW_MISSING_SHIPPING_RULES. Now require %HZM_FORBID_MISSING_SHIPPING_RULES to force Hazel to complain about missing rules. --3.217 Added %HZM_MY_BIRTH. See MY_LOGIN notes for 3.214-3.215, but s/LOGIN/BIRTH/. --3.218 A SHIPPING: +XXX will /not/ increment anything shippable, but will force the rules file to be processed for any extra charges. (If only free items are ordered, totals such as COST and QUANTITY will be 0.) --3.219 %HZM_MY_FINISH now accepts multiple semicolon-delimited scripts to be executed when the order completes. (No other MY_* fields support multiple scripts at this time.) --3.220 If %HZM_DOC_DIR_FOLLOWS_THEME is true, then Hazel will look for all served pages in DOC_DIR/themes/THEME where THEME is the currently selected (or DEFAULT_THEME) Hazel theme. --3.222 If %HZM_CLOSED is true, Hazel dies early with a CLOSED custom message or template informing the shopper that the store is currently closed. --3.223 %HZM_MAIL_PATH is now rendered as HZML. --3.224 Hazel-Slurp now accepts an EXEC argument of a script (in your CGI_DIR) which will be called with a single argument of the current shopper's client-id. Its output is inserted into the document at that point. --3.226 Support for %HZM_LOG_FORMAT to set the format of the line Hazel writes to an existing hazel.log file after completing each request. Here is the default format: LOG_FORMAT: %HZM_DATE "%HZE_REMOTE_HOST|%HZE_REMOTE_ADDR" %HZE_CLIENT %HZH_LOG_ACTION_DESC [%HZH_LOG_CART_STRING] (%HZH_LOG_CLOCK seconds; status = %HZH_LOG_STATUS) %HZH_LOG_ACTION_DESC is something like "CHECKOUT" or "SERVE foo.html". %HZH_LOG_CART_STRING is a semicolon-delimited list of SKUID in the cart. %HZH_LOG_CLOCK is the CPU time (in seconds) used for the entire process. %HZH_LOG_STATUS is the exit status of the process. 0 is normal, 1 is error. --3.227 Fixed Win32 softgoods binary pickup corruption. Was a problem with stdout being in TEXT mode by default. Now it is explictly set to BINARY mode, but that /still/ didn't fix it, so further hackery BLAH BLAH fixed now. --3.228 Fixed bug whereby a complex token with trailing whitespace after an embedded HZML token (eg. %HZ{M_ %HZE_FOO }) failed to render properly. Thanks to Mark Clear for the report. --3.229 %HZH_PRODUCT_LOOP_COUNT, %HZH_NOTE_LOOP_COUNT and %HZH_NOTE should be used in place of the counterparts in the %HZM namespace. Added %HZH_PRODUCT_LOOP_TOTAL and %HZH_NOTE_LOOP_TOTAL, set to the total loop iterations after each loop is rendered. Can be used to gracefully deal with cases of no iterations at all, rather than displaying (eg.) an ugly collapsed table. --3.331 Fixed inconsistency with min/max quantities setting the internal quantity selected, but not the %HZI_QUANTITY token. A typo causes us to leap forward in versions to the 3.3 series. --3.332 Fixed bug in rulecmp_weekday wherein the first semicolon-delimited weekday was not being checked. --3.333 Fixed bug whereby an extraordinary discount could plunge the subtotal below zero. The price is ultimated maxed to zero for the final order total, but logic elsewhere in Hazel could have resulted in her looping to her maximum recursive level and halting. Speaking of recursion--prettied up the maximum recursive "loops" message and replaced "loops" with "bodies". Most significant in this build is the addition of the "SSTR" rule comparison type, which allows one to use search specifications in their rules files. Here's an example which handles Canadian postal codes prefixes: [%HZE_SHIP_POSTAL_CODE;SSTR] ^H0M ^J0M ^J0W ^J0X ^J0Y ^J0Z:x2_ @Double Shipping to Somewhere in Canada, eh The only search comparison character which doesn't work is the colon, since that's used to separate the rule from the action. Fortunately, the default search comp char is ":", so leaving out any comparison character will check if any of the space-delimited strings are anywhere within the header value. (How about that paragraph? Serendipitous full justification. Awesome.) --3.334 Added the ability to pass an optioned quantity along with a constructed optioned product. With fields OPTIONED_FOO, use field OPTIONED_QUANTITY_FOO to specify quantity for an optioned product constructed from base SKUID FOO. --3.336 Hacked such that when nonsecure URL appear secure (ie. they begin with an "https://") Hazel will never try to redirect to them from secure mode. --3.337 Fixed bug whereby a line such as "1/2/3" was interpreted as the number 123 by Hazel's search engine, sometimes resulting in failed containment matches. Added %HZH_TOTAL_MATCHES token in search templates, giving the total number of matches for the current search. Most useful when using a custom template with a search, allowing one to split the page into failed and matches content. --3.338 Only check %HZM_CCN_INVALID and %HZM_CCD_EXPIRED if their relevant CREDIT_* fields are required by the current action. Fixes bug whereby shoppers of a site saving those CREDIT_* fields would encounter an infinite loop when trying to correct an improperly entered value. --3.340 If %HZM_REPLACE_EMAIL_HEADERS is true, read initial lines of the e-mail invoice, inserting any headers found into the existing mail headers. Malformed headers (eg. no delimiting colon, or spaces before the colon) will prevent further scanning. Include an initial empty space on any templates for which you want no extra headers added. --3.341 Added %HZM_FLOCK_MAX_TRIES and %HZM_FLOCK_SLEEP_SECONDS to control how many times Hazel attempts to obtain a lock on a file, and how long she waits between attempts. Best not set these unless you know what it means. Warnings are printed in hazel.log (if it exists) when a file lock fails. --3.343 New Hazel-Explode HZML tag: %HZH_FOO1=foo; %HZH_FOO2=bar; %HZH_FOO3=baz; DELIMITER defaults to ";", and PREFIX defaults to "WORD". The prefix is appended with an index for each word in the SRC, and that is used as the %HZH token to represent that word. Arbitrary maximum of 9 words. This actually gives you a way to set variables within a single HZML template, like so: %HZH_MYFOO1=foo; ...but you didn't hear that from me! --3.344 Added processing of a credit.rules file, for credits to an order, applied after the total has been calculated. Use +X.XX to add X.XX credits. Here's some HZML to add to your payment templates (right before the %HZT_ORDER line item) to account for any credits you might want to add: Pre-Credit Total %HZT_UNCREDITED Credits (see notes below) - %HZT_CREDIT --3.346 Added support for a SORT=product-file-key attribute value in product loops which will allow them to be sorted by that key's value. Not optimized for speed. If you experience problems after enabling it, disable it. It is very "alpha" at this point. Don't ask about it, either. In fact, forget you ever read this paragraph. --3.347 Added %HZV namespace, with a resulting in %HZV_FOO equaling "BAR". Hazel-Explode now uses %HZV as its root instead of %HZH. There's no good way to note this in the hazel.log, so I hope you bleeding-edgers are reading this file like good boys and girls! --3.348 Fixed long-standing bugs in fixed-width tokens. %HZ*_NNl_* (lowercase L or R) will now properly avoid truncating the full length of the token if NN is less than its total length. Also, a right-justified token with a length less than the width (eg. %HZM_04R_CAT_DIR) will properly use the /last/ four characters of the token. --3.349 Added for stripping a set of characters from a string. --3.350 Much code cleanup, and gutted some ancient code supporting extinct URL such as %HZU_ATS* %HZU_SECUREPAY* and more. Likewise with %HZM_{ITEM,NOTE}_LIST. --3.351 Give a passed cookie client precedence over a passed client-id. Re-call MY_WELCOME if Hazel chokes on a client-id. --3.352 Erase all client data read from a userfile if Hazel chokes on a client-id. --3.353 Don't complain about any mismatching browser if the remote address of the shopper matches that stored. Added support for VARIABLES, HAZEL, and TOTALS as root attribute values for the Hazel-Dump tag. --3.354 Added %HZT_CREDIT_REMAINING, representing credit remaining on a coupon. --3.357 Default format for template names is now %s.html. If you have a very old catalog, rename all your templates from hazel_*.html to *.html. Removed support for CLIENT_MEMORY field. Use SUBST_FORMS:1 and SUBST_LINKS:1 instead of "subs", and REMEMBER_HOSTS:0 if you want to turn off the addr.db method Hazel uses to track client state. Removed support for HAZEL_KEY, HTTP_DOC_ROOT_SECURE, and HTTP_CGI_BIN_SECURE fields. Use {HARDGOODS,SOFTGOODS}_KEY, HTTPS_DOC_ROOT, and HTTPS_CGI_BIN. If ARGH_NOWUSER is sent to Hazel, she won't write the user file during that session. The Dump loop now recognizes URL and ARGH roots. There are now %HZU_*_NONSECURE versions of all Hazel URL, in addition to ye olde %HZU_ACTION. --3.358 The OPTIONS field now supports semicolon-delimited option groups, representing the allowed namespaces for that product's options. If an OPTIONS field is present, its option codes /must/ fall within those named groups. --3.359 The value of a product's DTEMPLATE field will be interpreted as the basename of a template in hazel-cat/templates/custom to be used when that product is the item of a detail action. Similiarly, the value of a product's MTEMPLATE field will be interpreted as the basename of a template in hazel-cat/templates/custom to be used instead of the search/matches.html template, if and only if /all/ matching products have the same MTEMPLATE value. NOTE: All passed templates are now searched for in hazel-cat/templates/custom, instead of the root templates directory. If you don't want to move them to the custom subdirectory, define %HZM_FLAT_PASSED_TEMPLATES true. Hazel now recognizes an (eg.) action=SEARCH_AGAIN in addition to the SUBMIT_ACTION_SEARCH_AGAIN and action=SEARCH&item=AGAIN methods. Added SEARCH_ACTION_MAX to return all possible matches, ignoring any [DEFAULT_]SEARCH_MAXHITS restrictions. --3.362 All %HZM_RESTRICT_* and %HZM_SLIDE_* fields are now unused in favor of a more logical scheme for detecting browsers mistakenly trampling over existing user files. %HZM_CAUGHT_CLIENTS_CHOKE also unused. Only Hazel herself (as defined by %HZM_HTTP_CGI_BIN and %HZM_HTTPS_CGI_BIN) and those referers in the semicolon-delimited URL prefix list in %HZM_ALLOWED_REFERERS are allowed to pass `client' field values. This will hopefully prevent overly verbose bookmarks from resulting in user trampling. New [MIVS] header in field.rules allows one to define input field names for which "Multiple Input Values" are allowed to be stored. For example, a line such as "FOO:;" and an query string such as "hazel.cgi?FOO=1&FOO=2" results in Hazel saving "1;2" as the value for FOO. Delimiters can also be specified as their decimal ASCII values. For example, "FOO:32" means use a space to seperate multiple values. --3.363 Fixed bug of the "cosmetic" kind in which %HZE_SEARCH_SPEC would sometimes be set to "?x=1" due to something too complex to explain here. --3.366 Replaced internal reference of %HZM_DATE which was causing a warning of it being obsolete. :/ Deprecated %HZM_ORDER_SEQ in favor of %HZH_ORDER_SEQ. Removed support for a lot of ancient (now defunct) payment methods, and case-insensitivity support for payment methods such as STANDARD, COD, and PRINTOUT. Shouldn't affect anyone, but if you were running an ancient 2.x or earlier catalog, upgraded, and now get "template not found" errors at confirmation, make sure your payment method names are lowercase. --3.36601/3.370 Fixed occasional problem with mixed secure and nonsecure items. Now all Hazel URL will be switched to their secure counterparts whenever a session is served securely, regardless of the value of SERVE_SECURE. --3.371 The `*' option modifier now multiplies all percentage option price/weight modifiers together to come up with the final calculation. `+' still adds them all together, as before. --3.372 Case is now properly insensitive for an OPTIONS field. Whoops. --3.373 Fixed bug whereby SERVE_SECURE might linger, causing %HZU to switch to their secure counterparts when such is not desired. Now forces %HZE_SERVE_SECURE to NULL if !%HZH_HTTPS. --3.375 If ENABLE_ADD_REDIRECT is true, Hazel will HTTP-redirect to the VIEW action. This prevents shoppers from `accidentally' reloading a shopping cart view and adding an additional quantity of an item. Unfortunately, it sometimes causes problems with the caching mechanisms of some browsers, and with Hazel's client-id checking, so it's off by default. Pick your poison. Available as of 3.375. Previously, redirecting was the default, and DISABLE_ADD_REDIRECT disabled it. There are more problems with the redirection than without, thus this reversal, and DISABLE_ADD_REDIRECT's obsolescence. --3.376 A softgoods PICKUP_FN can now reference itself via %HZI_SKUID, which enables one to access optioned softgoods named after their own SKUID. --3.377 Added LOOPNAMES block to custom.rules which allows Hazel to use the data in your loops to determine the `pretty' name of a field. Here is the default block: ----------cut---------- # The LOOPNAMES block tells Hazel to interpret values from the given # loop file as containing 'value;pretty-name' lines where if %HZE_FOO # has a value of 'value', %HZE_FOO_NAME will be set to 'pretty-name'. [LOOPNAMES] SHIP_METHOD:ship_methods.txt PAYMENT_METHOD:payment_methods.txt BILL_COUNTRY:countries.txt BILL_STATE:states.txt SHIP_COUNTRY:countries.txt SHIP_STATE:states.txt [/LOOPNAMES] ----------cut---------- Also, loop text is now cached so they're only ever loaded once per session. If %HZM_DOC_ROOT_FOLLOWS_THEME is set true, Hazel will append 'themes/THEME' to all %HZU_DOC_* URL, where THEME is the current (or default) theme. --3.378 Added support for all rulecmp types (DATE, WDAY, etc.) in tax and shipping rules files. Added special support for an %HZM_HTTP_RECEIPT_EXPIRES config field which specifies a special expiration time for the final receipt page, allowing it to be printed without defective browsers complaining that the post data has expired. Defaults to 300 seconds (5 minutes), and can be set to 0 to turn it off entirely. Added support for a Template attribute in Hazel-Slurp, which causes the SRC file to be read from hazel-cat/templates rather than hazel-doc. --3.380 %HZE_REFERER no longer chops off the query string bit of the URL. Hazel-Choice (and True, False) evaluates numbers as floats rather than integers, allowing more precise comparisons. --3.383 Fixed bug wherein a search on an SKUID would never match the final product in the products file. --3.384 The value of a custom TEMPLATE field sent to a search action will be ignored if the search fails, allowing the proper search/failed.html to be displayed. --3.386 Added SEARCH_SPEC_MISSING custom.rules message for display when no search specification is sent. --3.387 Use %HZM_ORDER_SEQ as the next serialized order number if it is larger than the one stored in hazel-cat/users/orderseq.txt. --3.388 Hazel's accounting of whether or not there are %HZH_SEARCH_MORE matches should now be correct. --3.391 If default search fields are assumed and the AND logic is used, require that all given words are present in any one of the fields, rather than requiring them ALL in ALL fields. Makes searches more `natural' for humans. Next step is to allow a match where all words are present across any number of the fields, rather than just in one. --3.392 Added MPRICING product field, recognized as similiar to a DISCOUNT field for volume discounts, but Hazel doesn't look for the /lowest/ price, instead taking whatever's given. Not ready for prime time. --3.393 The BATCH_QUANTITY_* fields (for their BATCH_PRODUCT_* counterparts) now recognize +N and -N values, for inc/decrementing product quantities. --3.394 HZML and HZM are now value servable extensions by default. sets the current product context to the last item in the cart. Useful for doing "Related Products" lists in your view template. New %HZD tokens of format %HZD_[PF]n[SMHDLY]. P/F is for Past or Future, n is a number, and S-Y stand for Seconds, Minutes, Hours, Days, (L)unar months, and Years. The format returned is YYYYLLDDHHMMSS if a unit less than days is given, and YYYYLLDD if days or greater are used. For example, used today, 25 April 2000, %HZD_P0D would return 20000425. %HZD_F1D would return 20000426, %HZF1Y would return 20010425. Get it? --3.395 Added . Tightened up %HZM_CHECK_CCN check for valid credit cards. Previously, ignored any non-numeric characters. Now, reject a card if it contains anything but numbers, spaces, and dashes. Explicitly check for valid characters in an e-mail address if %HZM_CHECK_EMAIL. --3.397 Added %HZM_CUSTOM_SEARCH_FAILED. If set, always serve a passed custom template for search actions, even if the search produced no results. --3.402 On NT, if MAIL_HOST is false but MAIL_PATH is true, try to use a local program to send mail a la the Unix version. Not reliable. If the SORT attribute begins with +/-, ascend/descend the sort. Default is to use ascending order. Support for an %HZM_MAXIMUM_ORDER, with a MAXORDER custom.rules explanation. --3.405 Sending e-mail invoices is now the last thing Hazel does. Printing an HTML receipt is more important, particularly when using online payment methods. --3.406 Loose AND behaviour only if %HZM_SEARCH_PARAND is true. If you have multiple default search fields with AND logic and searches appear to be failing now, try setting SEARCH_PARAND:1 in hazel.config. --3.408 Added %HZH_FILE_LOOP_COUNT and %HZH_FILE_LOOP_TOTAL. --3.409 Deprecation warnings are no longer printed to hazel.log. Touch a hazel.dep if you want to see them. Also, API_LOG messages now show up in a hazel.bug file and not the standard hazel.log file. Should cut down on spam in the primary hazel.log logfile. --3.410 Added CONFIRM as possible %HZM_LOGIN_ACTION. --3.411 The suggested filename for a softgoods pickup now deletes any leading path info, giving only the final filename itself. --3.412 Check credit card length when deciding whether or not to invalidate a card number in accordance with %HZM_CHECK_CCN. --3.413 Added a %HZM_MY_CONFIRM API action hook, called at the confirm stage. --3.415 Win32 Hazel respects a %HZM_MAIL_PORT for a custom SMTP host port. --3.416 Added code to write a stdin/stdout file in Win32 to compensate for its lack of proper pipes, or our lack of Win32 hacking expertise. --3.417 If %HZM_ALLOW_UNKNOWN_USERS is true, allow a passed client-id even if no associated userfile exists. Otherwise, force assignment of a new one, preventing some occurences of conflicting client-id. --3.418 If %HZM_PARANOID_REFERER_CHECK is true, re-assign a client-id for any referer which appears not to be from Hazel. This includes the domains in HTTP_* and HTTPS_* config fields, and the semicolon-delimited ones in the %HZM_ALLOWED_REFERERS field. --3.419 Added %HZM_PROXIED_SUBNETS for semicolon-delimited IP-address subnets which are known to be proxies for AOL, etc. --3.421 Added a secure token to be passed when Hazel switches from insecure to secure mode, to prevent Hazel from incorrectly rejecting a client-id in that precious moment where someone is not sending a cookie when they had been before, in nonsecure mode. --3.422 Fixed so %HZH_FILE_LOOP_COUNT starts at 1, not 0. --3.425 Added block to check for %HZM_LOCKED_FINISH. If true, nuke everything saved and passed and accept only %HZE_FINAL_PRODUCT_* as the sets of cart items and their quantities. Added %HZM_HZML_PRODUCT_FIELDS. Its value should be a semicolon-delimited list of product fields which should be run through the HZML interpreter after they are read from the products source. --3.426 Removed hard `WORD9' limit to %HZH_WORD* counts in file loops. --3.427 Fixed BUG in which Hazel-Date would sometimes fail to properly render certain date tokens as per strftime. --3.428 Fixed long-standing BUG in DETAIL action in which Hazel added the item being detailed to the selected loop with zero-quantity. --3.429 Backported Hazel-Math from H4. Docs from the C comments: /** Perform mathematical manipulations on the given VALUE as specified by each attribute with a name prefixed by "OP". Operations should be of the form "+XXX" where `+' can also be `-', `/', `*' or `%'. (You can use `x' or `X' for multiplication, as well.) The result is stored in the %HZV_* dictionary under the key specified by RESULT. (By default, %HZV_RESULT.) For example: 100 x 0.20 = 20 20 + 50 = 70 So, finally, we get `70' in %HZV_RESULT. To force the result into a floating point number, add Type=FLOAT as an attribute to the tag. This is very important when you want (for example) an exact result for a division operation. */ Here's a usage example from one of our Hazel customers: --------cut-------- My equation is to compare list price vs. our price and show the percent off savings that we offer customers with our price. The equation is: (1 - our/list) * 100 = % off In our products file I have defined recurring fields LIST_PRICE and OUR_PRICE and given them values for different products. I use the following code: You Save: %HZV_RESULT! --------cut-------- --3.436 Added support for %HZM_REQUIRE_COOKIES, requiring a cookie to identify the shopper in all but the case of a client-id passed on the cmdline. Added bake_multidomain_cookie in client.c to send cookies for both secure and nonsecure servers. Semicolon-delimited URI in %HZM_EXTRA_COOKIE_DOMAINS will be parsed as HTTP_CGI_BIN/HTTPS_CGI_BIN and hazelcookie (and any future Hazel cookies) will be sent for those domains, as well. If adding domains, remember the Netscape cookie spec: http://home.netscape.com/newsref/std/cookie_spec.html It requires at least two periods in a domain name. So, if you wanted to include all subdomains within your domain example.com, you would use a URL such as http://.example.com/ with the initial period. http://example.com has only one period, and thus would not work (at least in Netscape.) Now you've been saved the trouble I debugged for a day! Gah! --3.437 Fixed bug with Hazel-Math and a default RESULT. --3.438 Added support (from H4) for a generic (no TYPE attribute) Hazel-Loop. --3.439 More backporting from H4, this time to the get_query_string CGI function. --3.440 Backported HAZEL_ERROR_LOG, HAZEL_COMMON_LOG, HAZEL_DEPREC_LOG and HAZEL_DEBUG_LOG hazel.config fields, allowing one to specifying a file to which Hazel will write log messages of each class. For example, if you want to dump everything into hazel.log, add these lines to hazel.config: HAZEL_DEBUG_LOG:hazel.log HAZEL_COMMON_LOG:hazel.log HAZEL_ERROR_LOG:hazel.log HAZEL_DEPREC_LOG:hazel.log --3.441 Fixed bug in Hazel-Choice "SNI" attribute. Copy-n-paste casualty was duplicating behaviour of SIN. --3.442 Backslash-escaped `#' character now allowed in hazel.config. Hazel will now always cook a no-domain no-path cookie in addition to any others she sends. --3.443 Use \r and \n as internal CR/LF tokens instead of octal codes. Relevant on 64-bit platforms. --3.444 Many changes to state-tracking backported from H4. --3.445 Added ' as a valid email username character. --3.446 Backported new and improved state-tracking mechanism from H4. --3.447 Set %HZT_SHIPPING just before calling rules, so the rules file has a value for the shipping charges computed thus far. --3.449 Set %HZM_PENDING_ORDER_FILE_AGE, same values as USER_FILE_AGE, to control purging of saved nascent orders in hazel-cat/pending. --3.450 Possibly the good right and proper state tracking fix to end all fixes. Added support for hazel-cat/rules/tweak.rules. Here's an example: ------------tweak.rules------------ ## tweak.rules ## Rules for tweaking product info right after Hazel reads their data ## from the standard source. ## -- ## quinn@netsville.com SKUID:%HZI_SKUID NAME:%HZI_NAME (%HZI_SKUID) ## End. ------------tweak.rules------------ It'll reset all your product names to include a parenthetical indication of their SKUID. Of course, that isn't useful. It's stupid. However, the tweak rules themselves are nice for setting weird discounts based on quantity ordered, quantity from a particular group ordered, some code passed to Hazel, and so on. Lots of fun. Yep. Good times. We have fun. --3.451 Some bug fixes to the SIZE=x attribute for random loop picks. --3.452 Made tweak.rules actually work. It was aborting early if there was no MY_PRODUCTS_TWEAK, dammit. Now it should work as described up in the 3.450 update. Big fix for win32 users. Changed the way Hazel determines whether or not she was called from the cmdline. Sometimes NT sends an extra argument to the CGI *argv[], and Hazel thought it was a command line argument, and thus trusted it more. She doesn't do that now. Could fix some state-tracking problems. --3.453 Preliminary support for a rules/header.rules for adding extra HTTP headers to Hazel's response. Each line is an HTTP header to be sent. --3.454 Shined and buffed the header.rules handling. It now strips comments, then splits each non-whitespace line in the HZMLified header.rules into key:value pairs and then outputs the headers. Should fix problems people encountered when they (understandably) added their header.rules with comments. --3.455 Added purge_pending_orders to the explicit action=CLEANUP. Bumped up default PENDING_ORDER_FILE_AGE to a week. 20020304;3.456 If Hazel-Date and Hazel-Currency are passed a Result="vkey" attribute, they'll write their output there instead of to the document. 20020311;3.457 Hacked state.c to forgive no cookie when REQUIRE_COOKIES and STORED_COOKIE is SECURE_COOKIE_SWITCH_TOKEN. Bugfix hzml.c::parse_HZML_Token_Expression; bad `sl' expression after strduping the passed token. 20020313;3.458 Fixed possible buffer problem in store.c::write_session_log_line which used the string itself as the format for hzlog. 20020319;3.459 Added support for %HZM_DISABLE_USERFILES to prevent any reading or writing of user files. With %HZM_BAKE_USERFILE and %HZM_REQUIRE_COOKIES, this enables operating Hazel without ever writing any userfiles, which basically means everything is stored client-side and we rock ass. You should be very careful using it, though. If your clients don't use cookies, or you don't have a P3P policy and the browser thinks they don't want cookies, or whatever the hell else, they won't be remembered. 20020321;3.460 No longer require matching products be sequential in the GROUP loop. Changed config SEARCH_PARAND to DEFAULT_SEARCH_PARAND. No option for passing SEARCH_PARAND per-search. 20020327;3.461 Hacked set_client_http_data and transfer_env in client.c to rearrange which HTTP reference fields are saved to which namespaces. Only %HZE_ORIGIN is now written to %HZE, with a synopsis of the originating values. The other fields are copied from getenv to %HZH. Hacked hzml.c to support deprecated %HZE tokens above. Backported support for a templates/welcome.html template. If present, will be displayed to any shopper deemed to be "new." Set %HZH_READ_BAKED_USERFILE in state.c if info was read from the cookie. 20020328;3.463 Added %HZT_TAXABLE calculation for the taxable order amount. 20020424;3.464 Added %HZH_WORD_LOOP_COUNT/TOTAL. Re-write of the "choices" mechanism which should result in truly random and proper SIZE results in word, file, and product loops. Also added a SCRAMBLE attribute for said loops to randomize all available choices. 20020507;3.465 Fixed bug in get_template_pathname which would use a passed template even in a Hazel-Slurp Template Src="..." element. 20020509;3.466 Possible fixed discrepancy between handling of SUBMIT_ACTION_ for actions with and without items. 20020514;3.467 Re-added SHOPPER_ID and BROWSER_ID unless %HZM_MINIMAL_USER_FILES. 20020528;3.468 Argh-- backed out SUBMIT_ACTION_ "fix" -- BAH! It's there to allow FINISH_FOO to get through without stripping FOO and making it the ITEM. 20020529;3.469 Fixed problem with MIN=x doing an extra iteration in product loops. 20020603;3.470 Don't print a cookie w/out path and domain if we've already managed to print cookies. When not sending a path or domain, Mozilla seems to interpret the path as the whole URI, including the query string. One can still include whatever one wants by adding EXTRA_COOKIE_DOMAINS or COOKIE_DOMAINS to the config file, with semicolon delimited URL. 20020612;3.471 Added "All" attribute for simple product loops, to show every damn product in the catalog. Good for default start.html catalog. It is checked before GROUP, so we can use both, and Hazel will prefer "All" if the merchant has a newer binary, and ignore it if not. 20020617;3.472 cgi.c::rewrite_multiple_input_values fixed to leave an %HZE untouched if it has no DICT_MIVS entry. 20020715;3.473 Changed default log format to use %HZH_REMOTE* instead of %HZE_REMOTE* fields. 20020716;3.474 Fixed bug with scrambled_choices and choose_all. Return early with NULL if total or choices are < 1. 20020717;3.475 Fixed cgi.c interpretation of HTTP_EXPIRES to jibe with documentation, ie. -1 means don't send any Expires, Cache-Control, Pragma headers. 20020718;3.476 Complex tokens now get &, ", <, >, \n, \r, and \t properly quoted, ready for an HTML form input value. 20020724;3.477 Changed test action email to test@fazigu.org. 20020828;3.478 Hacked client.c::save_invoice to use FILE orders_db_format if a hazel-cat/orders directory exists. 20020907;3.479 Hacked search.c::get_spec_words to determine if a single-quote is actually intended as an apostrophe. 20020910;3.480 Backported new state machine from H4. 20020919;3.481 Whoops, missing break in quote_html_specials caused & to be inserted for any non-space whitespace. Respect RAW_COMPLEX_TOKENS. 20020920;3.482 Call my_roundup on the float being compared in rules.c::rulecmp_num, to prevent (eg.) 3.005 from matching 1-3.00 even tho it is rounded to 3.01 in display. 20020923;3.483 Mighty bug fix in state.c::inspect_cookie_client. Check for a NULL return from Hazel_extract_encapsulated_client_id before the strchr for a textclient! 20020923;3.483 Mighty bug fix in state.c::inspect_cookie_client. Check for a NULL return from Hazel_extract_encapsulated_client_id before the strchr for a textclient! 20021003;3.484 More backported state changes: (1) adjust is_newbie in hazel.c for new way of assigning client-id, (2) re-integrated support for baked userfiles. 20021028;3.485 Don't set BILL_EMAIL in actionTEST. Force the tester to enter that item. Defaulting to test@fazigu.org is silly and bounces, and defaulting to STORE_EMAIL might creep out merchants. 20021108;3.486 If DISABLE_HOURLY_PURGES, don't purge files more than once a day. 20021109;3.487 Hazel_cookie_domain now returns the full domain if the top-level is numeric. Fixes bug with Hazel asking a cookie be saved for domain (eg.) 173.205. 20021111;3.488 Properly handle IP addresses in state.c::Hazel_cookie_domain. 20021119;3.489 Backported Hazel_Capitalize* funcs to text.c. Backported Hazel-Subst. 20021210;3.490 Added TAX_SHIPPING and TAX_SUBTOTAL hazel.config fields. Fixed case-sensitivity issue in Hazel-Explode PREFIX attribute. Fixed bug with MOD=0 in Hazel-Choice. Got rid of remaining strcpy calls, including a fix in search.c for MAX_SKU_LEN. 20021223;3.491 Added welcome to hardcoded get_template_pathnames. 20021224;3.492 Uh...nothing? 20030120;3.493 Backported %HZH_SEARCH_SPEC and %HZH_SEARCH_SPEC_WORDS, with routines for building each value in new canonical_search_spec_string and canonical_search_spec_words_string. Hacked get_spec_fields to determine word-searchedness before the loop to strip the search subject. Within the loop, first check for wordsearch, and if so, either replace a tilde or verbatim copy the character. This fixes a bug wherein something like "world's fair" would never match because the apostrophe was being removed. It was being preserved earlier, but the "stripping" loop within get_spec_fields was lazy-- it only replaced tildes with spaces, and not other punctuation which may have been preserved. Tough bug to track down-- it wasn't present in H4, but H4 got rid of get_spec_fields, so a simple diff didn't uncover it. 20030203;3.494 store.c: Hacked get_template_pathname to prevent un-fn_safe files from ever being served. Fixed problem pointed out by the great Tom Woozle, all hail! 20030206;3.495 text.c: Added '/' substitution to quote_html_specials. 20030207;3.496 hzml.c: Added Hazel_HZML_output_error to handle creation of comments spat out by certain HZML rendering routines. Additionally, it writes an %HZH_ERROR with the guts of the problem. Eventually, it'd be nice to get rid of the comments altogether. At least now they're centralized and we can return a dup'd empty string later. 20030210;3.496 hzml.c: Backported %HZH_LINE to file loops. 20030312;3.497 hzml.c: Backported COOKIEDATES tweak. Grr! 20030414;3.498 Added location of hazel.config to commented SHOWREG_CONFIG area in SHOWREG. 20030415;3.499 Damn. text.c::quote_html_specials was not quoting unless there were quotable punctuation characters. Thus, it would not quote whitespace. ARGH. (Fixed.) 20030422;3.500 Removed mention of actual filepaths in CLEANUP action. Subject DEBUG and SHOWREG actions to a maybe_disallow_cmdline_action check, so that they may be disallowed via CMDLINE_ACTIONS config value. Fixed a few unused variable and other warnings with -Wall -ansi -pedantic. 20030508;3.501 Pass TEMPLATE when redirecting to secure or nonsecure. 20030513;3.502 hzml.c: Upped GROUP_LOOP_MAXHITS to 1,000,000, and hacked render_HZML_Query_Loop to use GROUP_LOOP_MAXHITS as its default max. text.c: my_srandom uses getpid as its base seed rather than the time in seconds. 20030813;3.503 Added Hazel_writable_userfiles to check both DISABLE_USERFILES and ARG_NOWUSER when determining whether or not Hazel can write userfiles. Added that check to client.c to prevent writing the "reserved for" lines in these cases. 20030908;3.504 Backported HzSt02 state-tracking device. 20031003;3.505 Fixed bug with loopnames wherein (eg.) INTL would use the loopnamed value for IN as its pretty name. (stribeg used, was too loose.) 20031118;3.506 cgi.c:: Added FORM to URL which are converted to secure versions when redirecting to secure site. 20031119;3.507 Use FORM_SECURE to redirect to secure server, rather than ACTION, which could have been truncated of its pathinfo if a cookie was recognized. 20031119;3.508 Added "Result" attribute support for Hazel-Email, Hazel-API, Hazel-Slurp, and Hazel-Belch. Added alias "Value" for "Src" attributes in Hazel-Strip, Hazel-Explode. 20031230;3.509 Added DISABLE_PICKUP_REDIRECTION to, well, disable redirection in action=pickup to a URL ending with the actual filename. 20040113;3.510 Added %HZI_PICKUP_URL to initialized pickups, using new Hazel_pickup_url_extended to give what redirect usually shows. (Could be a problem for anyone who has embedded an explicit PICKUP_URL field in their products file.) Fixed bug in HzSt02 mechanism where (null)(null) was used-- needed revised min/max base encoding in text.c. 20040207;3.511 Hack for sf1000.registeredsite.com which doesn't identify itself as secure by the usual methods. Set HTTPS_IF_URL_SAYS_SO:secure, make a "secure" link in cgi-bin to the same cgi-bin, and use that as HTTPS to know when we're secure. 20040210;3.512 Fixed text.c::my_vsnprintf to copy cooked string a maximum of `size' characters and not `maxlen' (the internal buffer limit.) 20040212;3.513 Fixed pointer trespass in variables.c::to_fields which would cause a crash when an opening HZML tag ended in a boolean attribute (without a value) followed by a single space. Crikey, that to_fields code is scary. 20040324;3.514 A lot of futzing to cross-compile H3 for Windows. Worked fine on H4, but H3 uses a new build system. Gargh. Changed all refs to atoi to atol in a futile attempt to fix a compiler problem of undefined _toi symbols. Gargh. 20040707;3.515 Backported SUBST_HIGH_BASE support to hzml.c.