Since there's not a huge amount of activity on this list, it's somewhat hard to gauge just what's going on out there, seaside-wise. So I thought I'd throw some questions out that might help me figure out, as I amass little bits of time here and there to work on this stuff, what I should be doing.
First of all, how many of you are actively using Seaside? There are 35 or so people on this list, but Kamil and Alain are the only ones that I know have gone much further than looking through the tutorials. It would be good to have a better idea of where you guys are at, how interested you are, what's holding you back from using it more, etc.
Second of all, what should I be doing in the documentation department? I know that, eg, a tutorial on using subcomponents is long overdue, but have people managed to figure them out from the examples anyway? Would it be useful, when I don't have time for a full tutorial, for me to start throwing out random short descriptions of features that people might otherwise not know about? For example:
----------------------- BodyContent. Each embedded subcomponent has an implicit BodyContent element. This is used to insert the contents appearing inside the subcomponent's tag inside the parent template. For example, if you had a (rather useless) BoldItalicPage, you might use it in the parent template like so:
SomePage>>html ^ '<BoldItalicPage sea:id="sub">foo</BoldItalicPage>'
in which case, if you used BodyContent like so:
BoldItalicPage>>html ^ '<b>[BodyContent]</b><i>[BodyContent]</i>'
the final output would be <b>foo</b><i>foo</i>.
You can also bind values to the BodyContent element; if you do, these will appear as template-local variables in the scope of the body content of the parent element. As another silly example, if you have the following template in the parent:
SomePage>>html ^ '<BindToXPage sea:id="sub">this is a test: [x]</BindToXPage>
and the following bindings in the child:
BindToXPage>>addBindingsTo: template (template elementNamed: 'BodyContent') set: #x to: 'foo'
and the following template in the child:
BindToXPage>>html ^ '<b>[BodyContent]</b>'
Then you would get the following output: <b>this is a test: foo</b>
---------------------------------------------------
Third of all, what are the features that Seaside needs before people feel comfortable doing development in it? One obvious lack is good persistence support. For example, if it came with a lightweight object-relational mapping system, would it suddenly become much more viable? What if there were a connection to Oracle? What if there were a Squeak port of GLORP? Or, what if there were a VisualWorks port of Seaside?
I'm asking all of this because currently, development on Seaside is almost exclusively motivated by the needs of my projects, which may or may not have any bearing on the needs of others. I encourage y'all to speak out so that this can change.
Email me privately or respond to the list, but I'd like to hear from you.
Cheers, Avi
Avi Bryant wrote:
Since there's not a huge amount of activity on this list, it's somewhat hard to gauge just what's going on out there, seaside-wise. So I thought I'd throw some questions out that might help me figure out, as I amass little bits of time here and there to work on this stuff, what I should be doing.
First of all, how many of you are actively using Seaside? There are 35 or so people on this list, but Kamil and Alain are the only ones that I know have gone much further than looking through the tutorials. It would be good to have a better idea of where you guys are at, how interested you are, what's holding you back from using it more, etc.
Well, maybe I'll talk a bit about what I have so far. First, I am using Squeak to serve my site: http://www.smalltalkpro.com. Now, I'll admit that most of the rhetoric on my site is specifically addressed as a propoganda piece for the employees at my current gig (a *cough* Java gig). In other words, I don't really talk about Smalltalk or Squeak at my current gig-- I just point people to my site. I update my site to suit the conversations that are taking place at work. So, it is just a propoganda piece-- what I call a part of my "propoganda machine", whose propoganda is specifically tailored to my current (*cough*) Java gig.
As a propoganda machine, it is important to be able to showcase a *Smalltalk only* solution (with the exception of the html generation). Thus, I won't tolerate Apache, Tomcat, or anything else. It must be Squeak *only*-- otherwise it loses it's propoganda effect.
As a propoganda piece, it is also important to be able to separate the work done by a Graphics Designer from the work done by a Smalltalk Programmer. Furthermore, the Graphics Designer needs to be able to use any tool of his/her choice (Dreamweaver, FrontPage, or whatever), and the Programmer can take the html created from that tool and wire it to the backend. This is an *absolute* unnegotiable requirement at my Java gig, and thus it will also be an *absolute* unnegotiable requirement for my Smalltalk propoganda machine.
My wife's site (http://www.bountifulbaby.com) is also being served by the same server as my site. Besides it being a good sideline business for her, it is also actually part of my propoganda machine. At my current (cough) Java gig, they have several people working on an online catalog ordering system. My wife's site is also going to be expanded into roughly the same kind of catalog ordering system we are doing at work. The goal is to stay slightly ahead (functionality-wise) of what they have developed at work. And, do it with a 12 year old boy (my son Adam) working on it part time after school (but with my guidance).
If Adam can work part-time, and yet produce more functionality that they have at any given time on the project at work (thus keeping ahead of the expensive "professional Java team" at work), it will have a "slam-dunk" effect on the project at work when management gets wind of it.
That's what I am doing, and so far it is working. And, it is already beginning to stir some interest at work. And, I'm enjoying the effect immensely. It is a source of pride for me watching it actually happen.
OK, from this description, there are a number of things that become evident.
First, we *have* to be able to support virtual hosts (the gig at work likewise does). Thus, if you check the IP for "smalltalkpro.com" as well as "bountifulbaby.com", you will see they both point to the same machine--my server machine. The squeak server therefore must be able to synthesize a different "document Root" based on the incoming URL. This is how I've done that:
docRootForRequest: aRequest "For virtual domain support, we need to map a host to a local directory. This is how. There are numerous other ways this could have been done, but doing it this way means I don't have to update the map when I add another host. All I have to do is make sure the appropriate directory exists in '/home' (smalltalkpro, bountifulbaby, or whatever matches the host portion of the URL just before the .com or .org), plus make sure that directory has an htdocs directory." | tok domainDir | tok _ aRequest host findTokens: '.'. domainDir _ tok size > 1 ifTrue: [tok at: tok size - 1] ifFalse: [tok at: tok size]. ^ '/home/' , domainDir , '/htdocs'
I am using a Comanche/Seaside interface very similar to IAKom, and thus the #process: method knows the request argument, which in turn is passed into the method above. In this way, a web URL of, say, http://www.smalltalkpro.com will result in a document root of "/home/smalltalkpro/htdocs", and a web URL of http://www.bountifulbaby.com will result in a document root of "/home/bountifulbaby/htdocs".
Now on to the next thing:
I absolutely *must* be able to support allowing a Graphics Design person to use Dreamweaver to generate the html pages. If I don't do this, I lose a big chunk of my propoganda machine, because that is the strategy they are using at work. Fortunately, my son knows (and likes) Dreamweaver. Thus, all of the bountifulbaby.com pages were created with Dreamweaver. However, the requirement of using Dreamweaver for the html code severely limits my ability to use the html templating scheme that Seaside uses.
Now look at the "Past Work" page at: http://www.bountifulbaby.com/pastwork.ssp. This page was originally a "pastwork.html" static page created via Dreamweaver, but it is now a dynamic page that looks in a "pastwork" directory (under the doc root) for any jpg images in that directory, and serves those images. It gives each picture the baby name of the jpg filename that it found. Thus, to add to the list of babies on this page, all that Adam (or my wife, Denise) must do is drop the picture in the "pastwork" directory, and it is automatically served on this page.
OK, but how exactly was that done?
Our "IAKom" class (well, actually we've called it something else, and left the original IAKom intact) has the following #process: method:
process: aRequest "This is the required Comanche method that kicks everything off. Nothing else works until this method is properly run, and it will automatically be run by Comanche." | str | str _ self processStaticPage: aRequest. str notNil ifTrue: [^ str]. ^ self processSeasidePage: aRequest
The #processSeasidePage: is essentially the same as the original IAKom #process: method, but with a minor mod where we hardwired it to the "seaside" URL. Look at, for example, http://www.bountifulbaby.com/seaside/calc to see it in action, or any of the other example Seaside apps (minesweeper, whatever). You'll see 'em work.
But for the SSP side of things, the relevant portion of #processStaticPage: that handles the SSP stuff is this:
(file name endsWith: 'ssp') ifTrue: [str _ HTMLformatter evalEmbedded: file contents with: httpRequest] ifFalse: [str _ file contents]
Notice in this code snippet that the file being served by our custom "IAKom " (in the #processStaticPage: method) is checked to see if it ends in "ssp", and if it does, it passes it to the HTMLformatter (the same one that PWS uses for SSP) to process the SSP code.
Thus, to make the "pastwork.ssp" page work, Adam stripped out the html from his Dreamweaver code that generated the pictures, and replaced it with a single SSP call to a method we wrote together that walked the "pastwork" directory as described. We in turn stole his html from the original "pastwork.html" page and used it as a "guide" for the new method, so it's not like his original html was wasted work.
OK, so far, so good. But, there's no real Seaside involvement yet (besides the standard example Seaside apps that nobody really knows about that visits the site). So, what's next? I want to use Seaside, but you can see we haven't really used it yet. But I plan to as we move forward.
One thing we need is a clean way to grab modified Dreamweaver html and use it in a Seaside app. Some minor manual modifications (edits) to the html are OK, but we need to keep the required editing down to a minimum. If we have to extensively hack the Dreamweaver html to make it work, we lose our propoganda effect.
Yes, I realize I can use IAFileTemplate to have a file-based template, and have it load in the Dreamweaver html, and this is actually a good start. But, one of the immediate problems hit is how to serve the static content found in the Dreamweaver html-- JPG and GIF images, for example. We don't want to have to code an absolute path for these static images. Absolute paths suck-- what if you want to host the site somewhere else? This limitation would also be jumped on by the hounds at work.
We also don't want to have to write a bunch of bogus action methods in our Seaside IAApplication subclass to serve the images dynamically. We need true static content serving from a standard Dreamweaver html file well-integrated into a Seaside app. This bugs me.
What I am thinking of doing right now is intercepting the static file requests in our "IAKom" class, and munging the path to remove the "/seaside/app/5/top/1/view" stuff from the URL so that our custom IAKom class can serve it before it gets to the Seaside app. That way static resources (images and pictures) can be served before it gets to the Seaside side of things. But I don't see a clean way of doing this when the Seaside app served the original html that referenced the static resources. The only way I see (off hand) is by having my "IAKom" class detect the static resource in the URL, and then munge the URL to make it look purely static for Comanche.
But then, I'm not exactly a world-class pro with Squeak, Comanche, or Seaside right now, so we're both learning the tools. I'm primarily a VisualWorks person. The reason for grabbing these tools was also part of my propoganda machine-- the gig I'm at now thinks they want a purely open-source solution, without tying to any vendor, and they haven't figured out yet that Java is not open source and ties them squarely to Sun. That's actually addressed by my propoganda machine via the rhetoric at the bottom of my home page at: http://www.smalltalkpro.com. Management at my current gig has made a big-deal about not tying to any vendor, and yet simultaneously selected Java to develop with. They don't realize what they've done (how those two statements are so mutually exclusive), but when they do realize it, I want a strong example available using purely open source tools. It's all part of the propoganda machine.
And, my wife is actually making money with her site, too. So, no matter what the outcome of the propoganda machine, it's still a win for us. And, as a propoganda machine, we are further along (i.e., we have more functionality) than the Java team has at work. And, I'm confident we can keep it that way.
Anyway, you can see what we are up to. Any suggestions along these lines, to help fascilitate our goals, would surely be considered, and appreciated.
Nevin
Nevin Pratt wrote:
One thing we need is a clean way to grab modified Dreamweaver html and use it in a Seaside app. Some minor manual modifications (edits) to the html are OK, but we need to keep the required editing down to a minimum. If we have to extensively hack the Dreamweaver html to make it work, we lose our propoganda effect.
I might also add, stripping html out of the Dreamweaver output, and replacing it with a single line of SSP (Smalltalk) code, and then reusing the stripped out html in the Smalltalk image, fits very well within the guidelines required by my propoganda machine. As long as it is very easy for the Smalltalk programmer to take the Graphic's design produced by the Graphic Artist (who will be using Dreamweaver primarily), and plug it into the backend, then it passes.
The point is that the hounds at work think that a programmer should *not* be doing the graphic layout of the web pages, but that should instead be done by a graphic artist (one with rudimentary, or very basic, html knowledge). And, I think that is actually a very worthy goal (that is exactly why NeXTSTEP was always so pretty, in my opinion, because Steve Jobs had the same opinion that a graphic artist should do the UI).
The Java hounds at work are also using a high-overhead "Big Design Up Front" approach, and requiring a 10 inch stack of documentation to do anything. That will also help to make it easy for Adam to keep ahead of them.
Nevin
On Sat, 20 Apr 2002, Nevin Pratt wrote:
First, we *have* to be able to support virtual hosts (the gig at work likewise does). Thus, if you check the IP for "smalltalkpro.com" as well as "bountifulbaby.com", you will see they both point to the same machine--my server machine. The squeak server therefore must be able to synthesize a different "document Root" based on the incoming URL.
Hmm, haven't really thought much about virtual hosts with Seaside - no document roots to worry about, and my first thought would be to just redirect to the appropiate app, so http://foo.com would get redirected (by apache or whatever) to http://foo.com/seaside/foo. But obviously this is an issue when using Comanche for static content.
However, the requirement of using Dreamweaver for the html code severely limits my ability to use the html templating scheme that Seaside uses.
This is very interesting, since of course one of the main requirements for that templating scheme was precisely that it work well with Dreamweaver. More below.
Yes, I realize I can use IAFileTemplate to have a file-based template, and have it load in the Dreamweaver html, and this is actually a good start. But, one of the immediate problems hit is how to serve the static content found in the Dreamweaver html-- JPG and GIF images, for example. We don't want to have to code an absolute path for these static images. Absolute paths suck-- what if you want to host the site somewhere else? This limitation would also be jumped on by the hounds at work.
So, I think the issue here is that the defaults for the <img> tag used to suck. It used to be that <img src="@foo"> would create a path binding, that is, would look for a method named #foo and use the result of that as the src attribute (appended to the configurable "document root", which should maybe be renamed to something like "url prefix", of the app).
What it does now is uses a literal binding by default, so if your app is configured to have a doc root of http://smalltalkpro.com/images, then <img src="@foo.jpg"> will become <img src="http://smalltalkpro.com/images/foo.jpg">. Notice that this allows images to be served statically (likely even by a different webserver), without requiring hardcoded paths, or any funny business with IAKom. If you want this to be chosen dynamically (like your example of iterating over all the images in a directory), add an explicit binding to #resource, ie,
addBindingsTo: template (template elementNamed: 'myImage') set: #resource toPath: 'currentImage'
I'm not sure exactly when this change occured, but if you grab the latest source off SSVS it'll have it.
Now, I would like to see a better way of handling resources (so that, for example, dynamically generated images from within squeak become easier), and am open to suggestions for how this should work. But does that solve your immediate issues with using Dreamweaver?
Avi Bryant wrote:
I'm not sure exactly when this change occured, but if you grab the latest source off SSVS it'll have it.
What/where is SSVS?
When I grabbed Seaside, I grabbed it from: http://beta4.com/seaside (the "seaside-0.92.cs" link on that page). I did that about a month ago.
Now, I would like to see a better way of handling resources (so that, for example, dynamically generated images from within squeak become easier), and am open to suggestions for how this should work. But does that solve your immediate issues with using Dreamweaver?
That sounds very good--like it will work for what I need. I'll probably have time Sunday evening to grab the latest source and try it and see.
Thanks,
Nevin
Nevin Pratt wrote:
Avi Bryant wrote:
I'm not sure exactly when this change occured, but if you grab the latest source off SSVS it'll have it.
What/where is SSVS?
SSVS is what we developed for use as version control. More info here:
http://swiki.squeakfoundation.org/sea/3
Julian
Avi Bryant wrote:
So, I think the issue here is that the defaults for the <img> tag used to suck. It used to be that <img src="@foo"> would create a path binding, that is, would look for a method named #foo and use the result of that as the src attribute (appended to the configurable "document root", which should maybe be renamed to something like "url prefix", of the app).
What it does now is uses a literal binding by default, so if your app is configured to have a doc root of http://smalltalkpro.com/images, then <img src="@foo.jpg"> will become <img src="http://smalltalkpro.com/images/foo.jpg">. Notice that this allows images to be served statically (likely even by a different webserver), without requiring hardcoded paths, or any funny business with IAKom.
OK, I did the following:
1. Grabbed a "virgin" 3.2gamma image. 2. Made sure the image had all the latest 3.2gamma updates by selecting "load code updates" from the "Squeak" tab. It loaded and installed exactly one additional 3.2gamma update, for whatever that's worth. 3. Filed in 'kom49-base.11May354.cs' (the Comanche filein-- is there a newer one?) 4. Downloaded and filed in 'SSVS.cs'. 5. Evaluated the following: (SSVS forModule: 'seabed') update. (SSVS forModule: 'seaside') update. 6. Created an IAPastWork subclass of IAComponent. 7. Gave IAPastWork an #html instance method that returned a string. 8. Copied the html output from my son's old (static) 'pastwork.html' file he created with Dreamweaver to the #html method of the new IAPastWork class. 9. Defined a 'pastwork' seaside application to use the new IAPastWork component. 10. Started up an IAKom session on port 80. (for the following, note that my test machine is known on my internal network as 'test.com' or ' www.test.com') 11. Hit the following URL from my (Mozilla on Linux) browser: http://www.test.com/seaside/pastwork
It did not work. It did not display the static files referenced in the 'pastwork.html' code placed in the #html method. However, it displayed all of the rest of the html code. It just did not display the images.
In contrast, referencing the same html code using only Comanche, without Seaside, works fine: http://www.test.com/pastwork.html , so yes, all of the images are in place. Likewise, loading the 'pastwork.html' file directly into the browser again works just fine. So again, yes, all of the images are in place. But, trying to use the same html code in an #html method of a seaside app just doesn't work. The static images never get served.
Hopefully in a day or two I'll have more time to track down *why* it did not work. But in any case, I still don't see an easy way to use Dreamweaver html in a Seaside app.
Nevin
On Sun, 21 Apr 2002, Nevin Pratt wrote:
- Copied the html output from my son's old (static) 'pastwork.html'
file he created with Dreamweaver to the #html method of the new IAPastWork class. 9. Defined a 'pastwork' seaside application to use the new IAPastWork component. 10. Started up an IAKom session on port 80. (for the following, note that my test machine is known on my internal network as 'test.com' or ' www.test.com') 11. Hit the following URL from my (Mozilla on Linux) browser: http://www.test.com/seaside/pastwork
Ok, if you have relative urls for those images, they're not going to work *quite* that simply - obviously if your url is http://www.test.com/seaside/pastword/some/other/stuff, and you have <img src="foo.gif">, that's not going to come out as http://test.com/foo.gif the way you want it to.
You need to let Seaside modify that url, which means putting an @ sign in there, like this: <img src="@foo.gif">. Hopefully that's an acceptable change to make.
You'll also need to tell the Seaside app where your images are stored (eg, http://test.com/), so go into the configuration page for your pastwork app and set the document root to that url (or just '/' should work here). Programmtically, that's (IAApplication at: 'pastwork') documentRoot: '/'.
This make sense?
Avi
Avi Bryant wrote:
Ok, if you have relative urls for those images, they're not going to work *quite* that simply - obviously if your url is http://www.test.com/seaside/pastword/some/other/stuff, and you have <img src="foo.gif">, that's not going to come out as http://test.com/foo.gif the way you want it to.
You need to let Seaside modify that url, which means putting an @ sign in there, like this: <img src="@foo.gif">. Hopefully that's an acceptable change to make.
You'll also need to tell the Seaside app where your images are stored (eg, http://test.com/), so go into the configuration page for your pastwork app and set the document root to that url (or just '/' should work here). Programmtically, that's (IAApplication at: 'pastwork') documentRoot: '/'.
This make sense?
Avi
Well, nobody dumps ALL of their images in just one directory. They will always be scattered among a number of subordinate directories-- not just one. Therefore, the mechanism used needs to be able to follow a path down from the docRoot. And that doesn't seem to be supported (i.e., <img src="@path/image.jpg"> won't work).
I'm still inclined to change the "IAKom" code (actually, I've called it "IAComancheInterface" as to not touch the original IAKom) to hack out the seaside portion of the URL it sees when the end of the URL is ".jpg" or ".gif". After all, I can't think of anytime such a URL should *not* be statically served. Can you?
For example, wouldn't you *always* want <img src="foo.gif"> statically served? If you wanted it dynamically served, wouldn't you instead write <img src="@foo">, and not have the ".gif" extension?
Likewise, wouldn't you *always* want <img src="images/foo.gif"> statically served? Again, if you wanted seaside to dynamically serve it, wouldn't you *always* write something like <img src="@foo"> instead? (thus ommitting not only the trailing ".gif", but also the leading "images/" portion)
In other words, when using Comanche with Seaside, I would think that static images should be handled entirely by Comanche and not involve Seaside at all. But there doesn't seem to be any way to do that while simultaneously driving the html from the #html method of the seaside app, unless the Comanche/Seaside interface detects the ".jpg" or ".gif" extension and hacks out the seaside portion of the URL so that Comanche can handle it.
I see the same issues if you instead use Apache with Seaside. The problem is that Seaside doesn't integrate static content very well with its way of doing things (although for purely dynamic content, Seaside seems top notch).
Or at least, that's how it is all appearing to me. I'd love to be corrected, though :-)
Nevin
On Mon, 22 Apr 2002, Nevin Pratt wrote:
Well, nobody dumps ALL of their images in just one directory. They will always be scattered among a number of subordinate directories-- not just one. Therefore, the mechanism used needs to be able to follow a path down from the docRoot. And that doesn't seem to be supported (i.e., <img src="@path/image.jpg"> won't work).
It won't? Have you tried it?
Avi Bryant wrote:
On Mon, 22 Apr 2002, Nevin Pratt wrote:
Well, nobody dumps ALL of their images in just one directory. They will always be scattered among a number of subordinate directories-- not just one. Therefore, the mechanism used needs to be able to follow a path down from the docRoot. And that doesn't seem to be supported (i.e., <img src="@path/image.jpg"> won't work).
It won't? Have you tried it?
Yes.
Assuming a <img src="@path/foo.jpg"> example, where the docRoot of the seaside app is set to: "http://www.test.com/", it looks like it is trying to bind to a 'foo' instance variable, because it results in a walkback with message <Could not find value for key "foo">. This is because of an attempted <instVarNamed: 'foo'> lookup against my IATest instance, which of course errors because there is no "foo" instance variable.
But, if I instead just use <img src="@foo.jpg">, and instead put the image path in the docRoot (i.e., change the docRoot to: "http://www.test.com/path"), then it works like you said.
Nevin
Nevin Pratt wrote:
But, if I instead just use <img src="@foo.jpg">
^^^^^^^^^ But again, why would I ever want a trailing ".jpg" here? If there is a trailing ".jpg" (or ".gif", for the matter), wouldn't I *always* want it statically served? And in that case, why would I want the leading "@"?
Can you think of a counter-example where this idea is wrong?
And if not, should we modify Seaside to behave that way? Or should I handle it at the Comanche/Seaside interface (i.e., IAKom) (i.e., hack out the seaside portion of the URL when it sees the trailing ".jpg" or ".gif" so that the URL never gets dispatched to Seaside)?
What do you think?
Nevin
On Mon, 22 Apr 2002, Nevin Pratt wrote:
But, if I instead just use <img src="@foo.jpg">
^^^^^^^^^
But again, why would I ever want a trailing ".jpg" here? If there is a trailing ".jpg" (or ".gif", for the matter), wouldn't I *always* want it statically served? And in that case, why would I want the leading "@"?
Well, by "statically served" what you mean is "have a document root prepended". The @ is what's alerting Seaside that this tag should not be output verbatim, but should be treated specially. The @ is actually just a macro that Seaside uses by default; if you have another rule that you want to encode, it's quite easy to add another macro. It sounds like you want one that takes all <img> tags with a src attribute ending in .gif, .jpg, etc, and prepend a certain path to them. If you take a look at the Seaside-Macros category you'll see some examples to emulate. To see where they're used, look at IATemplate>>defaultExpander.
And if not, should we modify Seaside to behave that way? Or should I handle it at the Comanche/Seaside interface (i.e., IAKom) (i.e., hack out the seaside portion of the URL when it sees the trailing ".jpg" or ".gif" so that the URL never gets dispatched to Seaside)?
This makes me uneasy. I'd much rather see it done as a macro.
Avi
Avi Bryant wrote:
And if not, should we modify Seaside to behave that way? Or should I handle it at the Comanche/Seaside interface (i.e., IAKom) (i.e., hack out the seaside portion of the URL when it sees the trailing ".jpg" or ".gif" so that the URL never gets dispatched to Seaside)?
This makes me uneasy. I'd much rather see it done as a macro.
Avi
It makes me uneasy, too. Feels too much like a "hack".
I'll see if I can wrap my brain around the macro stuff tomorrow.
Nevin
Nevin Pratt wrote:
Avi Bryant wrote:
On Mon, 22 Apr 2002, Nevin Pratt wrote:
Well, nobody dumps ALL of their images in just one directory. They will always be scattered among a number of subordinate directories-- not just one. Therefore, the mechanism used needs to be able to follow a path down from the docRoot. And that doesn't seem to be supported (i.e., <img src="@path/image.jpg"> won't work).
It won't? Have you tried it?
Yes.
Assuming a <img src="@path/foo.jpg"> example, where the docRoot of the seaside app is set to: "http://www.test.com/", it looks like it is trying to bind to a 'foo' instance variable, because it results in a walkback with message <Could not find value for key "foo">. This is because of an attempted <instVarNamed: 'foo'> lookup against my IATest instance, which of course errors because there is no "foo" instance variable.
But, if I instead just use <img src="@foo.jpg">, and instead put the image path in the docRoot (i.e., change the docRoot to: "http://www.test.com/path"), then it works like you said.
Nevin
Just out of interest, does it work with <img src="@images\foo.jpg"> ??
Obviously not a solution but it would confirm my suspicion of the problem.
As for the reason to have @foo.jpg as the ID, the reason is that if I don't want to manually create a binding, I can give the id @foo.jpg which makes the element dynamic (because it has an id) and the id ("foo.jpg") is used by default as the name of the image (appended to the docRoot). If you just put <img src="images/foo.jpg"> then it wouldn't get the docRoot added, and if you put <img src="@foo"> then you'd have to write a binding when the default could have sufficed.
Julian
Julian Fitzell wrote:
Just out of interest, does it work with <img src="@images\foo.jpg"> ??
Hmm, sort of. It looks like it results in <img src="http://www.test.com\images\foo.jpg">.
But IAKom>>process: explicitly looks for "/" rather than "" (via "aRequest url findTokens: '/'"). Consequently, the URL isn't getting properly parsed for this case. So, no, it doesn't work, even though it sort of does. I think you see what I mean.
In other words, to make that work would again require hacking the IAKom code.
Obviously not a solution but it would confirm my suspicion of the problem.
As for the reason to have @foo.jpg as the ID, the reason is that if I don't want to manually create a binding, I can give the id @foo.jpg which makes the element dynamic (because it has an id) and the id ("foo.jpg") is used by default as the name of the image (appended to the docRoot). If you just put <img src="images/foo.jpg"> then it wouldn't get the docRoot added, and if you put <img src="@foo"> then you'd have to write a binding when the default could have sufficed.
Good point for not modifying Seaside for what I was thinking. But, if Comanche handles the static images instead of Seaside (which I'm still thinking should be the case if there is no leading "@"), it will automatically get appended to the docRoot (as Comanche understands it) anyway. Which brings me back to thinking about modifying IAKom again.
But then, I think I need to think about it some more.
Nevin
On Mon, 22 Apr 2002, Nevin Pratt wrote:
Assuming a <img src="@path/foo.jpg"> example, where the docRoot of the seaside app is set to: "http://www.test.com/", it looks like it is trying to bind to a 'foo' instance variable, because it results in a walkback with message <Could not find value for key "foo">.
Aha. So what's going on here is that each IAElement subclass is being asked whether they want that tag. Now, IAImage grabs <img> tags and IARepeat grabs anything with a / in the id. What must be happening is that IARepeat is being asked first. We need to find some better way of ordering this (for example, matches on tag take precedence over matches on attributes) so these sorts of things don't happen.
Avi Bryant wrote:
On Mon, 22 Apr 2002, Nevin Pratt wrote:
Assuming a <img src="@path/foo.jpg"> example, where the docRoot of the seaside app is set to: "http://www.test.com/", it looks like it is trying to bind to a 'foo' instance variable, because it results in a walkback with message <Could not find value for key "foo">.
Aha. So what's going on here is that each IAElement subclass is being asked whether they want that tag. Now, IAImage grabs <img> tags and IARepeat grabs anything with a / in the id. What must be happening is that IARepeat is being asked first. We need to find some better way of ordering this (for example, matches on tag take precedence over matches on attributes) so these sorts of things don't happen.
Yes, I remember seeing the IARepeat thing in the debugger.
Nevin
I am developing a web application for real estate agents. It is purposed as meeting point for the agents where they would have prepared advertisements from various sources. They would have a system for managing their own informations that would be private to them or to their companies. I am using PostgreSQL for storage but no object-relation mapping. I am quite new to smalltalk and OODB systems I know only from web pages. The database (object or relation) support in Squeak is quite primitive. I feel some simple generic layer for implementing database drivers is really missing. May be me need to study object-to-relation techniques little bit. Anyway, the project si so lagged that perhaps investor will have enough and tells me good bye. And yes, I am in Czech Republic and I can live fairly good with $100 a week.
In my opinion Seaside is winning when it comes to really advanced web applications.
On Sun, 21 Apr 2002, Kamil Kukura wrote:
The database (object or relation) support in Squeak is quite primitive. I feel some simple generic layer for implementing database drivers is really missing.
Yes, what I've done instead is stolen an existing generic layer. I keep a small java app running that accepts socket connections from squeak and forwards database queries through JDBC drivers; this lets me generically access Oracle, Postgres, etc, at a slight performance penalty.
A pure squeak solution would be preferable, of course.
Yes, what I've done instead is stolen an existing generic layer. I keep a small java app running that accepts socket connections from squeak and forwards database queries through JDBC drivers; this lets me generically access Oracle, Postgres, etc, at a slight performance penalty.
Yea I was thinking about that. JDBC is quite nice, but it lives only with that big fat toad called Java. I am examining the combination of Ruby + DBI/DBD + SOAP.
On Mon, 22 Apr 2002, Kamil Kukura wrote:
Yea I was thinking about that. JDBC is quite nice, but it lives only with that big fat toad called Java. I am examining the combination of Ruby + DBI/DBD + SOAP.
I imagine you'll find SOAP too slow; my initial JDBC bridge used XML-RPC but the performance was pretty bad for large result sets, so I switched to a simple binary protocol. But, yeah, Ruby-DBI is a nice way to go (hmmm... random thoughts of producing a Ruby Plugin for Squeak...)
I imagine you'll find SOAP too slow; my initial JDBC bridge used XML-RPC but the performance was pretty bad for large result sets, so I switched to a simple binary protocol. But, yeah, Ruby-DBI is a nice way to go (hmmm... random thoughts of producing a Ruby Plugin for Squeak...)
Wow. At first maybe calling druby (distributed ruby) from Squeak could be cool. I'm quite tempted by that idea...
Avi Bryant avi@beta4.com said:
Yes, what I've done instead is stolen an existing generic layer. I keep a small java app running that accepts socket connections from squeak and forwards database queries through JDBC drivers; this lets me generically access Oracle, Postgres, etc, at a slight performance penalty.
A pure squeak solution would be preferable, of course.
I think that you should be able to access PostgreSQL and MySQL from Squeak (IIRC, there's a Squeak driver for MySQL and the VW PostgreSQL driver has been ported). Both are probably direct socket interfaces.
Oracle and Sybase would probably be relatively easy as well with FFI.
Cees de Groot wrote:
Avi Bryant avi@beta4.com said:
Yes, what I've done instead is stolen an existing generic layer. I keep a small java app running that accepts socket connections from squeak and forwards database queries through JDBC drivers; this lets me generically access Oracle, Postgres, etc, at a slight performance penalty.
A pure squeak solution would be preferable, of course.
I think that you should be able to access PostgreSQL and MySQL from Squeak (IIRC, there's a Squeak driver for MySQL and the VW PostgreSQL driver has been ported). Both are probably direct socket interfaces.
Oracle and Sybase would probably be relatively easy as well with FFI.
You can access them but there is no db-independant layer. We've got around this by abstracting some stuff ourselves but in a case where you're writing something that is going to be re-used for multiple projects and the dbms' involved cannot be predicted, having a generic DBI layer is more than a nicety.
Julian
Julian Fitzell julian@beta4.com said:
You can access them but there is no db-independant layer. We've got around this by abstracting some stuff ourselves but in a case where you're writing something that is going to be re-used for multiple projects and the dbms' involved cannot be predicted, having a generic DBI layer is more than a nicety.
So start growing one.
Last time I did this I just started out with a db-dependent layer until the request for the first port came. That request hurt a bit, the subsequent requests hurt a lot less. Certainly I wouldn't take the absence of a db-independent layer as a reason to let Java enter the picture ;-).
(I'm a bit on my home turf here, having designed and implemented lots of ODBC and JDBC and even ODBC-to-JDBC-bridging stuff - JDBC and ODBC suck to a large extent, because Microsoft bloated ODBC beyond recognition and JDBC imitated that; the original X/Open SAG/CLI spec would probably be a reasonable starting point for a database independence layer. I'm not sure whether it floats on the Net somewhere; an old DB/2 programming manual would probably do, IBM used to stick close to this spec).
(I'm a bit on my home turf here, having designed and implemented lots of ODBC and JDBC and even ODBC-to-JDBC-bridging stuff - JDBC and ODBC suck to a large extent, because Microsoft bloated ODBC beyond recognition and JDBC imitated that; the original X/Open SAG/CLI spec would probably be a reasonable starting point for a database independence layer. I'm not sure whether it floats on the Net somewhere; an old DB/2 programming manual would probably do, IBM used to stick close to this spec).
Yes, I found DDJ's article about it (http://www.ddj.com/documents/s=953/ddj9613a/9613a.htm) And there is also DB2 Call Level Interface Guide and Reference (http://www-4.ibm.com/cgi-bin/software/db2www/library/document.d2w/report?&am...)
Because PostgreSQL connection is already there, I am looking forward when it could be wrapped as a database driver :)
I thought some time if I should post this message. Why? Because I haven't got the time to help you with the things I mention...
I'm asking all of this because currently, development on Seaside is almost exclusively motivated by the needs of my projects, which may or may not have any bearing on the needs of others. I encourage y'all to speak out so that this can change.
Email me privately or respond to the list, but I'd like to hear from you.
I went through the tutorials, too. Although I'm thinking I can't get used to the "squeak-philosophy", seaside is very interesting and I'm thinking how I could use it to enrich my homepage with some "active sugar", like a calculator for my worktime :-)
I need to learn more about OODBMS (like goods :-) to think about how and when to use them (I feel a bit unconfortable about storing things in RAM - especially without an USV); at this point, if I use seaside for data-based applications, I would use mysql or postgresql (having the ability to use the data with a lot of other applications and programming languages) as DBMS (just my opinion).
I think it would be useful to have all classes inline-documented; as I'm new to squeak and additionally, never saw something like servlets before - just php - I don't know "what's for what". Also, a short text like "a short journey to the seaside: exploring the code" would be nice (I think) to explain the programming newbies how they should start to understand what's going on, and how they could use it for themselves or to improve the framework.
But, as we all know: so many ideas and so little time... :-)
Regards, Markus
On Tue, 23 Apr 2002, Markus Fritsche wrote:
I think it would be useful to have all classes inline-documented; as I'm new to squeak and additionally, never saw something like servlets before - just php - I don't know "what's for what".
Did you read the class comments? Method comments would be nice too, of course.
Also, a short text like "a short journey to the seaside: exploring the code" would be nice (I think) to explain the programming newbies how they should start to understand what's going on, and how they could use it for themselves or to improve the framework.
That's interesting. Something else to add to the list of stuff to do...
Thanks, Avi
This is what I'm looking at doing with SeaSide. At the moment I'm trying it in Stephen Pair's swikinet stuff as well, but it just dosn't seem to work with my mindset. Lots of clever stuff, but somehow it baffles me...
Anyway the basic requirement is fairly simple seeming - I have to present tests consisting of multiple choice questions and record the answers.
The 'teacher' has to be able to choose groups of questions from a pool and assemble them into tests. There will also be a pool of pre-built tests. Teacher must be able to add new questions, which would be 'private'. Teacher must be able to add/remove students to the permitted users. Teacher must be able to see the results of all tests for students in some reasonable format (a table I suppose) and email the form to somewhere for record keeping (CSV type file would be fine and easy). Teachers will need login ids that permit them to do al the above.
Students will need login ids that permit them only to take tests.
Tests will be either 'practise' or 'graded'. Tests will consist of a modest number of questions, typically twenty or so. Practise tests may be taken several times by any student and the student will see both their grade and the correct answers at the end. Graded tests can only be taken once and the student see only their result. Graded tests may have a time limit attached - 20 mins, or whatever. The timing would start when the students hits the start-test button for the first question. Once the time limit is reached there would be no more questions presented and the results would be worked out. If the student finishes before any time limit they can hit a finished-test button.
Questions will (initially, there are dreams of more sophistication) consist of a text explaining the problem and a short (3-5) list of possible answers. The neat trick is that the list of answers will be re-ordered randomly each time they are presented to avoid students remembering "oh, that one was 'b' last time" so some way to remember the ordering used is needed. I'm assuming a session related var can do this.
We need to maintain the appearance of many separate areas, one for each college/teacher using the service (could be several teachers from each college I supose). I don't mind how that is done, but the swikinet DNS handler does a good job of making a single server respond to many URLs. Obviously there needs to be a nice simple way to add new colleges/teachers to the system. I imagine keeping that as the preserve of the overall admin person rather than allowing teachers to do it for themselves.
I managed to make a very simple testing demo in ComSwiki several months ago and then got lost in swikinet somehow. I think a part of the trouble is that it is very focussed on the swiki.net needs and digging out the infrastructure is hard work, even with Stephen trying to explain it. Of course, part of the problem is that I know a lot about the vm & low-level stuff but bugger all about writing applications.
So, all advice welcomed. I need to get this done _really_ quickly, I'm a long way behind on original estimates and things are getting desperate. I'll obviously need to know how to deal with permissions, logins, cookies, sessions, aaargh! Help Obi-wan WebPerson, you're my only hope!
tim
Tim Rowledge wrote:
This is what I'm looking at doing with SeaSide. At the moment I'm trying it in Stephen Pair's swikinet stuff as well, but it just dosn't seem to work with my mindset. Lots of clever stuff, but somehow it baffles me...
Anyway the basic requirement is fairly simple seeming - I have to present tests consisting of multiple choice questions and record the answers.
The 'teacher' has to be able to choose groups of questions from a pool and assemble them into tests. There will also be a pool of pre-built tests. Teacher must be able to add new questions, which would be 'private'. Teacher must be able to add/remove students to the permitted users. Teacher must be able to see the results of all tests for students in some reasonable format (a table I suppose) and email the form to somewhere for record keeping (CSV type file would be fine and easy). Teachers will need login ids that permit them to do al the above.
Students will need login ids that permit them only to take tests.
Tests will be either 'practise' or 'graded'. Tests will consist of a modest number of questions, typically twenty or so. Practise tests may be taken several times by any student and the student will see both their grade and the correct answers at the end. Graded tests can only be taken once and the student see only their result. Graded tests may have a time limit attached - 20 mins, or whatever. The timing would start when the students hits the start-test button for the first question. Once the time limit is reached there would be no more questions presented and the results would be worked out. If the student finishes before any time limit they can hit a finished-test button.
Timing should be pretty easy. You can store the start time in the session and compare it each time a question is submitted to see if the time has elapsed yet.
Questions will (initially, there are dreams of more sophistication) consist of a text explaining the problem and a short (3-5) list of possible answers. The neat trick is that the list of answers will be re-ordered randomly each time they are presented to avoid students remembering "oh, that one was 'b' last time" so some way to remember the ordering used is needed. I'm assuming a session related var can do this.
Ordering is non-issue. If you create a list of radio buttons, you give it a Collection of items. The actual item associated with the selected radio button is given to you so you can do a straight comparison. Or even just have a flag in the PossibleAnswer object that indicates whether it is correct. All depends how you implement your data objects of course.
We need to maintain the appearance of many separate areas, one for each college/teacher using the service (could be several teachers from each college I supose). I don't mind how that is done, but the swikinet DNS handler does a good job of making a single server respond to many URLs. Obviously there needs to be a nice simple way to add new colleges/teachers to the system. I imagine keeping that as the preserve of the overall admin person rather than allowing teachers to do it for themselves.
I managed to make a very simple testing demo in ComSwiki several months ago and then got lost in swikinet somehow. I think a part of the trouble is that it is very focussed on the swiki.net needs and digging out the infrastructure is hard work, even with Stephen trying to explain it. Of course, part of the problem is that I know a lot about the vm & low-level stuff but bugger all about writing applications.
So, all advice welcomed. I need to get this done _really_ quickly, I'm a long way behind on original estimates and things are getting desperate. I'll obviously need to know how to deal with permissions, logins, cookies, sessions, aaargh! Help Obi-wan WebPerson, you're my only hope!
tim
The most important thing is figuring out how you're storing (database, text file, ...) and representing the data (what objects you're using for it). Once you have those objects, most if not all of what you're proposing should be relatively easy. We haven't played with virtual hosts or anything in terms of different looks for essentially the same site and we haven't done much with permissions or authentication yet (only HTTP Basic at the moment) but both should be doable.
I'm heading out the door but Avi may have further suggestions and I'll look over it again tomorrow to see if I have any more. Obviously you can keep posting with questions.
Julian
Julian Fitzell julian@beta4.com is claimed by the authorities to have written:
Questions will (initially, there are dreams of more sophistication) consist of a text explaining the problem and a short (3-5) list of possible answers. The neat trick is that the list of answers will be re-ordered randomly each time they are presented to avoid students remembering "oh, that one was 'b' last time" so some way to remember the ordering used is needed. I'm assuming a session related var can do this.
Ordering is non-issue. If you create a list of radio buttons, you give it a Collection of items. The actual item associated with the selected radio button is given to you so you can do a straight comparison. Or even just have a flag in the PossibleAnswer object that indicates whether it is correct. All depends how you implement your data objects of course.
Err, I'm not sure I follow you here. I'm going to be randomly permuting the list of possible answers each time the question is displayed. I had been 'returning' a,b, etc as the result chosen and worrying about how to 'remember' what permutation was relevant to each occasion (obviously for five answers there's 120 possible permutations) and de-permuting. Are you suggesting that I can 'return' the entire answer string? That would certainly save one problem but might be painful if answer were big (maybe an image?). Or is there something else? Obviously it has to be hidden from the student to stop them cheating.
tim
On Wed, 24 Apr 2002, Tim Rowledge wrote:
Err, I'm not sure I follow you here. I'm going to be randomly permuting the list of possible answers each time the question is displayed. I had been 'returning' a,b, etc as the result chosen and worrying about how to 'remember' what permutation was relevant to each occasion (obviously for five answers there's 120 possible permutations) and de-permuting. Are you suggesting that I can 'return' the entire answer string? That would certainly save one problem but might be painful if answer were big (maybe an image?). Or is there something else? Obviously it has to be hidden from the student to stop them cheating.
Returning from what?
If you mean at the HTML (or rather HTTP POST) level, forget about it. Seaside doesn't operate at the level of the query string, it operates at the level of object pointers. So if you have a series of radio buttons, what you're giving the template is a collection of Answer objects, and what it's giving you back is the Answer object that was picked. It worries about generating unique IDs in the html so that it can figure out which one was actually picked, that's not your problem.
The first tutorial doesn't do a great job of making this clear, I guess. But notice that by the end of the tutorial, the radio buttons are built from an array of associations, and the 'conversion' instvar is being set to the chosen association. Your answers could similarly be associations of 'a'->'7 bananas', 'b'->'a bicycle', etc.
Am I completely misinterpreting what you're saying? Or does that help?
Avi
In message Pine.LNX.4.30.0204241132430.23670-100000@cable.beta4.com Avi Bryant avi@beta4.com wrote:
Returning from what?
If you mean at the HTML (or rather HTTP POST) level, forget about it. Seaside doesn't operate at the level of the query string, it operates at the level of object pointers. So if you have a series of radio buttons, what you're giving the template is a collection of Answer objects, and what it's giving you back is the Answer object that was picked. It worries about generating unique IDs in the html so that it can figure out which one was actually picked, that's not your problem.
Oh. Gosh, that sounds useful.
The first tutorial doesn't do a great job of making this clear, I guess.
I have to admit that I haven't played with the tutorial yet. I will, promise.
tim
On Mon, 22 Apr 2002, Tim Rowledge wrote:
So, all advice welcomed. I need to get this done _really_ quickly, I'm a long way behind on original estimates and things are getting desperate. I'll obviously need to know how to deal with permissions, logins, cookies, sessions, aaargh! Help Obi-wan WebPerson, you're my only hope!
Cookies. Heh! Sessions. Heh! A Jedi craves not these things. Help you I can. Yes, mmm.
So, here's my advice. 90% of the work in this app is going to be on the actual model. For now, forget about the web and all the nonsense that goes with it. Trust that Seaside will handle this effortlessly for you when the time comes. Instead, build the logic: how are questions represented? How are they structured into tests? How do you model a particular writing of a test, and where do you record the answers? How is this data persisted? Who can access/read/write which parts of it? Take this as far as you can and still be able to test it with SUnit instead of with a live interface. At that point, we should be able to guide you very easily through the triviality of performing these same operations over the web.
Now, that's not to say you shouldn't play around with the web stuff in the meantime. But there is a (usually justified) fear that the web will impose its own bizarre structures on the entire application, and that writing a web app is thus a completely different thing from writing any other code, which Seaside makes a concerted effort to prove false ("No! No different! Only different in your mind. You must unlearn what you have learned").
Ok, no more Yoda quotes. Go out and write the code, and come back when you want help with the dinky little HTML bits. And ask lots of questions when you do. I like answering questions, it saves me from having to write real documentation.
Cheers, Avi
In message Pine.LNX.4.30.0204230115050.16807-100000@cable.beta4.com Avi Bryant avi@beta4.com wrote:
Cookies. Heh! Sessions. Heh! A Jedi craves not these things. Help you I can. Yes, mmm.
Ah, master, grateful am I indeed. But what have you got in your pocketses?
OK, I'll try to worry about the actual model for a while. It'll be a nice change instead of fighting to get a login window. I'm still convinced the UI side will be the main hassle....
tim
seaside@lists.squeakfoundation.org