revJournal - Revolution Tutorials

MacAddict Forum Reader

by Sarah Reichelt

Let revJournal columnist Sarah Reichelt take you to revSchool with a step-by-step tutorial for building your own MacAddict Forum Reader...

In the February 2004 issue of MacAddict magazine, there was a article in the HowTo section, showing how to use RealBasic to create an application that would list the various forums at the MacAddict web site and for each category, list their sub-sections.

Always keen to prove that anything that can be done with RealBasic can be done more easily with Revolution, I decided to duplicate the exercise with my favorite tool. For non-Mac users, I realise you won't be interested in the MacAddict forums, but hopefully you will still be able to learn something from this mini-tutorial and perhaps apply it to something of more interest to you.

The first step is to start up Revolution and create a new stack by choosing "New Mainstack" from the File menu. Open the Stack Inspector and give your new stack a name. You will see that the name appears in the title bar of your new window with an asterisk after it. This indicates that the stack is editable, but if you don't like it, enter a label for the stack. This can be the same as the stack name or different, but the label is what appears in the title bar. I generally set the stack name to something short and use a longer descriptive label. For this project, I'll set the stack name to "MAForums" and the label to "MacAddict Forums Reader".

While we are in the Stack Inspector, let"s set up a few other things. Go to "Colors & Patterns" and choose a background color for your stack. Then choose a foreground color - this is the color for your text. Of course any object can have these settings changed, but the colors chosen here will be the defaults. Now go to "Text formatting" and choose a font and font size. Resize your stack window so that it is roughly 500 pixels wide by 400 pixels high.

Forum1

Next we want to add the objects we will need. There aren't many: 2 scrolling list fields, 1 field, 1 button, and 2 labels. Use the Inspector to name the fields as follows:

- the single line field at the top is named "Address"
- the left-hand list field is named "Categories"
- the right-hand list field is named "Forums"

For the scripts to work, these must have the specified names, but you can arrange them in any way you see fit.

Give the button a name too; I called mine "Load" as it is going to go to the web site and load the data.

The only other object we need is a graphic to show that the computer is busy while it downloads the web page. Go to the Development menu and choose "Image Library". Scroll nearly to the bottom and you will see an circling arrows graphic. Select it and click "Place Image" to add a copy of this graphic (an animated gif) to your stack. Now close the library and you will see the new image in the middle of your stack. It is very hard to drag such a small transparent image, so while it is still selected, move it using the arrow keys (Shift-arrow moves it faster). I put mine beside the Load button. Change it?s name to "Busy". Use the alignment tools in the Inspector to get your objects neatly arranged however you would like them, then save the stack.

Forum2

We now have the layout of our application, so we need to give it some brains. Our scripts have to perform three tasks:

1. Download the page from the MacAddict site, find the categories and the forums in each category.

2. When the user clicks on a category, show the forums for that category.

3. Go to the web page for a forum, when it is selected.

The web page address is: http://www.macaddict.com/phpBB2/. Type or paste this into the Address field so the program knows where to get the data. Then select the Load button and open it?s script editor. It is going to use Revolution?s built-in URL commands to retrieve the data and by using a callback message, we aren?t going to stop anything else from happening while the web page downloads.

Type (or copy & paste) this script into the editor, then save the stack:

on mouseUp
  show image "Busy"
  put field "Address" into tAddress
  load URL tAddress with message processWebPage
end mouseUp

This shows the circling arrows graphic (we haven?t hidden it yet, but we will), gets the address you typed into the Address field, and then loads it. When the page has completely downloaded, the processWebPage handler will be called. That being the case, we?d better write one :-)

Copy & paste this into the Load button?s script after the mouseUp handler.

on processWebPage
  put field "Address" into tAddress
  put URL tAddress into tRawData
  unload URL tAddress
  -- loop through data once to find all the categories
  put empty into tCategoryList
  put quote & " class=" & quote & "cattitle" & quote & ">" into categoryStart
  put "<" &"&"/a" & ">" into categoryEnd
  -- I had to break up that string so it would show properly on a web page :-)
  put the length of categoryStart into categoryLen
  put 0 into lineCounter
  repeat for each line L in tRawData
    add 1 to lineCounter
    if L contains categoryStart is false then next repeat
    put offset(categoryStart, L) + categoryLen into startChar
    put offset(categoryEnd, L) into endChar
    put char startChar to endChar-1 of L & tab & lineCounter & cr after tCategoryList
  end repeat

  delete last char of tCategoryList
  put tCategoryList into field "Categories"

  -- loop through the data a second time to find the forums
  put empty into tForumList
  put "<"&quote&"span class=" &quote&" forumlink" &quote&"<a href="&quote \
      into forumStart 
put quote &" class="&quote&" forumlink"&quote&">" into forumEnd put the length of forumStart into forumStartLen put the length of forumEnd into forumEndLen put 0 into lineCounter repeat for each line L in tRawData add 1 to lineCounter if L contains forumStart is false then next repeat put offset(forumStart, L) + forumStartLen into startChar put offset(forumEnd, L) into endChar put char startChar to endChar-1 of L into tSite put char endChar + forumEndLen to -1 of L into tName get offset("</a>", tName) delete char it to -1 of tName put tName & tab & tSite & tab & lineCounter & cr after tForumList end repeat delete last char of tForumList set the cForumList of this stack to tForumList hide image "Busy" beep end processWebPage

I don't intend to step through this code line by line, but here is what it does:

It gets the URL data that has already been downloaded, then unloads it to save memory. Then it steps through the data once to find each line that contains the snippet of HTML identifying a category. It stores the category titles AND their line numbers. You see the reason for this later. These are shown in the Categories list field.

The data is looped through again to find all the forum titles and this time, the script finds their web addresses as well as their names and line numbers. These are not displayed yet, because we only want to display the forums in a specific category, so this list is stored in a custom property.

Although we aren't finished yet, we have done enough to test, so save your edited script, save the stack, change to the browse tool and click the "Load" button. After a few seconds, the computer will beep and you will see a list appear in the Categories field.

We put the categories on display but we used a custom property to hold the list of forums, so open the stack inspector again and have a look at the ?Custom Properties? section. You should see one called "cForumList". Click on it and check that the list of forums has been filled in.

Our list of categories isn't very tidy because it is showing the line number of each entry. We don't need to show these but if we set a tab stop which is greater than the width of the field, they will effectively disappear. Select the Categories field, open the Inspector and go to the Table section. Enter 500 in the Tab stops field and press Enter. The line numbers will disappear.

Forum3

Now we can move on to item 2 in our list of scripts: showing the list of forums for a selected category. Since this has to open after a category has been clicked on, we are going to put this script in the Categories field. Select the Categories field, open it's script editor and paste this in:

on mouseUp
  set the itemDelimiter to tab
  put the hilitedLine of me into lineNum
  put item 2 of line lineNum of me into startLine
  put item 2 of line lineNum+1 of me into endLine
  if endLine is empty then put 9999 into endLine
  put the cForumList of this stack into tList
  put empty into tForums
  repeat for each line L in tList
    if item 3 of L > startLine and item 3 of L < endLine
    then put L & cr after tForums
  end repeat
  delete last char of tForums
  put tForums into field "Forums"
end mouseUp

Now you can see why we needed to save the line numbers of each category and forum link. We use them here to decide which forum falls into which category. This script gets the line number of the selected category and the line number of the next one, allocating a huge number for the next category if it is the last one. Then it checks each of the forum entries to see if it falls between those numbers. If it does, then it must be within the selected category.

Save this script (and the stack) and test it by clicking on a category. You can see that we have the same problem that we had with the categories: the list is untidy because of the extra information that is still showing. We will hide it in the same way, by setting the tabStops. Select the Forums field, go to the Table section of the Inspector and set the tabStops to 500.

Forum4

Now we have just the last step left: loading the correct web page when a forum is selected. If you check the custom property cForumList, you can see that the 2nd item on each line is part of a web address. It is a relative address and the data in the Address field needs to be put in front of each link to make it complete. Once we assemble the complete address, we only need to call the standard Revolution command "revGoURL" to load the correct page in the default browser.

Here is the script that needs to be in the Forums field script:

on mouseUp
  set the itemDelimiter to tab
  put item 2 of the selectedtext of me into tURL
  revGoURL field "Address" & tURL
end mouseUp

Save the script and test by clicking on a forum name. Your browser should start up and the relevant forum page should be loaded. Save the stack.

OK, that?s it. You now have a basic forum reader. There are extras that could be added, e.g.:

- showing more details like number of posts, date of last post
- showing the first category automatically after loading
- automatic updates
- error checking in case the computer is not on line or the web page is not available
- geometry settings to handle window resizing

but I'll leave that up to you.

Hopefully, you now have some knowledge of how you can use Revolution to load and extract data from a web page and then use that information to go back to another web page. There are undoubtedly many other ways to do the same job and maybe some are better, faster or more efficient. If you have some other suggestions, send them in :-)

If you don't want to create this yourself, but would like to download the stack, click here.

This technique can be used for gathering data from almost any web page: weather reports, page updates, stock prices, sports results, etc.

For those interested in comparisons, this uses 67 lines of script. The RealBasic version used 5 property declarations and 92 lines of code! (The line counts do not include comments or blank lines.)

Until next time,
Sarah

© 2006 Fourth World Media Corporation All rights reserved. Portions copyright by the original authors.