DOCUMENTATION WebAdverts 3.10 by Darryl C. Burgdorf (burgdorf@awsd.com) http://awsd.com/scripts/webadverts/ =========================================== WebAdverts is a comprehensive system for maintaining a set of rotating banner ads on your site or for setting up a "banner exchange" between your site and others. Banners can be displayed on your pages via JavaScript, IFRAME, IMG or SSI tags. (Banners may also easily be included on CGI-generated pages.) Multiple "zones" can be established, allowing certain banners to appear only on certain pages. WebAdverts keeps track of exposures and click-thrus for each banner, as well as of the average total number of exposures per day. Individual passwords allow each of your advertisers to view their own advert stats (overall and daily) without viewing anyone else's. Banners can be "weighted" to control how often they are displayed, and can automatically be expired from the rotation after a designated number of exposures, click-thrus or days. WebAdverts is shareware. If you use it, please register it! The registration fee is only $50 (US). Payment should be sent via check or money order to Darryl C. Burgdorf, Affordable Web Space Design, 3524 Pacific Street, Omaha NE 68105. =========================================== The files that you need are as follows: ads.pl: This is the script you call directly, in order to display banners on your HTML pages. ads_display.pl: The script which actually handles the banner displays. It is referenced by the ads.pl script; you don't need to call it directly. ads_admin.pl: The administrative maintenance script. With this script, you can add, edit and delete accounts. It also allows you (and your advertisers) to check on how well your accounts are performing. ads_settings.pl: The configuration script containing the majority of the configuration variables used by both the administrative and the display scripts. ads_rebuild.pl: This script is called when needed by the administrative script. You don't need to call it directly or modify it in any way. ads_text.pl: This script contains the text passages shown by the administrative script to your advertisers or exchange members. They are separated from the administrative script to make editing or translating easier. Note that this document does *not* include some of the text passages seen only by you, the administrator, and not by your advertisers or exchange members. =========================================== SETTING UP WEBADVERTS: Setting up the script is quite easy. You'll first need to set up a directory to contain your data files. Make sure, of course, that it is set world-writable ("chmod a+w "). You can put the scripts in that same directory, if you like, or in another directory; the latter is to be prefered, though, for security reasons discussed below. (On some servers, you'll have no choice; it may be that your scripts *have* to be in your CGI-BIN directory, in which case your data files *must* be elsewhere, since storing data files in your CGI-BIN is a *very* bad idea.) Make sure that the first lines of your ads.pl and ads_admin.pl scripts point correctly to the location of Perl on your system, and be sure that both those scripts are set world-executable ("chmod a+x "). The other scripts do *not* have to be executable, nor do they need the line pointing to Perl's location, since they won't be called except from other scripts. In the display config script (ads.pl, or whatever you've renamed it), define the following variables: $settings_path: The full server path (not the URL) of your ads_settings.pl script. $display_cgi: The URL (not the path) of your ads.pl script. If you are using multiple copies of the ads.pl (possibly to define a set of zones), each of those scripts should point this variable to itself. $advertzone: The "zone" (category) of banners which should be shown when this script is called. Even if you're using zones, it isn't actually necessary to define this variable, since (unless you're calling banners via SSI tags) the banner calls themselves can specify a zone. For more information on setting up and using zones, see the "zoning" section of the documentation, below. In the admin script: $settings_path: This variable is precisely the same as the variable defined in the ads.pl script, and should be defined in the same way. $text_path: The full server path (not the URL) of your ads_text.pl script. $rebuild_path: The full server path (not the URL) of your ads_rebuild.pl script. The bulk of the configuration variables are, of course, found in the ads_settings.pl script. The first set affect the actual display of banners: $display_path: The full server path (not the URL) to your display script (ads_display.pl). $adverts_dir: The full server directory path (not the URL) to your adverts data directory. Note that this directory does not need to be -- and in fact should *not* be -- the same directory within which your scripts are contained. For security purposes, this directory should be password protected or (better yet) inaccessible to Web browsers. (You need to make sure that visitors can access your ads.pl script, of course, but nothing else needs to be directly accessible!) $ADVUseLocking: Under most circumstances, this variable should be defined as 1. Set it to 0 only if, for whatever reason, your server doesn't support the flock() command. (If this variable is set to 0, a semaphore-based file locking will be used instead of flock(); while it works reasonably well in most situations, it isn't nearly as efficient.) $ADVUseCookies: Cookies are only relevant when banners are called via IMG tags, which in general, will only be the case if no better option is available for a particular visitor. Even so, the number of IMG tag calls could be significant, so the efficiency of those calls should be considered. This variable determines whether browser-based "cookies" or a data file on your server will be used to keep track of which visitors have seen which banners. If you set it to 0, the script will not utilize cookies. That's bad. Unless you have a *VERY* compelling reason to do so, you should *never* set $ADVUseCookies to 0. Using cookies is *much* more efficient than constantly updating and reading a file on your server. Turning off cookie support *will* result in a noticeable increase in the load on your Web server, especially if you're running a busy site. $CheckForCookie: If you set this variable to 1, then the script, before displaying a banner and "blindly" setting a cookie, will set a "dummy" cookie in order to be sure that the visitor's browser is actually set to utilize cookies. For those visitors who can't or won't utilize cookies, the script will "fall back" to storing data in a file on your server. Performing this check will result in a slight increase in the work your server is doing, though it still won't be working as hard as if cookies are turned off. On the "up" side, though, use of this check will ensure that *all* of your visitors, whether they allow cookies or not, will be able to click on your banners successfully. (Without this check, the script will simply have to assume that cookies are being set, which means that visitors who can't or won't allow cookies will get error messages when they click on your banners.) $GraphicTimestamp: If you set this variable to 1, the URL of each banner sent by the script will include a "timestamp." (In other words, rather than appearing in the IMG tag simply as "banner.gif," it might appear as "banner.gif?968429321" instead.) This will *not* in any way affect the browsers' ability to display the images; however, it *will* "fool" the browser into thinking that repeated displays of the same banner are actually displays of distinct banners, and thus force the browser *not* to reload the image from cache. Unless you have advertisers who want to be able to count "pulls" of their banner graphic for comparison to WebAdverts' reported exposure count, though, you should probably leave this variable undefined, as it will just result in wasted bandwidth. (Note that WebAdverts' count will likely be slightly higher than the "pull" count, in any event, since WebAdverts counts the number of times it sends an IMG tag to a page, and has no way of "uncounting" people who don't load graphics and/or who use "banner-blocking" software.) If you want to include such timestamps in the URLs of only a few of your accounts, instead of setting this variable, you can simply add "" in the URLs, where you want WebAdverts to insert the timestamps. $ADVLogIP: If you set this variable to 1, WebAdverts will maintain running log files of the IP addresses which have viewed or clicked on each banner. Keeping these logs allows account holders to keep an eye on how many different people are viewing their banners, and also allows the administrator to keep an eye out for exchange members or others attempting to "skew" their account stats by repeatedly loading or clicking on banners. $ADVResolveIPs: If your server provides you only with raw IP addresses instead of with resolved domain names, you can set the script to resolve IP addresses for you. This will allow domain names rather than just IP addresses to be seen in the IP log files. However, if your site is even remotely active, utilizing this capability is *not* recommended, as in the final analysis, it's a rather useless drain on system resources. $DupViewTime: If you want to prevent multiple exposures of a single banner to a single visitor from counting against that banner's total, set this variable to the minimum number of minutes which must elapse between counted views. For example, if you set it to 5, once a given visitor has seen a particular banner, further showings of that banner to that visitor will *not* be counted by the system until at least five minutes have elapsed. Normally, this variable should be left at 0, both for reasons of improved efficiency and because most of the time you won't *want* to "undercount" your exposures. However, if you are running an exchange, and have problems with members trying to "inflate" their statistics, and don't want to be bothered having to spot the abusers manually and put them on a permanent "ignore" list, this is the next-best solution. $DupClickTime: This variable works exactly the same as the $DupViewTime variable, only it determines how many minutes must pass before a second click-thru (rather than a second exposure) will be counted by the system. $ClickViewTime: This variable is yet another variation on the same theme, and determines how many minutes must pass after a visitor clicks on a banner, before another *exposure* to that visitor will be recorded. $LogByZone: If you set this variable to 1, when you (or your account holders) view an account's stats, you'll be able to view a breakdown of how the banner is performing in each zone (or on each member's site). The bookkeeping overhead isn't too terrible, but if you're running a very large exchange, the data files might start getting large, which could cause minor slowdowns. $ADVRandomizeList: Setting this variable to 1 will instruct the script to "randomize" the order of the accounts in your rotation list every 12 hours. This can be handy, especially if you have advertisers with multiple accounts, as it will ensure that banners aren't always seen in the same general sequence. $DefaultBanner: You can, if you choose, define this variable with the name of one of your accounts. If you do so, that account's banner will be displayed at any time when (for whatever reason) the system isn't able to find an eligible banner via the normal routines. Note that this assignment is far more useful in banner exchanges than in straight advertising setups. Note also that if you've set up your accounts correctly, and have at least one account which is *always* eligible for display -- in other words, if you've got at least one account set with a weight of 1, which is *not* dependent upon reciprocal displays to "earn" exposures -- then this variable will never even be referenced. To be blunt, it exists solely as a "CYA" for administrators who don't bother to set up their exchanges properly. $IgnoredIPs: You can enter a list of IP addresses or domain names (or portions thereof) in this variable, separated by spaces. Any visitor whose IP or domain matches an entry in this list will still be shown banners; however, the views or click-thrus will *not* be recorded by the script. This allows administrators to prevent their own activity on their Web sites from counting against their advertiser's banner's exposure counts, and also provides an easy way of dealing with exchange members who try to artificially inflate their exposure counts by repeatedly viewing their own pages. $RequireMember: If you set this variable to 1, any banner call that does *not* include a "member=" or "ID=" reference to a valid account will *not* be sent a banner. (This restriction does not, of course, apply when banners are called via SSI tags, since they can't include such designations; however, since SSI tags can only be used from within the same domain which houses the script, exchange "cheaters" and others trying to skew your stats won't have any way of taking advantage of them.) $IFRAMEbodyspec: Banners can be called via IFRAME tags, which act sort of as "windows" from the calling site to your server. This variable is very similar to the $bodyspec variable discussed below, and allows you to define a background color or image to match that of the site calling the banners, so that the "window" isn't obvious while the banner is still loading. $IFRAMErefreshrate: Another advantage of IFRAME tags is that, since they're actually showing banners on a page "behind" the one your visitors are viewing, the banners can be refreshed without affecting the rest of what your visitors are looking at. If this variable is set to anything other than 0, banners displayed through IFRAME tags will thusly refresh. The value of the variable is the number of seconds between new banner calls. $JSConflict: JavaScript tags can show *almost* any sort of banner. However, in some cases, banners which themselves contain JavaScript code *can't* be displayed via JavaScript tags. If this variable is set to 1, any banner containing This doesn't allow you to refresh banners on otherwise static pages, but it does allow you to show just about anything to just about anyone. (After all, the percentage of your visitors using browsers that don't support even simple JavaScript tags is likely to be *quite* small.) Of course, it's also possible to utilize both IFRAME tags *and* JavaScript tags, for even greater reliability, as follows:

Of course, if all else fails, you can call banners via simple, basic IMG tags: You can "fancy it up" however you like; just make sure that both the link and the image call point to the correct config file, that the "?banner=NonSSI" is tacked on to the end of the link address and that both the link and image address include the (same) "page=" identifier. However, such tags will not allow you to show anything other than simple GIF or JPEG graphics. And more importantly, visitors viewing your pages with MSIE are almost certain to occasionally be directed to incorrect pages (or to error messages) when they click on banners, thanks to the fact that MSIE often caches (even though it shouldn't) CGI-generated images. =========================================== SETTING UP NON-ROTATING BANNERS: Though the primary purpose of WebAdverts is, of course, to rotate banners, it will occasionally happen that you want to show one and only one banner in a particular location. You could do this by setting it up in a zone by itself, but there's an easier say. Simply add an extra entry ("setdest=") to the QUERY_STRING. (The QUERY_STRING is the part of a URL following the actual page name, separated from it by a question mark.) For example, if you wanted to always show an ad named "rugrats" in a particular spot, you could reference the script as follows: http://foo.com/ads.pl?setdest=rugrats (If you're adding QUERY_STRING elements to IMG tags, you need to be sure to add them both to the image call and to the link tag: =========================================== RUNNING A BANNER EXCHANGE: If you're running a banner exchange, you'll want initially to set up each member's account as you would an account for a normal advertiser. Assign the "display ratio" as appropriate, so that a certain number of banner display's on the member's site will generate an exposure of that member's banner on someone else's site. Once you've completed entry of the member information, you'll see on the response page an example of the HTML code which should be inserted on that member's pages to display banners. (That same info is visible any time the member checks his own stats.) The HTML code provided will allow the script to keep track of which member's site displayed the banner, as well as, of course, of what site the user should be sent to if the banner is clicked. If you desire to do so, you can allow members to enter or edit their own information. If you've set the $AllowUserEdit variable to 1, anyone will be able to create a new account simply by entering a new name and password, or to edit an account, so long as they know the correct password. The edit screens in this case are "stripped down" versions of the full administrative edit screen; users can only edit their name, e-mail address, site URL, banner URL and password. When a new account is created by a user in this way, it is first put on a "to be approved" list on the main admin screen. Until the administrator approves it (by "editing" it, with or without actually making any changes), it will *not* appear in the actual rotation, though the new member may begin immediately to accumulate credits by displaying banners on his own site. Note that you should always have at least one non-exchange banner in your rotation. What I mean by that is that there should be at least one banner which is *not* displayed solely on the basis of a specified display ratio. (You can use the spot like LinkExchange does, to advertise the exchange.) Even if you've specified a "default" banner, it's still a good idea to have at least one banner in the exchange which is *always* available to be displayed. =========================================== "ZONING" BANNERS: WebAdverts allows you to set up "zones" for your banners, in order to ensure that certain banners are seen only on certain pages. Assume, for example, that you want to treat your main page as one "zone," and all your other pages as a second zone, since you plan to charge advertisers more to appear on your main page than to appear on your other pages. You could do so by setting up two configuration files, "zone_A.pl" and "zone_B.pl." In the former, you'd define $advertzone as "A" ($advertzone = "A";), and in the latter, you'd define it as "B." Your main page would then include a tag calling zone_A.pl, while your other pages would include tags calling zone_B.pl. (Note that zone names can consist of any series of alphanumeric characters.) Unless you're using SSI tags, though, you don't actually need to set up multiple configuration scripts. In fact, if you do so, you're actually doing things the hard way. You can specify a zone in the QUERY_STRING, just as you can call a specific banner (as discussed above): http://foo.com/ads.pl?zone=A You can also designate that a banner call should show banners from more than a single zone, by listing all the relevant zone names, separated by "plus" signs: http://foo.com/ads.pl?zone=A+B When you enter new accounts, you would define the adverts' zones as either "A" or "B," as appropriate. Those accounts assigned to zone A will show up on your main page; those assigned to zone B will appear on your other pages. If you want a particular banner to be able to appear in *either* zone, either define its zone as "A B" or leave it undefined. (Any banner with no zone defined will be shown in *all* zones.) Note that all of your accounts still comprise a single list, and can still be maintained with a single admin script. Note that the lack of a zone definition constitutes a "wildcard" zone definition. A banner not assigned to any specific zone(s) will be available for display in *any* zone. Similarly, a banner call which does not specify any specific zone will be able to draw banners assigned to *any* zone. If you want *all* of your banners to appear only in certain defined locations, you need to be sure (a) that all of your banners are in fact specifically assigned to the appropriate zone(s), and (b) that all of your banner calls are in fact specifying the zones from which their banners are to be called. If you want to be able to show *all* your advertisers on a single page, create a config file with the $advertzone variable defined as "showall" ($advertzone = "showall";) or just add "zone=showall" to the URL of your banner call. All of your current banners (those which have not expired and which have a non-0 weight) will be displayed. (Note that if you've defined $RequireMember to 1, you'll need to make sure your "ShowAll" banner calls, just like any others, reference a valid account name, even if it's only your "default" account!) Finally, you can also show all of the banners defined to a specific zone, and only that zone, by combining "showall" with the specific zone's name. For example: http://foo.com/ads.pl?zone=showall-rugrats (The "zone=" designations, like all other QUERY_STRING elements, by the way, can be included on IMG tag, IFRAME tag, and JavaScript tag banner calls.) =========================================== USING ZONES IN A BANNER EXCHANGE: Zones themselves work the same regardless of whether you're using SSI- or IMG-based calls. However, while with SSI-based calls, the manual assignment of zones for banners works fine, if you're running a banner exchange, things are just a bit more complicated. You can't expect your members to "pick" zones appropriately at random; you need a way to let them know which zones exist and to allow them to select appropriately. Hence the %nonssi_cgis variable. If you leave this variable unassigned, your banner exchange will be untargeted. All members will reference the same config script to call banners (the script referenced in $nonssi_cgi), and all banners (unless you, as the administrator, specifically assign them zones) will be eligible for display on any page. If, on the other hand, you assign a value to this variable, you introduce targeting -- which can be used to split banners and pages into categories based on topic, age-appropriate content, or whatever else you come up with -- into your exchange. Let's say you've set up four zones, "G" (config script zone_G.pl), "PG" (config script zone_PG.pl), "R" (zone_R.pl) and "X" (zone_X.pl). You'd define the %nonssi_cgis variable as follows: %nonssi_cgis = ( 'G','http://foo.com/ads/zone_G.pl', 'PG','http://foo.com/ads/zone_PG.pl', 'R','http://foo.com/ads/zone_R.pl', 'X','http://foo.com/ads/zone_X.pl' ); Now, when you or a member add or edit an account in the exchange, you'll be able to select the zone or zones in which the banner can be displayed, as well as the zone (unfortunately, only one) from which banners will be displayed on the member's page. When the account data is displayed to the member, the appropriate CGI script will be referenced in the "cut and paste" HTML code presented. =========================================== INCLUDING BANNERS IN CGI OUTPUT: Including WebAdverts banners in the output of other CGI scripts is quite simple. All you need to do is include a tag -- JavaScript, IFRAME or IMG, as you prefer -- on that script's output page. As usual, the former two are to be preferred. Certain versions of MSIE (the world's most popular buggy browser) will *not* display a banner on a CGI-generated page, when called via an IMG tag, until and unless the page is refreshed. =========================================== USING "RAW MODE" BANNERS: "Raw" mode allows you to actually specify the particular HTML code that WebAdverts should insert on your pages. If you want to include in the rotation a banner from an advertiser who requires certain HTML code or banners from a network such as LinkExchange, this is how you do it. Note, though, that if you do so, what you enter in the "raw mode" text input box will be copied exactly onto your pages when the banner is called. The ability to include "raw" HTML can be handy, but use it carefully. It would be quite easy to "screw up" your pages if the HTML inserted here is incomplete or incorrect. Generally speaking, if you utilize "raw mode" for your banner entries, whatever you input will be copied *exactly* onto your Web pages. WebAdverts will be able to track the number of times the banner was displayed, but nothing more. You won't get click-thru data. But there are a few tricks available to allow you to let WebAdverts modify this supposedly unmodifiable text. Some banner exchanges utilize a numbering system to keep track of separate banner calls. (WebAdverts' own "page" designations in IMG tag calls serve as an example of this.) If you wish to put such a number in the raw mode entry, simply include "" where you want a random "page" number inserted. And if you want to be able to track click-thrus as well as exposures, include "" immediately before the destination URL in the HTML entry. This will insert a "pass-thru" reference to your WebAdverts script and enable WebAdverts to log the click-thru before sending the user on to the banner's real destination. As an example, let's assume that you want to include banners from an outside banner exchange, which happens to utilize WebAdverts, in your site's normal advertising banner rotation. If the code with which you were provided by the exchange looked like this: Foo Exchange
Foo Exchange Then inputting the following into the "raw HTML" text input box for the account displaying the exchange's banners would allow you to track the number of click-thrus, as well as ensure that each time the banner is called, a new page number is used and thus a new call is made to the remote host server: Foo Exchange
Foo Exchange Note the placement of the tags and the tag. Note also that the tag isn't a guarantee; even if you include it, you may still not be able to track click-thrus. LinkExchange, for example, makes use of IFRAME tags; since those are actually just "windows" to their own server's display of a banner, there's no way the WebAdverts script can modify it and thus track clicks. =========================================== SENDING E-MAIL NOTIFICATIONS: If you have a file called "welcome.txt" in your data directory, you'll have the option each time you add or edit an account of sending the contents of that file as a "welcome" e-mail message to the account holder. An example "welcome.txt" file is included in the downloadable program package. The <--UserID-->, <--Password--> and <--HTMLCode--> "comment" tags are, of course, replaced by the program with the actual information for the particular user being e-mailed. Similarly, if you have a "reject.txt" file in your data directory, you'll be able to send the contents of that file as an e-mail message to the account holder of any new account that you choose not to allow into the exchange. If you've defined an e-mail program, your advertisers or exchange members will also be able to have their passwords automatically sent to them from the main entry screen, in case they've forgotten them. This should cut down the volume of your "help me" mail messages just a bit. =========================================== GENERAL SECURITY NOTE: The directory containing your data files should be password-protected or (better yet) should be located somewhere inaccessible to browsers. You probably don't want random passers-by snooping about in your advertisers' or exchange members' data. This is especially important if you're running an exchange in which members can update their own information, as if someone can read the data files, they can read the individual members' passwords, as well. =========================================== REGISTERING WEBADVERTS: WebAdverts is shareware. If you use it, please register it! The registration fee is only $50 (US). Payment should be sent via check or money order to Darryl C. Burgdorf, Affordable Web Space Design, 3524 Pacific Street, Omaha NE 68105. (If you happen to live in a country other than the United States, you can write a check in your local currency for the equivalent of $57.50. That will cover the $50 registration fee and the $7.50 service fee which my bank charges. Please do *not* write me a check in US funds drawn on a non-US bank; the service charge for those can be anywhere from $10 to $25!) You can also register via credit card online, of course, by following the links from the WebAdverts download page and/or the "registration information" page on the WebScripts site. Alternately, you can register online via the PayPal system. Just send your payments to burgdorf@awsd.com. The unregistered version of the script is not crippled in any way. I'm not trying to "coerce" anyone into sending me money. But I don't think it's an unreasonable request. I believe WebAdverts is a commercial- quality product; a *lot* of work has gone into its creation. If you use it, I'd appreciate it if you would be kind enough to send in the registration fee. I'll be that much more likely to be able to continue spending time and effort on the scripts in the WebScripts collection, and you'll have the satisfaction of knowing you did the right thing. ;) =========================================== This documentation assumes that you have at least a general familiarity with setting up Perl scripts. If you need more specific assistance, check with your system administrators, consult the WebScripts FAQs (frequently-asked questions) files , or ask on the WebScripts Forum . -- Darryl C. Burgdorf