Overview

This engine is solution for typical small or middle size corporative sites. Engine implements all needed administration tools and developers need only "Get" functions to take parameters and place them into the pages.

Knowledge requirements

You must be familiar with JavaScript (or MS JScritpt) basic conceptions and syntax. But it isn't required to have experience with data bases, ADO etc. You must be able to write simple ASP pages using JScript and this is enough. All needed DB functionality, administration forms, structure abstractions are already implemented in the engine. Pages are built over the simple to use APIs.

In the other hand these APIs can be used by advanced ASP programmers to build advanced sites with less time costs.

Why we choose JScript? It is a flexible language that allows data packaging in easy form for final use (dynamic object properties generation). JScript/Javascript is known as language used in DHTML pages, but it gives many advantages in the server side programming too. Language has some problems with enumerations returned by ActiveX objects, but in all other cases it is more flexible than VBScript.

Use sample site to begin your work.

Conception

Site engine maintains for you several types of objects in data base:

  • Categories
  • Resources
  • Stories
  • Products
  • Menus
  • Menu Items

Contents of the objects can be changed through administration tool of the site. Change includes relations between some of the objects too.

At the other side engine exposes to developer set of functions for object manipulation. All functions are accessible as members of the base object - ResAccess. It must be initialized (before any function call occurs) with current language on every page in your project. Language support of the engine was based on two character text fields in every entry (excluding categories and products). Once initialized, ResAccess object will return only those objects that have language equal with current. This gives you an easy way to build international sites.

All functions documented here are for read only access to the objects - we suppose that only the administration part will modify data.

For some guidelines on how to build your applications see Guidelines


Initialization

Every asp page based on ZmeY CorpSite must include ResAccess.js - that can be found in /engine directory. This means that beginning of every page must look like this:

<%@ Language=JScript %>
<!-- #include virtual="/Engine/resaccess.js" -->

To init ZmeY CorpSite engine you must create ResAccess object and pass as an argument to the constructor, the language to use (as two letter string - for example: "en").

example:

var Res = new ResAccess("en");

To choose language you can use query string parameters, session, accepted languages reported by browser etc. We provide helper functions for some of the possible ways:

The easiest way to init engine is function

InitCorpSiteEngine()

Call it in <HEAD> part of your page - in the place where must be placed encoding meta tag - for example:

<HEAD>
<% var Res = InitCorpSiteEngine() %>
<TITLE>My Page</TITLE>
</HEAD>

It will select language to use in following manner:

  • If there is parameter in the query line called "Language", it will use it (ex: http://www.mysite.com?Language=en.....)
  • If not found, it will use the browser accept-languages and will choose first supported. If not found it will init engine with the default language - "en". (You can modify script to change this default value).

In addition function will generate an appropriate meta tag - for example:
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">

Supported languages are determined by Table "Languages" in site database. If you want to add support for more than predefined languages (or remove some) edit this table with MS Access. (There isn't no administration form for this task - typically set of supported language will not change during the time of site life - but tell us if you need this - we will add language form).

InitCorpSiteEngine() is preferred way for engine initialization it has optional string parameter defaultLanguage i.e. it can be called as follows:

InitCorpSiteEngine("it")

This will cause to use italian as default language - if list of desired languages reported by the browser does not contain acceptable languages.

Some additional functions for advanced users who want to implement another form of language selection:

FindFirstSupportedLanguage(); - returns short name (two letters) of first supported by site DB language depending to the reported by browser accepted languages.

ResAccess.LanguageHeader(); - returns encoding part of meta tag. Must be called after initialization. For example returns charset=windows-1252 for the ResAccess initialized with "en" language.

ResAccess.GetLanguages(); - returns array of objects that describe every language defined in site DB. Example:

var x = ResAccess.GetLanguages();

Returned object is array with global property:

x.RecordCount - count of all language objects returned.

every language object has following properties:

  • x[i].Lang - short name (two letters) of the language
  • x[i].LangName - display name of the language
  • x[i].LangImageURL - URL of language image (national flag etc.; optional)
  • x[i].LangHeader - encoding string that must be placed in meta tag.


Categories

ResAccess.GetCategory(Category,intEncodeType)

heading | Type | Name | Description
[in] | ID or String | Category | Name or ID of category
[in] | Number | intEncodeType | One of the encXXX constants or null

Returns:

Category object or null if category not found

ResAccess.GetCategories(intPage,intPageSize,intCatType)

heading | Type | Name | Description
[in] | Number | intPage | Start page for output array
[in] | Number | intPageSize | Length of page
[in] | Number | intCatType | One of the ctXXX constants

Returns:

Array of Category objects with following global properties:

Type | Name | Description
Number | PageSize | Size of the page
Number | PageCount | Total pages
Number | RecordCount | Count of records in the array (not total count)

ResAccess.GetCatTypeID(CatID)

heading | Type | Name | Description
[in] | Number | CatID | Category ID

Gets type ID of category (see Category type constants)

ResAccess.GetCatTypes(intEncodeType)

heading | Type | Name | Description
[in] | Number | intEncodeType | One of the encXXX constants or null

Returns list of all category types registered in the system - useful if you have made extensions using new category types


Resources

ResAccess.GetResource( strResName, strCatName, intEncodeType, intPage, intPageSize)

heading | Type | Name | Description
[in] | String | strResName | Resource name
[in] | String | strCatName | Category name
[in] | Number | intEncodeType | One of the encXXX constants or null
[in] | Number | intPage | Start page for output array
[in] | Number | intPageSize | Number of records on each page

Returns one resource or array of resources depending to the input parameters:

strResName - null strCatName - not null | Returns array of all resources in that category. Array contains Resource objects.
strResource - not null strCatName - null | Returns all resources with the given name in all categories as array of Resource objects.
strResource - not null strCatName - not null | Returns one record - "Resource with that name/ID from the given Category" as Resource object.

If no records found, returns null.


Stories

ResAccess.GetStory( Story, intEncodeType)

heading | Type | Name | Description
[in] | ID or String | Story | ID or name of story to return
[in] | Number | intEncodeType | One of the encXXX constants

Returns:

First story found by ID or Name given as Story object

ResAccess.GetStoriesByProductID(Category, ProductID, intPage, intPageSize, intEncodeType)

Finds all stories related to a product in specific category.
Can not be called with null for Category input parameter.

heading | Type | Name | Description
[in] | ID or String | Category | Name or ID of category
[in] | ID | ProductID | Select stories about this product ID
[in] | Number | intPage | Start page for output array
[in] | Number | intPageSize | Length of page
[in] | Number | intEncodeType | One of encXXX constants or null

Returns:

Array of Story objects and the following global properties for the array object:

Type | Name | Description
Number | PageSize | Size of the page
Number | PageCount | Total pages
Number | RecordCount | Count of records in the array (not total count)

or returns null if no stories found

ResAccess.GetStoriesByCategory(Category, intPage, intPageSize, intEncodeType)

Finds all stories in specific category.
Can not be called with null for Category input parameter.

heading | Type | Name | Description
[in] | ID or String | Category | Name or ID of category
[in] | Number | intPage | Start page for output array
[in] | Number | intPageSize | Length of page
[in] | Number | intEncodeType | One of encXXX constants or null

Returns:

Array of Story objects and the following global properties for the array object:

Type | Name | Description
Number | PageSize | Size of the page
Number | PageCount | Total pages
Number | RecordCount | Count of all records returned in the array (not total count)

or returns null if no stories found

ResAccess.GetStoriesByGroup(Group, intPage, intPageSize, intEncodeType,FromCat)

Finds all stories with attached group category.
Can not be called with null for Group input parameter.

heading | Type | Name | Description
[in] | ID or String | Group | Name or ID of category attached to the story (this is second attachment - in admin forms this is the drop down menu below the product attachment)
[in] | Number | intPage | Start page for output array
[in] | Number | intPageSize | Number of records per page
[in] | Number | intEncodeType | One of encXXX constants or null
[in] | String (optional) | FromCat | If passed lookups only stories in this category

Returns:

Array of Story objects and the following global properties for the array object:

Type | Name | Description
Number | PageSize | Size of the page
Number | PageCount | Total pages
Number | RecordCount | Count of records in the array (not total count)

or returns null if no stories were found

Remarks

With GetStoriesByCategory() you can obtain only stories of the given category and this category must be of type ctStory. GetStoriesByGroup() gives you ability to obtain stories with attached categories. Attached category can be any non-hidden one. As an example you can use this function if you want to attach a story (or several stories) to the product categories.


Menus and Menu Items

Menus

ResAccess.GetMenuID(strIntName)

heading | Type | Name | Description
[in] | String | strIntName | Internal name of the menu

Returns ID of the menu

ResAccess.GetMenu(MenuCatID,intEncodeType)

heading | Type | Name | Description
[in] | ID | MenuCatID | ID of the menu (Every menu is defined as a category)
[in] | Number | intEncodeType | one of the encXXX codes

Returns a Menu object or null if menu was not found

ResAccess.GetMenuArray(strMenuName)

heading | Type | Name | Description
[in] | String | strMenuName | Name of the menu to return

Returns simple menu object with properties:

Type | Name | Description
Number | itemsCount | Count of items in this menu
Array | Items | Array of MenuItem objects
ID | MenuCatID | ID of the menu

Use this function to build your own view of the menu (or if you need to enumerate all menu items).

ResAccess.BuildMenu(MenuCatID)

heading | Type | Name | Description
[in] | ID | MenuCatID | ID of the menu to display

Constructs (directly writes in Response) default view of the menu - vertical table with styles/parameters in <table> and <td> tags (see headStyle properties of the Menu and MenuItem objects)

Menu items

ResAccess.GetMenuItemID(strIntName)

heading | Type | Name | Description
[in] | String | strIntName | Internal name of the menu item

Returns ID of the menu item

ResAccess.GetMenuItem (MenuCatID,ItemIntName,intEncodeType)

heading | Type | Name | Description
[in] | ID | MenuCatID | Menu ID (Get it with GetMenuID function)
[in] | String | ItemIntName | Internal item name to return
[in] | Number | intEncodeType | One of the encXXX constants

Returns MenuItem object or null if item was not found.


Products

ResAccess.GetProduct(ProductID, intEncodeType)

heading | Type | Name | Description
[in] | ID | ProductID | ID of the product to return
[in] | Number | intEncodeType | One of the encXXX constants

Returns a Product object if found or null

ResAccess.GetProductsByCategory(CatID, intPage, intPageSize, intEncodeType)

heading | Type | Name | Description
[in] | ID | CatID | ID of category to return
[in] | Number | intPage | Start page for output array
[in] | Number | intPageSize | Records per page
[in] | Number | intEncodeType | One of the encXXX constants or null

Returns:
Array of Product objects and following for the array object:

Type | Name | Description
Number | PageSize | Size of the page
Number | PageCount | Total pages
Number | RecordCount | Count of records in the array (not total count)

Remarks:

When called with CatID = null will return all products.


Miscellations

Miscelanous functions

ResAccess.HasStoryImage(Story)

Checks ImageURL field of a story.

heading | Type | Name | Description
[in] | ID or String | Story | Name or ID of story (name must be unique - if not use ID instead)

Returns:

Boolean result - true if story has an image

ResAccess.HasStoryURL(Story)

Checks LinkURL field of a story.

heading | Type | Name | Description
[in] | ID or String | Story | Name or ID of story (name must be unique - if not use ID instead)

Returns:

Boolean result - true if story has an LinkURL

TextToHTML(strText);

Returns the passed string after replacing <new line> "\n" codes with <BR> HTML tag - useful for displaying preformatted text in HTML pages.

HTMLToText(strText);

Returns the passed string after replacing <BR> HTML tags with <new line> codes - converts plain HTML text to text.


Integrated Shopping-Cart Callbacks

These two functions are used to extract products from your database and preform special processing. See /engine/Catalog.inc for more info.
Note that catalog-internal.inc in the same directory (/engine) implements this functionality for the corpsite datebase. You can change this file to meet your real needs.

function GetProductPricing(intProductID, intQuantity)

heading | Type | Name | Description
[in] | ID | intProductID | Needed ProductID
[in] | Number | intQuantity | Quantity items of this product

Returns:

A new JScript Object (shown below) or null if the given ProductID is invalid

Returned object must have the following properties set:
Type | Name | Description
Number | intCartItemID | Must be set to null
Number | intCartID | Must be set to null
Number | intGroupID | Set to product group ID or null if no product groups are used
String | strGroupName | Product group name (up to 48 characters) or null if no product groups are used
Number | intProductID | Product ID (same as intProductID argument)
String | strProductName | Product name (up to 64 characters)
Number | intQuantity | Quantity (same as intQuantity argument)
Number | numUnitPrice | 1 product unit price
Number | numFullPrice | (intQuantity * numUnitPrice) if there is no volume discount

function GetPriceCorrection(objCart, arrCartItems, intTotalItems, numTotalPrice)

heading | Type | Name | Description
[in] | Object [Cart] | objCart | JScript object with properties. This function may modify the following properties: objCart.numDiscount - discount for all items (if any) objCart.numShipCost - shipping cost
[in] | Array | arrCartItems | An array of JScript objects corresponding to items in shopping cart
[in] | Number | intTotalItems | Sum of all items
[in] | Number | numTotalPrice | Sum of the full prices for all items

Remarks:

You can use this function to modify the price for several products. So here you can add shipping costs, calculate discounts, etc. See /engine/Catalog-internal.inc for an example.


Products

Search functions

ResAccess.FindProducts( StoryCat,bSearchBody,Phrase,startPage,pageSize)

Searches linked stories in the given category for "Phrase" occurence and returns array of the corresponding (distinct) product IDs.

heading | Type | Name | Description
[in] | ID | StoryCat | ID of the story category to search
[in] | Boolean | bSearchBody | if true - searches title and body - else only title of the sotries
[in] | String | Phrase | Search phrase
[in] | int | startPage | starting page to fill in the array
[in] | int | pageSize | page size to use

Returns a array IDs if found or null with following global properties:

Type | Name | Description
Number | PageSize | Size of the page
Number | PageCount | Total pages
Number | RecordCount | Count of records in the array (not total count)

ResAccess.FastFindProducts( Phrase,startPage,pageSize)

Searches product names for the "Phrase" occurence and returns array of the corresponding product IDs.

heading | Type | Name | Description
[in] | String | Phrase | Search phrase
[in] | int | startPage | starting page to fill in the array
[in] | int | pageSize | page size to use

Returns a array IDs if found or null with following global properties:

Type | Name | Description
Number | PageSize | Size of the page
Number | PageCount | Total pages
Number | RecordCount | Count of records in the array (not total count)

ResAccess.FindProductsByDate( dateBegin,dateEnd,startPage,pageSize)

Searches products dated between given dates and returns array of the corresponding product IDs.

heading | Type | Name | Description
[in] | date/time | dateBegin | ID of the story category to search
[in] | date/time | dateEnd | if true - searches title and body - else only title of the sotries
[in] | int | startPage | starting page to fill in the array
[in] | int | pageSize | page size to use

Returns a array IDs if found or null with following global properties:

Type | Name | Description
Number | PageSize | Size of the page
Number | PageCount | Total pages
Number | RecordCount | Count of records in the array (not total count)


Return object types

Objects returned by some ResAccess functions:

Category - returned by GetCategory() and GetCategories()

Resource - returned by GetResource()

Story - returned by GetStory(), GetStoriesByProductID() and GetStoriesByCategory()

Menu and MenuItem - returned by the menu functions

Product - returned by GetProduct() and GetProductsByCategory()


ResAccess Usage Samples

Samples

Here we will show some of the typical constructions used to display information from engine's DB. All the samples are part of the sample site (placed in home directory). You can modify it to understand how it works. there is no design in this site so to be easy to understand scripts - not HTML.

Some of the sample pages are in two versions - simple and advanced.

For engine initialization see Initialization.

1. Displaying stories of one category:

<%
   var i;
    var arrStories = Res.GetStoriesByCategory("MyCategory",1,1000,encForm);
    if (arrStories != null) {
        for (i = 0; i < arrStories.RecordCount; i++) {
            if (arrStories[i].fHidden) continue;
        %>
             Title: <%= arrStories[i].StoryTitle %><BR>
             Internal name: <%= arrStories[i].StoryName %><BR>
             Image: <img src=\"<%= arrStories[i].ImageURL %>"><BR>
             Text: <%= arrStories[i].StoryText %><BR>
             <BR><BR>
             Link: <a href="<%= arrStories[i].LinkURL %>">Story Link</a>
             Date: <%= arrStories[i].DatePosted %><BR>
             <HR>
        <%
        }
    } else {
        %>
             No stories in this page !
        <%
    }
%>

Calling GetStoriesByCategory() (or any other ResAccess member function that takes arguments intPage and intPageSize) with intPage = 1 and big value for intPageSize means that you will not use the paging capabilities of site engine - you just want to get all stories at once.

To implement paging when listing records, you must design a form that will call this function with appropriate the page. For example: on a page there is a form with an input field and submit button. When the button is clicked, the form is submitted to the same ASP (where the list-page resides). Then the input field value is used as page number and GetStoriesByCategory() is called (page size is assumed constant) to refresh the list.

2. Page caption

Suppose you want to give your pages different titles and to store these titles as resources (in category named "PageTitles"). Also lets assume the page category name is passed in the query line (or it is submitted in a form). For example:

Let your home page, about page, news page share same design and all they are implemented in one ASP script named mypage.asp. Then About page will be called as mypage.asp?category=about, Home page will be called as mypage.asp?category=home , etc.

How to implement this:

<%

// Request(XX) will operate either on QueryString or Form
var pageCategory =
Request("category");
var pageTitle = Res.GetResource(pageCategory, "PageTitles", 1, 1000, encForm);

%>
<title> <%= pageTitle.ResValue %> </title>


MultiLang

MultiLanguage support notes.

CorpSiteEngine supports different languages. In the administration forms you will not find form to add/remove support for languages. You must manualy edit Languages table in the SiteData.mdb. By default it ships with only one - english.

Table structure

Lang | Language display name | LangImageURL | LangHeader
example: en Two characters language ID | Used in the admin forms | reserved - not used | for example: windows-1252 Write here encoding for this language.

Please note ! If you are using automatic initialization and you have to enable certain language - this may cause users to view pages without any information entered yet. Add only supported (now) languages - not all that you plan to support in the future.


Return object types

Utilities

HTMLTemplate object

HTMLTemplate object supports template files. You can create HTML pages and make some parts of that pages replaceable by script.Templates suport simple tags and detail areas. Detail areas may contain another simple tags and details can be repeated as many times as you need (using AddNew).

Template syntax:

~TagName~ - simple replaceable tag. TagName can consist of Letters and numeric values.

<%DetailName%> ... <%DetailName%> - Detail part of the page - can be repeated 0 or more times.

Templates have parts of two types: Static and Detail parts. Details are defined by using <%Name%> for begin point and the same for the end point. All code that is out of detail sections is static part of the template.

You may have more than one detail but details can not be nested!

After initializing the template you choose active part/detail by setting value of currentPart property.

When currentPart is null you are working with static part, When it is name of the detail part you are working with current instance of the detail. Thus in the example on the bottom you are choosing detail "Phone". This will not add automaticaly new detail. You must add it using Member AddNew. Then you are able to replace tags in the current detail. Then you can add new detail instance and so on.

See samples on the bottom of this page for more information.

Properties:

  • currentPart - current detail name or null to work with static part

Methods:

  • HTMLTemplate() - constructor
  • SetTemplate(string TemplateString) - sets and parses new template. After calling this member call also Init without parameters
  • Init([optional] string FileName) - if FileName was specified it uses file like a template if FileName was omited - only initializes object
  • AddNew() - can be used only if currentPart is not null i.e. if you are currently working on a detail. Adds new copy of the detail and makes it current
  • Set(string TagName, string Value) - replaces tag with given value in the current part.
  • GetResult() - returns resulting string

Samples:

Supose that you have written this page template:

<HTML>
<BODY>
<H2>Wellcome to the page of  ~PageTitle~</H2>
My phones are:
<%Phone%>
Phone~PhoneIndex~:<BR>
~PhoneNumber~
<%Phone%>
</BODY>
</HTML>

You are using this code to generate page:

var h = new HTMLTemplate;
h.Init("TemplateName.htm");
h.Set("PageTitle","John Smith"); // This sets PageTitle in the static part of the page
h.currentPart = "Phone"; // This sets as active working part of the template detail "Phone"
h.AddNew(); // This ads one detail
h.Set("PhoneIndex",1);
h.Set("PhoneNumber","111-11-11"); // These two lines set corresponding simple tags in the newly created detail (With AddNew)
h.AddNew(); // This adds second detail "Phone"
h.Set("PhoneIndex",2);
h.Set("PhoneNumber","211-11-11"); // These two lines set corresponding simple tags in the newly created second detail (With AddNew)
Response.Write(h.GetResult()); // this spools page to the client

And result is something like this:

Wellcome to the page of John Smith

My phones are:

Phone1:
111-11-11
Phone2:
211-11-11


Site Installation

Installation

(see README file for complete installation guide)

If you have to purchase retail package of this product you do not need to install it anywhere. Distribution files are source for multiply site installations on one server. There is an Scripting host installation script in main directory that creates and initially configures new IIS site. It creates all needed directories, sets permissions, sets server bindings (IPs, Host headers, ports). You may want to install many different sites based on ZmeY Corpsite - for every new site you must run this script with appropriate parameters.

Site installation script is setsite.vbs (VBScript). For your convenience we provide setupsite.cmd NT batch file - this file also copies and installs ASPIniFile ActiveX. We recommend usage of the .cmd file for installations - it will run installation VBScript in console mode - with cscript (instead of wscript). Installation script can be started on remote machine through telnet or RemoteConsole session safely.

QUICK INSTALLATION

To install new IIS site based on ZmeY CorpSite use setupsite.cmd. Open Command prompt window go to the ZmeY Corpsite installations directory and run setupsite.cmd with appropriate arguments. Supported options are:

(required)      -r      ROOT DIRECTORY PHYSICAL PATH
(required)      -n      WEB SITE NAME
(def: 80)       [-o]    TCP/IP PORT NUMBER
(def: all)      [-ip]   IP ADDRESS
(optional)      [-h]    HOST NAME
(optional)      <-adm   ADMINISTRATIVE ACCOUNT OR GROUP> default: Administrators
(optional)      <-user  USER THAT OWNS THIS SITE>        default: (none)
(optional)      <-b     BASE SECURITY GROUP> default: Domain Users

Or use additional switches for help and auto-start site

                [-s]    Start site
                [-?]    Help screen
Using different HOST NAME arguments when creating sites on equal IPs and TCP ports creates a new virtual server that will answer only if the exact DNS name was used in a request. To use this powerful feature of Microsoft IIS you need to to configure your DNS server (please contact a responsible person) If parameter contains spaces enclose it with double quotes (").

After installation go to /admin virtual directory of your site, log on as administrator and select active data source to be used with this site. By default (if no configuration file found in /cfg directory) CorpSite.mdb will be selected (it appears to be in /data virtual directory). Jet 3.51 will be used by default. Administrators can change these settings. For DB source either physical path and ODBC alias can be used, for DB provider - OLEDB provider for MS Jet versions 3.51 and 4.0 or OLEDB provider for ODBC (if source is accessible throgh ODBC alias). In the most cases you need only to enter Database page and save atomaticaly generated settings.

To use upload features you must have Site Server Express installed - version 2.0 or later. DLL files in the /admin directory are placed here for easy installation - you can replace them with newer versions from site server express manualy.


Installation instructions on ZmeY CorpSite Engine

OVERVIEW

ZmeY CorpSite Engine is mostly script (JScript and VBScript) based application. In addition it uses INI file access ActiveX.

Package doesn't needs installation itself. Extract it and place files in location of your choice. Content will be used as a source of every site installation.

We provide two installation scripts with this package:

  1. setupsite.cmd
    (uses setsite.vbs and setsecurity.cmd)
    This script creates a web site in your web server with the appropriate settings for the application. After site setup you can modify it to meet special needs.
  2. setupdocs.cmd
    (uses setdocs.vbs)
    This script installs documentation/reference and creates a Program group and a shortcut Start Menu\Programs

INSTALLATION

Read notes below for requirements and compatibility

To install a new site based on this software, open a command prompt window, go to the directory with CorpSite files and use setupsite.cmd. Its command line parameters are described below. This .CMD file is for easy use only. It calls setsite.vbs with the console version of Windows Scripting Host and registers the ASPIniFile ActiveX object. Installation will register the ActiveX every time when new site was created, but this will not alter other running CorpSites.

Installation script assumes some security strategy. See notes for more information.

Command line parameters:

Usage: setupsite
(Every parameter consists of command and value, like -r MYMACHINE).

           Command     Value

(required)      -r     Root directory physical path
(required)      -n     Web site name
(assumes local) -c     Computer (name of the local machine without leading \\)
(def: 80)       -o     TCP/IP port number. Default: 80
(def: all)      -ip    IP address. Default: All unassigned
(optional)      -h     Host name. Must supply Host name or IP address, or both.
(optional)      -adm   Administrative account or group. Default: Administrators
(optional)      -user  User that owns this site. Default: (none)
(optional)      -b     Base security group. Default: Domain Users

You can also use these additional switches for help and auto-start site
                -s    Start site
                -?    Help screen

Note: Using different HOST NAME arguments when creating sites on equal IP addresses and
TCP ports creates a new virtual server that will answer only if its exact DNS name was used
in the request. To use this powerful feature of Microsoft IIS you need to configure your
DNS server (please contact a responsible person)

If a parameter contains spaces, enclose it with double quotes (").

Note: If all these settings & options on the command line confuse you, try using "Site Setup Helper" (helper.htm - located in the same directory as this file). It was designed to help you interactively construct the command line that will serve your needs.

Some examples follow:

Example1:

setupsite -r D:\inetpub\Company1Site -c MYMACHINENAME -o 80 -h www.company1.com -n COMPANY1_SITE -s

This example will copy application files to "D:\inetpub\Company1 Site" folder and create site named COMPANY1_SITE that will answer only when refered as www.company1.com (it will not answer if refered as http://x.x.x.x, if x.x.x.x is IP address of your web server). Site will be started.

Example2:

setupsite -r D:\inetpub\Company1Site -c MYMACHINENAME -o 80 -n COMPANY1_SITE -ip 195.96.227.12

This example will copy application files to D:\inetpub\Company1Site and create site named COMPANY1_SITE that will only answer on 195.96.227.12 IP address. Site will not be started immediately. You will have to start it manualy.

To install documentation just start setupdocs.cmd without any options. Then find in Start Menu\Programs, a group named ZmeY CorpSite Engine.

NOTES

Installation script assumes security strategy. Default options were designed for standard situations - NT and IIS installations with default options:

  1. IIS anonymous (see your IUSR_XXX account in User Manager) account is a member of "Domain users" (global) and Guests (local) groups. If your server is not a NT domain member, this usually will be the Guests group.
  2. Administrators are members of "Administrators" group
  3. Customers' accounts are with guest rights - not regular user rights. (Customers are owners of the sites, they have access to the content administration forms)
Terms:
  • BASE security group ( -b installation option)
  • ADMIN security group (-adm installation option)
  • USER security account or group ( -user installation option)
Security requirements are:

        BASE security group must allow MS Jet full access to the database file located in /data directory of the site.

        BASE security group must allow to the anonymous users read access to the public part of the site - /home (root), /pages, /downloads,
/img, /engine directories.

        ADMIN security group must have full access to the every part of the site. Of cource you can restrict admin access if your customers will
manage their sites exclusively.

        USER is not necessary, but if content management is directed to the customers
must this account must have access to the admin directory (only read access !!!)

    If your server configuration differs from standart please follow requirements and
choose appropriate arguments for installation. After installation check that DB engine
works for admins and for anonymous users - if not delete site from Management console
and try to reinstall with another BASE security group. (see samples below)

    Example 1:

        Working on PDC, BDC ...

        IUSR_XXX is a member of "Domain users"

        Administrators will admin site

        Cutomers are members of Guests group (with interactive access added)

         sample customer account will be ACME_Company

        setupsite.cmd -r c:\inetpub\ACMESite -n "ACME Site" -h www.ACME.com

    Example 2:

        Working on "Stand alone server"

        IUSR_XXX is a member of Guests group

        Administrators will admin site

        Cutomers are members of Guests group (with interactive access added)

         sample customer account will be ACME_Company

        setupsite.cmd -b Guests -r c:\inetpub\ACMESite -n "ACME Site" -h www.ACME.com

        But this is not enough secure, better create copy of Guests group named it for
example WEBSiteCustomers and make Customer accounts members of this group. Sample setup will be:

        setupsite.cmd -b WEBSiteCustomers -r c:\inetpub\ACMESite -n "ACME Site" -h www.ACME.com

        If you have problems with your security strategy contact us.
NTFS Security of the site directory structure after setup ("-" means not important):
    Virtual     Physical        Group/Account           Read    Write

/           home            BASE	                Yes     No
                                ADMIN                   Yes     -
                                USER                    Yes     No

    /admin      admin           BASE                    No      No
                                ADMIN                   Yes     -
                                USER                    Yes     No

    /data       data            BASE                    Yes     Yes (*)
                                ADMIN                   Yes     Yes
                                USER                    Yes     Yes

    /cfg        cfg             BASE                    Yes     No
                                ADMIN                   Yes     Yes
                                USER                    Yes     No

    /downloads  downloads       BASE                    Yes     No
                                ADMIN                   Yes     Yes
                                USER                    Yes     Yes

    /engine     engine          BASE                    Yes     No
                                ADMIN                   Yes     -
                                USER                    Yes     No

    /img        img             BASE                    Yes     No
                                ADMIN                   Yes     Yes
                                USER                    Yes     Yes

    /pages      pages           BASE                    Yes     No
                                ADMIN                   Yes     Yes
                                USER                    Yes     Yes
IIS access to the site after setup ("-" means not important):
    Virtual     Physical        Read    Write   Script  Execute

/           home 	        Yes     No      Yes     No
    /admin      admin           Yes     No      Yes     Yes
    /data       data            No      Yes     No      No
    /cfg        cfg             Yes     No      No      No
    /downloads  downloads       Yes     Yes     No      No
    /engine     engine          Yes     No      Yes     No
    /img        img             Yes     Yes     No      No
    /pages      pages           Yes     Yes     No      No

    (*) Write access not needed if no anonymous/user DB updates occur.

    Goals of the security strategy:

    As a result of this scheme Administrators are able to:
  • Use content administration forms
  • Upload files through WEB iterface to the img, downloads, pages, data directories
  • Configure datasource (if they place it at other - non-standard location or prefer to use alias)
  • use alternative way to manage content and engine of the site (such as FTP or shared folders)
Site owners are able to:
  • Use content administration forms
  • Upload files through WEB iterface to the img, downloads, pages, data directories
Site owners are NOT able:
  • To configure datasource (if they have this right - they will be able to access the data of other CorpSites !!! Please be careful with security of the /cfg directory)
Anonymous users (site visitors) are able to browse content and to download files from download directory.

This document does not cover FTP access to the site but Administrators can setup FTP site/directory
that will give to the site owners FTP access only to the content that can be changed without risks
for the entire system.

If you want to mount ZmeY Shopping Cart to this site we suggest installing it as separate virtual site or
use integrated version of this site engine.

Some additional notes:

We can make package self installing and implement WEB based setup of customers' sites but this will require creation of one site for this purpose. We will be glad to learn your opinion.

Installation is console based because of possibility to be used through telnet, remote console etc. (Remote Console server and client can be found in NT resource kit)

Documentation covers read-only part of the site API. If you find useful implementation of some public pages that can modify site DB please tell us. Our view is: This site is design part, Shopping carts, guest books, profiles etc. are separate applications (of course they can be integrated with this site and we offer such solutions).

We provide sample site with no design to be used as sample or as base of your site development.

Copyright 1999 ZmeY soft Web Development Team (www.zmey.com)

For information about our site engines and ActiveX-es use this URL http://products.zmey.com

Report problems at: support@zmey.com


Site management

Every installed site has a virtual directory named /admin. Depending to the installation options it will be accessible for administrators and site owners. Installation option responsible to give access to the administrative forms is -user (see How to install ).

User interface of administrative forms uses several rules:

  • Current category - when you select from menu (at left side of the pages) type of site objects to edit you will see list of defined categories for this type. To edit related objects you must select this category by choosing it in drop down box and clicking Change XXX button.
  • Current language - language selected in a dropdown box on top of most of the pages.

These settings are active for about 20 minutes - if you do not perform any action for such a period you must reselect them. Time-out is determined by session time-out of the site - you can change it using Microsoft Management Console.

The actual site can use CorpSite objects for different purposes. You must know what they mean in case of your site. All objects are current-language-dependent (except categories and products). This means that in typical situations the same object structure must be defined for every supported language (eg. you may have to translate your stories, resources and menus)

You can upload files to your site in some of the virtual directories - images, downloads, pages and data. We not recommend uploads in /data directory but it may be useful if some extensions are made in CorpSite (or "hard" DB updates), but typically you will never need this feature.


Guidelines on building a site

Guidelines on building sites.

You can use the objects, implemented in the site engine for different purposes. There are some typical ways, thought. One is:

Linking stories to products & product categories

You are building a site for company that will have several categories of products with story for every product and every category of products (group description). You can do the following:

Add all category products, add some products in every category. Design page for one-product information and place there a script that will list one product name, optionally some prices and its linked story. Your page must be referenced by some other page with parameter that will determine product to show. You can receive this parameter in the query string or by submitting a form (with post method). If you are using query string it is not good idea to pass ID of the product (because IDs can change when updating, etc.), but it is absolutely possible. We recommend using query instead of form, because pages called via query will be indexed just as the search engines (like AltaVista) do. Of course calling page with short name of product in query string parameter requires some more code lines than using product ID but in this case URL will be human-readable and more secure (for product updates).

see:
GetProduct
 GetStoriesByProductID

Using stories as category descriptors

Page that will refer to your product page will be your product category page - it will show general information about this type of products and list of all products in category (in a table or list). You can implement this page in following manner:

Suppose that page was called with parameter in query string that supplies category name. Get story or stories linked by GroupID to this category and display them. Then get all products of this category and list them in table or some other list. To implement links to the product page you can place product names in links that will call your product page with parameter with product name (see above text).

see:
GetStoriesByGroup
 GetProductsByCategory

Listing stories of one category

To implement a home page, about page, news page, etc. you can display a list of stories with a certain category (like "NewsStories","HotLinks", etc.). These pages you can implement as one page that will be called with different parameters - for example the list's category name. Then you will need only to get its stories and display them (with their LinkURL and/or ImageURL where needed).

see
GetStoriesByCategory

Listing stories as highlights

In most cases your home, about, news etc. pages will contain some highlights - stories with links to some products or product category - to do this proceed with GetStoriesByCategory and list this stories with appropriate design.

To list addresses and other types of short information of the company you can use resources and list category of resources.

see
GetResource

We recommend unique names for internal object names. If names are not unique you can expect problems with some functions. This is required for objects of one category (eg. resources, products, etc.) and recommended for objects of one type (it will be easy for you to get story only by name). Categories can share same names but we do not recommend do this for same type of categories - results are not defined (some functions allow category names to be used).

Implementing menus

Site engine gives you powerful features to create and manage menus with any style and design. Some automation for displaying vertical menus, is provided with the function BuildMenu() (it generates a renders the menu in table; each item below its predecessor). If you want to display a menu horizontly or anyhow, you must write your own rendering routine - using GetMenu(), GetMenuArray(), etc.

There are some fields in menus and menu items that handle style (all inline-style parameters in <td> and <table> tags). You can use them as you see fit, but you must instruct administrators to fill there the right values. If you choose to build your own menus the best way will be not to use these fields for layout or to use only style fields associated with the entire menu to avoid administration mistakes.

see:
GetMenuArray
 objects Menu and MenuItem

Listing categories

It is often needed to list some categories - for example all product categories (eg. "Motherboards", "CD-ROM Drives", etc.). You may need to display a bit longer text than the category's display name. This task can be done by using stories linked to these categories (by GroupID) or by using resources linked by name - resources with same internal name like category name. This can be useful for multilingual sites.

see:
GetCategories
 GetStoriesByGroup
 GetResource


Site Setup Helper

ZmeY soft CorpSite Site Setup Helper

Because our install script setupsite.cmd uses a complex combination of command line parameters, its usage can be difficult. So we created this helper to assist you in constructing the correct command line for setupsite.cmd.

To use it, just choose approriate settings and click "Generate command line". Then copy the generated text and execute it from console.

Some terms and notes:

  • Site name (it appears listed in IIS's Managment Console tool) and Root directory (place, where the site's files are copied), are required parameters and must be always entered.
  • If a site is assigned to answer on "all IPs", this means that you do not have to enter an IP address.
  • You will need to enter TCP port only if you have choosen that the site will operate on special TCP port. Otherwise the default port (80) is used.
  • Sharing same IP between several sites is accomplished by using different host names for sites, answering on the same IP. If you choose IP sharing, enter the shared IP and different host names for each site you create. This technique is known as "Virtual Web Servers".
  • Enter only an IP address, when have choosen "Site will operate on own IP".
Final note: This helper was designed to run on Microsoft Internet Explorer 4.0 (or later) or Netscape Navigator 4 (or later).
Site name:
Root directory:
Computer name:
Virtual server:
IP address:
TCP port:
Host name:
Administrators Group:
Owner of the site:
Base group:
Automaticaly start the site after creating

Copyright © 1999 ZmeY soft. Contacts: support@zmey.com


Caption

Corporative site template reference ZmeY soft


Category object

Type | Name | Description
ID | CatID | ID of the category
String | CatName | Name of the category
String | DisplayName | Display/readable name of the category
ID | CatTypeID | ID of category type

Category Types:

ctMenu = 1 | Category is menu. Menus are created using resources
ctMenuItem = 2 | Menu items - resource groups bolnging to the Menus
ctSystem = 3 | Used for system information
ctReserved1 = 4 | Currently not used
ctReserved2 = 5 | Currently not used
ctHidden = 6 | Hidden category - will not be displayed in lists
ctResource | Resources
ctProduct | Product records
ctStory | Stories
ctAllNonSpecial | Used in some functions to return all categories - excluding first 5


Menu and MenuItem objects

Menu object

Type | Name | Description
ID | CatID | Menu ID (Menu category ID)
String | IntName | Internal name of the menu
String | title | Title of the menu (displayable text)
String | headStyle | Style of the table - parameters (including style) to be placed in the <TABLE ...> tag
Number | itemsCount | Count of items in the menu
Array | Items | Array of strings - names of the menu items. You can obtain items by calling GetMenuItem function for every item name

MenuItem object

Type | Name | Description
ID | MenuCatID | Menu ID (Menu category ID)
String | IntName | Internal name of the menu item
Number | OrderTag | Order tag of the item (Array is by default sorted by this tag)
Boolean | fHidden | Is to be hidden
String | bodyText | Text of the item (display text)
String | link | Link - URL pointed by this item
String | headStyle | style for <td> tags - all parameters (not only style tag) in <td> tags used to build menu. Useful for BuildMenu function.


Resource object

Product object

Type | Name | Description
ID | ProductID | Product ID
ID | CatID | ID of the category
String | ProductName | Name of the product
String | Price1 | Price for the product
String | Price2 | Price for the product
String | Price3 | Price for the product
String | Price4 | Price for the product
Date | DateAdded | Date on which product was added to DB
String | cartURL | Contains URL of the add-to-cart page
function | PlaceSimpleForm() | Places simple form for adding product to cart (uses buy.gif in /img directory)
boolean | Shopping | Is product available for shopping

Products are objects representing customer products in the site. They have only one name for visual and non-visual purposes. Every product belongs to a specific category - and actual list of products in a category or can be obtained through function GetProduct() by ProductID.

Also how many (and which) of the prise fields are used, depends wholy on the site design (i.e. you can use all 4 fields or less - its up to you).


Resource object

Type | Name | Description
ID | ResID | Resource ID
String | ResName | Resource internal name
ID | CatID | CatID of the resource category
Number | OrderTag | Used for ordering in internal queries
String | ResValue | Value of the resource
Bollean | fHidden | Is resource to be hidden


Story object

Type | Name | Description
ID | StoryID | Story ID
ID | CatID | ID of the category
String | Lang | Language string
String | StoryTitle | Title of the story
String | StoryName | Internal name of the story
Memo | StoryText | Text of the story
String | LinkURL | URL
String | ImageURL | URL
Boolean | fHidden | Show or not
int | OrderTag | Used for ordering
Date | DatePosted | Posted on
ID | ProductID | Related product
boolean | HasImage() | returns true if story has attached image
boolean | HasLink() | returns true if story has Link


Glossary

Object names and terms overview

Here are the descriptions of some fundamental objects and terms, used in ZmeY CorpSite Template.
Menu
A menu is a sequence of menu items. It has a title and header style
Menu Item
A line of a menu. It has a name, header, and hyperlink to an URL (page address).
Category
A container for stories, products, resources, etc. Categories has a name, type (what type records to hold) and display name (name, displayed to the end-user)
Story
A story is a short or long piece of text that is inserted in your pages. Stories can be edited and thus change the apperance of your pages. They can be hidden (meaning the end-user won't see them). Also, each story has two extra links. The first is link to a product (used to write more info about given product) and the second is link to a category (used for grouping several stories, thus called GroupID). These two extra links are optional and are used only in special cases.
Product
Just one of your items in stock - it has a name and several prices.
Resources
A resource is a simple name-value pair of information. They can hold any type of information - from prices to addresses. Resources appear at fixed positions in pages. Like some of the other, they can be hidden. Also, they has an "Order Tag" - that is a number that is used to sort the resources when they are displayed to the end-user. An "Order Tag" equal to 0 is the first, 1 is the second and so on. All resources in a category are always sorted by Order Tag.