There are essentially two approaches to implementing a web service in your LiveCode stack—building an interface based on a published API, or "mining" the source code of existing HTML pages. Regardless of the approach you take, once you have discovered the API, the way to implement web service access in LiveCode is identical.
First, create the form in your LiveCode stack by building the interface with all of the control objects you need. Let's follow the etymonline.com example, as it is fairly straightforward.
The form on the web page looks like this:
The search term field is easy—just create a text entry field in your stack called "searchTerm".
There is also an option menu on the web page, for specifying the search mode. It's easy enough to create an option menu—just drag one onto the card and name it "searchMode". But getting it to work right requires a little more thought. The problem is that the visible choices on the menu don't exactly match the actual searchmode argument code that you need. (Compare the choice "Find exact phrase" with the
name=value pair it creates in the arglist: "
searchmode=phrase".) That means we have to keep two lists for the option menu—the visible text in the popup list and the list of actual searchmode codes, as we see in the table above.
How to connect the option the user chooses with the code? One way to do it is with a custom property of the searchMode menu. Copy and paste the list that is to appear as choices into the Menu items field of the button's property inspector. Then go to the Custom properties panel and create a custom property called searchModeValues. Copy and paste the list of codes into the custom property contents. Now when you need to get the value of the selected option in the option menu, you will get
the menuHistory property of
btn "searchMode". That gives you the line number of the option chosen. Now use that to get the corresponding line number of the searchModeValues custom property. The code for this is shown in item b. below.
Now you have to write a handler in your "lookup" button that assembles the URL, submits it and then shows the results in field "definition". Remember that it is important to convert spaces and other non alphanumeric characters to a form that lets them traverse the internet safely. LiveCode gives us a function to do this, called
Here's how it works.
Earlier you created an option menu called "SearchMode". You build your arglist out of the user inputs to
field "searchTerm" and
button "searchMode", making sure you pre-process the
value portion of each
name=value pair with
put the menuHistory of btn "SearchMode" into tModeNum put line tModeNum of the searchModeValues of btn "searchMode" into tMode put "?search=" & URLEncode(fld "searchTerm") & \ "&searchmode=" & URLEncode(tMode) into tArglist -- tArglist should be ?search=fool%27s+gold&searchmode=phrase
Once your arglist is built, all that's left is to build your complete URL and "submit" it to the host server. Use a simple
put URL statement:
In your "lookup" button:
put url ("http://www.etymonline.com/index.php" & tArgList) into tReturnedData
tReturnedDatawill most likely contain raw HTML code. That means you'll have to examine it to determine where the desired data is. The returned output will always be in the same general format, so you can safely design a strategy for parsing out what you need.
In this example, a scan through the returned HTML output reveals a section that looks like this:
<div id="dictionary"> <dl> <dt class="highlight"><a href="/index.php?term=fool">fool (n.)</a> <a href="http://dictionary.reference.com/search?q=fool" class="dictionary" title="Look up fool at Dictionary.com"><img src="graphics/dictionary.gif" width="16" height="16" alt="Look up fool at Dictionary.com" title="Look up fool at Dictionary.com"/></a></dt> <dd class="highlight">late 13c., from O.Fr. <span class="foreign">fol</span> "madman, insane person," also an adj. meaning "mad, insane," from L. <span class="foreign">follis</span> "bellows, leather bag," in V.L. used with a sense of "windbag, empty-headed person" (see <a href="/index.php?term=follicle" class="crossreference">follicle</a>). Cf. also Skt. <span class="foreign">vatula-</span> "insane," lit. "windy, inflated with wind." <blockquote> "The word has in mod.Eng. a much stronger sense than it had at an earlier period; it has now an implication of insulting contempt which does not in the same degree belong to any of its synonyms, or to the derivative <span class="foreign">foolish</span>." [OED]</blockquote> Meaning "jester, court clown" first attested late 14c., though it is not always possible to tell whether the reference is to a professional entertainer or an amusing lunatic on the payroll. As the name of a kind of custard dish, it is attested from 1590s (the food was also called <span class="foreign">trifle</span>, which may be the source of the name). The verb meaning "to make a fool of" is recorded from 1590s. Related: <span class="foreign">Fooled</span>; <span class="foreign"> fooling</span>. As an adjective, <span class="foreign">fool</span> “foolish, silly” is considered modern U.S. colloquial, but it is attested from early 13c. <span class="foreign"> Feast of Fools</span> (early 14c.), from M.L. <span class="foreign"> festum stultorum</span>) refers to the burlesque festival celebrated in some churches on New Year's Day in medieval times. <span class="foreign">Fool's gold</span> "iron pyrite" is from 1882. <span class="foreign">Fool's paradise</span> "state of illusory happiness" is from mid-15c. <span class="foreign">Fool around</span> is 1875 in the sense of "pass time idly," 1970s in sense of "have sexual adventures." <span class="foreign">Foolosopher</span>, a most useful insult, turns up in a 1549 translation of Erasmus. <span class="foreign">Fool’s ballocks</span> is described in OED as “an old name” for the green-winged orchid.</dd> </dl> </div> <!-- DICTIONARY -->
Since the information we want is bracketed between
<div id="dictionary"> and
</div> <!-- DICTIONARY --> it is a simple matter to discover where these lines occur in tReturnedData and extract everything between those lines. Here's a possible approach:
put "<div id=" & quote & "dictionary" into tStartString put "</div> <!-- DICTIONARY -->" into tEndString put lineOffset(tStartString,tReturnedData) into tStartLine put lineOffset(tEndString,tReturnedData) into tEndLine put line tStartLine to tEndLine of tReturnedData into tDefData set the htmlText of fld "definition" to tDefData
<span ...> </span>tags with simple
There is a working example of this in the webServices.rev stack that is in the InClass/webservices folder on the DigHT 310 web site.
As an exercise to help you learn how to do this, find an example of a form that uses the GET method on a web site of your choice and convert it to run in a LiveCode stack. Make it polished, the way you'd want it if you were having strangers use it. That means the output is well-formatted and readable and the interface is reliable and easy to use.