Squeak
  links to this page:    
View this PageEdit this Page (locked)Uploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
What Nevin was actually trying to do by converting strings into blocks?
Last updated at 4:26 pm UTC on 14 January 2006
Avi> Nevin, can you tell us what you were actually trying to do by converting strings into blocks?

Nevin >Yes, but it will take me a bit to explain it. It is in conjunction with Seaside and search engine spiders.

First, if you remember a thread on the Seaside list from back in March 2003, titled "[Seaside] anchors behaving like buttons?", you'll remember that I have code that allows the web user to invoke an arbitrary method on a component. For example...

http://www.bountifulbaby.com/seaside/index/viewcart

...will invoke the #viewcart method of the 'index' component, which would then take them to the shopping cart.

This scheme allows me to email somebody a URL that will allow them to enter the Seaside app at a relatively arbitrary point/page. Once they enter the app, though, it is thereafter tracked like any normal Seaside app, and thereafter has the normal Seaside URL's.

How the above scheme works is that I actually only have one component (the "index", or home page component), but it has an instance variable that can have different components assigned to it to control the actual contents of the current webpage being displayed. The "index" component. I also refer to as the "top" component.

I also have a subclass of WASession (which I call BBSession), that provides a method for accessing the "top" component (via #topComponent).

Thus far, I have the interesting situation where I can now call any arbitrary method of the top component from anywhere in the app. For example, suppose the app is on a page where the user clicks a button which invokes a method of that page, and within that method I have "self session topComponent viewCart". The result is that they can click the button and have the shopping cart shown to them. Yes, I know there are many other alternate ways to accomplish this same thing, but bear with me...

Next, I have added "WARenderer>>imageWithSource: srcUrl action: actionBlock ", per an earlier message of yours a few months ago. I have also added
 WARenderer>>imageWithSource: 
   srcUrl link: aLink 
per your earlier message. I commonly have code like this:

   html imageWithSource: aShoppingCartJPEGLink
           action: [self session topComponent viewcart]

(of course, the "viewcart" message in the block above might be some other method that the top component understands– I am just using #viewcart as an example).

Now, the idea is, if the WARenderer knows it is not servicing a spider, I want it to invoke #imageWithSource:action:, as shown above. But if it is servicing a spider, I want it to automatically do this instead:

   html imageWithSource: aShoppingCartJPEGLink
           link: "http://www.bountifulbaby.com/seaside/index/viewcart"

This approach results in spiders automatically seeing a static site with static URL's, and everybody else seeing a normal Seaside app. A way to do that would be to create a method somewhat like this:

   html imageWithSource: aShoppingCartJPEGLink
            method: #viewcart

...and then let the #imageWithSource:method: code either construct a static URL or a block, and then it calls one of the earlier two methods.

Then my code would always use #imageWithSource:method:. All spiders would then automatically see what looks to the spider like a static site with normal URL's, and everybody else would automatically see a normal Seaside site. Well, almost...

To finish the job of spiders seeing static pages, I have a page cache similar to what Cees did with Janus. So, for example, if my Seaside app sees this URL coming in:

http://www.bountifulbaby.com/seaside/index/viewcart

and if the requester is a spider, it checks the page cache for the #viewcart page, and if it is present, it feeds it back to the spider. If it is not present, it generates it, caches it, and feeds it to the spider. But for everybody else, it is just a normal Seaside app.


I never got the "blocks from strings" code working inside of this Seaside context. It worked fine attached to a test method of a test class, and seemed to capture the context of the test method just fine, but for some reason I couldn't get it to work inside of Seaside, within the WARenderer instance context. Not sure exactly why (maybe it's the lose nut above the keyboard or something :-), but after that is when I
realized that I really didn't need to get it working, because #perform: works just fine. So, chalk one up to embarrassment, for not seeing that solution sooner.

As for your comment that "This all sounds rather complicated", yes I agree. But I'm not sure how I can simplify it and still get all the features that it gives me (email-able URL's with multiple entry points into the app, auto-reconfiguration of the pages based on spider detection, etc.).