Tech News Back Issues Issue: 092603

Introduction to the Omnis Web Client: Part 20, Search engine promotion part 2.

By Dr Caroline Wilkins
iB2B Systems Ltd

In this weeks newsletter we will take a short commercial break from the html interface graphing tutorial and return to the subject of web marketing. As more and more Omnis developers turn their creative energies to web-based projects, the issue of web marketing becomes increasingly relevant.

In the previous article on search engine promotion of a site (Jul 17, 2003), we discussed a basic strategy that consisted of choosing metadata, dmoz registration and search engine submssions. If you do nothing more to promote your web site, make sure that you have done those things! It is amazing how many commercial sites neglect to do so.

If you are serious about getting high search engine rankings and boosting your web site traffic, there is more that you can do to achieve this.

1. Traffic vs Rankings

Traffic and Rankings are not the same things, by any means. Rankings are the positions in a result set that your site appears on a given search engine. e.g. If someone searches Google for "software" and your site is listed at the top of the first page of results, it has given your site a no. 1 ranking for the search term "software". It will probably vary between search engines and will most certainly be different for various search terms. Traffic is normally measured as the number of visitor sessions that occur on your website. Naievely, we might expect Traffic to be dependant on Ranking, but it isn't quite that simple in practise.

  • High search engine rankings do not necessarily lead to high web site traffic. To start with, you should consider what keywords it is that you are ranking highly for. It is very common for a site to get a relatively high ranking for a keyword that has little to do with the product or service they wish to promote. This may earn you a few curious visitors, but is unlikely to lead to actual sales.

Secondly, the description of your site should be enticing to a visitor as this is what is often displayed in search results. If you have opted for a string of keywords or unreadable english for your description, search engine customers might be reluctant to click the link and come to your site.

  • Rankings are great for the commercial ego, but it is clickthrough, i.e. visitors to the site, that matter. This means that you should aim to get high rankings for words that are pertinent to your business. There is no point attracting visitors that are looking for something else and/or aren't likely to make a purchase or respond to your site as your would like them to.

Put yourself in the shoes of your customer. Imagine you are sitting at a search engine and want to find a company just like you. What would you type? Ask your friends and family what they would type too. Ideally, ask your customers. You can do that indirectly by examining your web site logs (which display search engine keywords). Those are the words that you should be targetting with your search engine marketing campaign.

2. Keywords

As discussed in the previous article on search engine promotion, some search engines pretty much ignore your choice of keyword and formulate their own, based on the content of your pages. This has a couple of implications:

  • It is not sufficient to put the keywords in the metadata, it has to appear elsewhere on the page. You should aim to incorporate your keywords in the visible text of the site.

A clever device is to also use the keywords in the ALT tags for images. ALT tags are like Omnis tooltips. They are displayed if graphics are missing (either by ommision of web design or through browser configuration) and are displayed by some browsers when a mouse hovers over the image they are associated with.

ALT tag text enables you to boost keyword relevance on the page without adding extra visible text. This is a powerful technique that is ideal for sites where you don't want to use a lot of text and prefer to be more graphical in your presentation of material. This technique alone has been known to add 50% to a sites traffic in a matter of weeks.

This tool will look at any web page you point it to and give you a word count. If the words it returns as your most frequently used words don't match your keywords, you might like to consider changing your web page until they do!

  • The more words you have on a page or indeed the whole site, the more often your site will be returned in search results. Of course, this also means that your site will be listed for commercially irrelevant keywords so this won't necessarily translate to revenue. Nevertheless, it doesn't harm to have this sort of traffic in addition to your more targetted traffic. For sites where a general audience is a desirable thing, it can be a very good strategy in fact.

3. Content is King

You can significantly increase your visibility on the web if you have a lot of content on your site. Search engines like Google will notice every word on your site and send you visitors as a result, so it is worth giving the engine lots to index. For this reason, it is a good idea to have features on your site that contain a lot of content. These might include discussion forums, feature articles, press releases, news items, weblogs etc. In the case of an Omnis developer, online manuals for their software would also be a good idea as it is a low-hassle means of generating a lot of content that is relevant to your business. Obviously, you have to be careful where on the site you put this sort of content as it will put customers off if too prominent. It should be possible to follow links from the home page of the site to these sort of search engine baits though.

Note also that this strategy will cause web users to enter your site by a side door rather than the home page, so it is important that they can see a clear link to your home page and a navigation structure which will give them an idea of what else they might find on your site. This reinforces the need for navigation that persists throughout a site.

4. Keyword popularity vs usage

When selecting keywords, there are 3 main things to consider:

  1. Pertinence to your business. This is obviously most important!

  2. Usage. i.e. are people typing these words into search engines?

  3. Popularity i.e. how many other sites are competing for these keyword rankings?

Pertinence is something that you can assess for yourself, based on an understanding of your business. Usage and Popularity are more complicated. If the web had been running for longer than it has, then we might expect Popularity to be matching Usage patterns. That would level the playing field for keyword competition. As it is, there are some words that people search for but for which there aren't many sites competing. Those are the words that will give you a strategic advantage! Whilst there are some words that you have to include in your keywords because they summarise your business, they may not bring you a lot of search engine visitors because the competition for that keyword (Popularity) means that your site's ranking doesn't make it into the top 30.


The tool from will enable you to identify related keywords and the Usage associated with each. It draws on search engine data and tells you how many searches have been performed for each keyword in the past month. You might also like to sign up to to get a weekly report on the top searchterms that are being entered into search engines. This will enable you to spot opportunies and trends. It can be quite revealing to discover what people are really looking for on the web!


The crudest way to assess the popularity of a keyword is to go to a search engine and do a search on it. If there are few results, then the keyword is either unpopular or the sites that are trying to use it are not being effective in their search engine strategy and so haven't got listed. If there are a lot of results returned, then you need to find a way to assess whether or not you are going to be able to compete. That means determining how strong the rankings are versus how numerous.

To do that, you should visit a few of the top listed sites for that word and examine their sites. Do they have a well-executed search engine campaign? i.e. is there well chosen metadata? Are they using the keywords in their text and ALT tags? If they are using it in their ALT tags, you can probably bet they know exactly what they are doing and are competing hard for the search engine rankings they have achieved. If, on the other hand, they are very well linked (from other sites), that may be compensating for a loosely executed search engine strategy. If you can match their links and do better with your own strategy, then you should be able to beat them on the search engine rankings.

Usage vs Popularity

The key to success (i.e. boosting your traffic) is finding pertinent keywords with high Usage and low Popularity. Services such as are designed to assist you with this, but you can achieve a good level of success using the methods described above.

5. Who's linking to who?

As discussed previously, the relevance and quantity of links to your site have a very significant effect on your search engine rankings.

Altavista and Infoseek enable you to find out what sites are linking to a given site. Simply type something of the following format into the search box:

link:site URL,  e.g.

Google allows you to do a "Page Specific Search" and locate links to it using the advanced search facility: Alternatively, search from the main Google homepage using a search string of the format: (as for Altavista and Infoseek).

This doesn't tell you the whole story of course (and from experience, this is a very incomplete listing), but gives you some means for comparison, based on that particular engines database.

If your competition is a lot better linked than your site is, then you need to negotiate some links in order to compete. You might start by following in their footsteps and getting links on those same sites as well as finding other sites to link to you. Negotiating links is a big part of running a website, so don't feel shy about emailing to ask for a link. It happens all the time and is expected. Just be polite and ask nicely. Compliment their site, point out the relevancy between their site and yours and offer a reciprocal link. Most webmasters will happily trade links in this way.

Hopefully, some of the above will give you some ideas to better promote your web sites and web services. We will discuss web marketing strategies beyond the search engine issues at a later date.



Context Menus

By David Swain
Polymath Business Systems

In the last few articles we have explored various ways of deploying menu instances. The devices and techniques we have examined so far are "static" ones in that a menu instance is created and then it sits around waiting to be used. The menu instance in these cases is either installed on a menu bar or contained in a popup menu field, but it comes into being as portions of the application are constructed and continues to exist (whether it is used or not) for a long period of time. Each such menu instance can be used again and again until it (or its container) is deliberately removed from the application.

But there are also techniques and mechanisms that allow us to deploy "dynamic" or "instantaneous" menu instances that come into existence only as the user needs them and then are destroyed after being used only once. There are three kinds of "instantaneous" menu instances that we can create: context menus, cascading menus and popup menus that are spawned from the Popup menu method command. The common element among all these is their ephemeral nature.

Because of this shared mode of origin and super-short lifespan, these types of menu instance share a few other characteristics as well. But each one also has its own unique qualities and features, so we will detail them one at a time. Let's begin with the context menu...

Purpose of a Context Menu

A context menu is a menu we choose to associate with a specific window field object or with the window as a whole. We can use the same menu class as the context menu for any number of fields or windows, but we also have the ability to configure instances spawned from that menu class differently for different objects if need be. A menu class that is used as a context menu could very well also be used as an embedded or popup menu or even as an installed menu, but we most likely will want to put in some code variations specifically for its use as a context menu to pinpoint the field or window instance that received the context click that launched the menu instance.

Since the invocation of a context menu requires clicking on a window or on a specific window field, the most common use of a context menu is to present menu lines that can each perform some operation that affects some aspect of the window or object that received the context click. That is, the methods behind the lines of the context menu will generally be used to either modify some property or to execute some method of the object receiving the context click. We will see later in this article that this requires that we know what that object is while executing methods within the context menu instance.

The Integrated Development Environment of Omnis Studio is full of examples of context menus. This collection taken as a whole contains menus that exhibit all of the programming options we can apply to context menus, so we will call upon them to demonstrate these options and then further illustrate how to build these options into custom context menus in our own applications.

For example, a context click on an item in the Class Browser opens a variation of the Class menu, which is also available from the menu bar embedded in that window. The differences between these two menu instances are due to the context menu's focus on a specific class. Some lines of the context menu instance created by this action further vary depending upon the class type of the target item. For example, the first line would read "Open Window..." if the target is a Window Class, "Install Menu..." if the target is a Menu Class and "Cannot open" if the target is a Schema Class. The "Cannot open" line is also disabled since there is no operation that can be performed in that case.

A context click anywhere else on this window opens a copy of the View menu, which is also available from the embedded menu bar. These two are exactly the same because their target (the Browser window) is the same. The lines of the Class menu launch operations that affect a specific class while the lines of the View menu launch operations that affect the Class Browser window, hence the difference in the two context menus.

Context and Embedded Menus of the Class Browser
class item context menu
class browser class menu
Browser Item Context Menu
Embedded Class Menu
class browser context menu
class browser view menu
Class Browser Context Menu
Embedded View Menu


Context Clicks

context cursorContext menus are common in many computer programs. Standards have evolved for their use so that users can more easily remember how to access them - but they are still invoked differently on different operating systems. On the various Windows operating systems (and others where a multi-button mouse is the standard), a click using the right-hand mouse button is understood as a context-click. On Macintosh machines (both OS X and Classic) where the one-button mouse is standard, holding down the Control key and then clicking the mouse button produces a context-click. When the Control key is first held down, the basic mouse pointer icon also gains an additional symbol to indicate this state.

$contextmenu Property

To prepare a window or window field to react to a context click by presenting a context menu, we must set its contextmenu property value to be the name of the desired menu class. If we use the Property Manager to do this, it provides us with a convenient dropdown list of all the menus available. All we need to do is select the desired menu class from this list. We can also set the value of this property through a direct calculation, but we are then responsible for spelling the class name properly. External menu classes must be qualified by the name of the library to which they belong as well.

contextmenu list of menus

The contextmenu property is a fundamental property of a window foreground component, so all window fields contain it - including all foreground external component fields. Window background objects (including external ones) do not contain this property.

A window class and most field types can only have a single context menu assignment, but there are some field types that by their nature can have two. List display fields generally have two distinct regions: the lines of the list being displayed and an area of "white space" where there are no lines. It is possible that these regions could benefit from entirely different context menus, so we can optionally assign a second menu class name to the contextmenu property that will spawn an instance if the white space receives a context click. This is, in fact, the mechanism used in the Class Browser example above for opening the View menu when a context click is performed on the white space of the icon array field (which is a form of list display field) that shows the class icons.

second menu class in contextmenu property value

The name of the second menu class must by typed in, however...

The Context Menu Instance

When a context click is performed on an item that has a valid value in its contextmenu property, an instance of the menu class named in that property is spawned. This instance is a member of the $imenus group of $root. Its order value is reported as 0, which indicates that it takes precedence over the normal group of installed menus, but the most interesting feature is the name that is assigned to it.

The name value of a context menu instance has three parts connected with underscore characters. These parts are 1) the name of the original menu class, 2) the number 5 (which apparently indicates this is a context menu) and 3) a number which appears to identify the window instance for which the context menu was spawned. Each time the window is closed and a new instance is launched, this number is incremented by a certain amount (I have noticed that this amount is usually 34). The same window instance number is used whether a context menu is opened for the window itself or for one of its fields - and no matter which menu class originates the context menu.

The tool we use to explore these values will be explained in just a few more paragraphs...

Configuring for the Context

When a context menu instance is brought into the world, its $construct method is executed just like any other instance. This can then be used to adjust aspects of the menu before the new instance is presented to the user. We can add, rename or remove menu lines and modify the code executed by them as dictated by the context in which the menu finds itself. The trick is that the menu needs some means to know where it is so it can set up the proper contextual configuration.

Construction Parameters

With most instances, we can send parameters to the $construct method with information on how the specific instance is to be configured. But it appears that we cannot send parameters to the $construct method of a context menu. As I had demonstrated many months ago (and will again in the next article), a cascading menu can be sent parameter values from the cascade property of the menu line that contains it. But the contextmenu property of a field does not appear to support this technique. Interestingly, although we can include a comma-delimited set of parameters enclosed in parentheses after the menu name in the contextmenu property value without affecting the validity of the menu class name, these parameters are not received by the $construct method of the context menu instance. I have not tested this on other platforms, but this is certainly the case on Mac OS X.

Without the ability to send parameters to the constructor method, we need to find another means of gathering configuration data.

$contextobj Property

A context menu instance has a special property that other menu instances do not. The $contextobj property of the menu instance is a reference to the object that received the context click that launched that menu instance. We can use this property to learn a great number of things about the context in which the menu instance finds itself (most useful in the $construct method of the class or of an individual line for performing custom configurations). We can also use it from within a menu line method generically to change the value of a property or execute a method of the target object.

A Quick Example

Suppose we want to create a Menu Class for use as a context menu with date-displaying masked entry fields that allows the user to modify the display format. For outward simplicity, we choose to present the current value of the associated date variable as the text of each menu line in the format that line would impose on the field. If the associated variable is empty, we would use the current date instead. When the user selects a line of this menu, the field receiving the context click will have its display format appropriately modified and will then be redrawn. (It is our responsibility to make sure we only use this menu as the context menu for a field displaying a date variable.) Here are the steps:

  1. Create a new Menu Class and name it "dateFormatter".
  2. Determine the date formats you wish to support and create a menu line for each. If there are more than three or four, you might wish to group them using separator lines.
  3. Create a $construct method and a $event method for each line.
  4. Place the following code in the $construct method of the first line, substituting your preferred format string for that shown here:

    If len($cinst.$contextobj().$contents)
       Calculate $cfield.$text as jst($cinst.$contextobj().$contents,'D:m D y')
       Calculate $cfield.$text as jst(#D,'D:m D y')
    End If

    Note the use of $cinst before and the parentheses after $contextobj. $contextobj is a property of the menu instance and it must be resolved for most uses.
  5. Place the following code in the $event method of that same menu line, again substituting the format string represented by that line:

    Calculate $cinst.$contextobj().$formatstring as 'm D y'
    Queue tab

    The queued tab is used to properly redraw the field contents. While the masked entry field has the focus and the contents of that field are redrawn, Omnis Studio uses the date formatting from #FD to display the date value rather than the formatstringfrom the field.
  6. Copy these two methods to each of the other menu lines. Make the appropriate adjustments to the format string values for each line. Then close the Menu Class.
  7. Create a new Window Class and name it "contextTester".
  8. Open the Method Editor for this class and create an instance variable of Short date 1980..2079 type. Name this variable "birthdate" and give it an appropriate initial value (like your birthdate).
  9. Place a masked entry field on the window and give its dataname property the value "birthdate".
  10. Assign "dateFormatter" to the contextmenu property of this field. Also make the formatmode property value kFormatDate and give the formatstring property an appropriate default value.
  11. Place another entry field on the window so the focus can be taken off the birthdate field.
  12. Now open the window in test mode and try it out!

Each line of the context menu should display the current value of the associated variable in a different format and selecting a line from that menu should impose that format on the display value of the masked entry field. Also try emptying the field (be sure to tab to the next field to transfer the empty value into the associated variable!) and notice that the current date is now used as the "format model" for the context menu lines.

Context Click Events

If a field contains a valid menu class name as its contextmenu property value, a context click on that field will open a context menu instance. If that field does not contain such a property value but the container in which it resides does, the context menu for the container will be launched when a context click is performed on that field. The container could be the window itself or a container field (tab pane, group box, etc.). The most immediate container in the containment hierarchy that has a valid contextmenu value receives the context click event.

The evOpenContextMenu Event

This event message is sent to the object whose context menu was opened. It allows us to detect and react to such events from the field side rather than from the context menu side. As mentioned above, this event is sent to the object whose context menu is opened, not necessarily the topmost object over which the mouse directly hovers.

The evOpenContextMenu event message is accompanied by two event parameters: pContextMenu and pClickedField. These are used to further define the players in a context menu event.

pContextMenu is a reference to the menu instance that is spawned by the context click. We can use this to learn more about the properties of that menu instance. For example we can use pContextMenu.$name to examine the name assigned to the context menu instance.

pClickedField is a reference to the field or window that received the context click. It is roughly equivalent to $cobj except that it does not have to be "resolved" (followed by parentheses) to return a useful value for such properties as $name. The manual states that this parameter is not sent (or is empty) when the context click is performed directly on a window, but in fact it simply carries a reference to the window instance rather than to a specific field. (Don't believe everything you read - including this article. Test this out for yourself!)

On evRMouseDown

Whether or not a right mouse button is available on the current operating system, the evRMouseDown event can be trapped as the beginning of a context menu event. This event can be used as an alternative to the evOpenContextMenu event in those cases where finer control is required. The difference is that evRMouseDown is reported for whichever field the mouse is over at the time of the event while the evOpenContextMenu event is reported only for fields with a valid contextmenu property value. evRMouseDown is also reported slightly earlier than evOpenContextMenu, as we will see a bit later.

In order for us to be able to trap this event, the rmouseevents property of the field must be set to kTrue. Of course, if this property is already switched on globally for the library, we do not need to set it for any specific field. If we need to trap this event for a window, we must set it globally for the library since rmouseevents is not a property of a window class or instance.

Because of the order of events, we can use the evRMouseDown event to change the value of the contextmenu property and launch an instance of a different menu class if necessary.

Order of Events

The order in which all this occurs is quite interesting - and an important thing to understand when using this technology for more complex situations. In the simplest case, the context menu's $construct method is executed, followed by the menu line $event method (and any subroutines) and finished off by the context menu's $destruct method. All this activity is set off by the context click. If we have also chosen to trap the evOpenContextMenu event, then the order goes like this:

Context menu $construct (and any subroutines)
Field or window $event (and any additional event handling levels)
Menu line $event (and any subroutines)
Context menu $destruct

That is to say, the context menu instance comes into being before the $event method of the object receiving the context click executes (otherwise the pContextMenu parameter would have to be empty), but the $event method of the selected menu line executes after the $event method of the clicked object.

The process gets more interesting when we also trap the evRMouseDown event. To keep this simple, consider that the field receiving the context click has a valid, non-empty contextmenu value trapping both evRMouseDown and evOpenContextmenu events. The sequence of method execution goes like this:

Field or window $event (reacting to evRMouseDown)
Context menu $construct (and any subroutines)
Field or window $event (reacting to evOpenContextMenu)
Menu line $event (and any subroutines)
Context menu $destruct

The evRMouseDown event cycle that begins this process can actually be used to change the value of the field's contextmenu property with no negative consequences! Whatever Menu Class is named in the contextmenu property when the context click is completed (evRMouseUp occurs) is instantiated as the context menu.

Command Key Shortcuts - Not

Ha! You thought there might be some secret way of using shortcut keys with context menus. Not so! We can only use command key shortcuts for invoking items of existing menu instances. Since a context menu instance does not exist until a context click is performed, we can't expect to have keyboard shortcut access to items on such a menu.

Only menus installed on the main menu bar or embedded in the menu bar of the top window can have their shortcuts recognized.

Next Time

I hope this article has helped you understand some of the nuances of using context menus. There is a lot more to explore, but we only have so much time and space here.

You may have noticed that some of the IDE examples of context menus have lines that contain cascading menus. In the next article we will explore cascading menus as well as some of the special programming we must do to help a cascading menu of a context menu to understand its context.


© 2002-2003 Copyright of the text and images herein remains with the respective author. No part of this newsletter may be reproduced, transmitted, stored in a retrieval system or translated into any language in any form by any means without the written permission of the author or Omnis Software.
Omnis® and Omnis Studio® are registered trademarks, and Omnis 7™ is a trademark of Omnis Software Ltd. Other products mentioned are trademarks or registered trademarks of their corporations. All rights reserved.