And repeated for div, table, td, etc. I considered using dynamic invoke for this instead of repeating implementations for each tag:
out->divStart(["class":"foobar"]).nl
out.in.w("This is a test ").br.w(" Dude").nl
out->divEnd.nl
<div class="foobar">
This is a test <br/> Dude
</div>
This approach makes more sense for XmlOutStream - but since WebOutStream has a fixed element vocabulary, not sure if just implementing every method makes more sense. Also, there are rules about how certain elements can be used:
So I'm thinking we don't use dynamic invoke, and just provide API convience methods for the 10-15 most commonly used tags. What are your guys thoughts?
andyMon 12 Jun 2006
Actually, I'm not sure that we just don't use string interpolation and multi-line strings now:
out.w("
<div class='foobar'>
This is a test <br/> Dude
</div>").nl
My previous post may be attempting to overcomplicate the situation.
brianMon 12 Jun 2006
I would like to see the signatures you are planning for XmlOutStream because that is where we should standardize element start, end, and attributes.
First off I think we should use the standard XML term "element" rather than "span".
After some thought I think I'm against the idea of using map for the attributes - it is elegant from a source code perspective but very expensive from a runtime perspective because we have to allocate and populate a map on each call. Maybe we could come up with some compiler optimization, but otherwise I think we ought to do a more traditional approach with an attr(Str, Str) method.
So to rework your code above:
mixin XmlOutStream
mixin OutStream
{
XmlOutStream elemStart()
XmlOutStream attr(Str key, Str val)
XmlOutStream elemEnd()
}
out->divStart->attr("class", "foobar")->nl
out->in->w("This is a test ")->br->w(" Dude")->nl
out->divEnd->nl
Also note that I don't think using -> dynamic invoke operator can return anything other than Obj because it is by definition not known at compile time. Therefore to chain you will have to use -> and never dot.
andyMon 12 Jun 2006
Yeah, I think trying to force an API for HTML ends up being counter-productive when actually using it. The multi-line string and string interpolation approach is much closer to PHP or erb, which are both very productive.
brianMon 12 Jun 2006
That doesn't work either because we need a standard way to escape into XML (or SQL or whatever it may be). I guess we could put an escape method into Str itself so that you do things like "<td>$name.xml</td>". We need to solve that problem though.
andyMon 12 Jun 2006
Well I think that is actually the best way to solve that problem - adding a method to Str.
andyThu 15 Jun 2006
I started to do some markup using the "PHP" way - and I realized that there is actually a ton of verbosity in doing HTML that gets in the way - especially when trying to make it XHTML valid (not to mention error prone).
So I decided to give my original idea another shot. And while its a much curter solution, I still hit the attributes problem. But then it hit me, just let the developer type in the entire attribute string:
out.div("class='foobar'")
out.in.w("This is a test ").br.w(" Dude").nl
out.divEnd
And I found this was actually both pretty effective, as well as more readable. I'm going to mull on it some more before I commit to it, but I think this is the direction I am heading.
brianThu 15 Jun 2006
Except use tab instead of in :)
andyTue 20 Jun 2006
I checked in my initial version of WebOutStream - its incomplete, but the big picture exists. John, you should look at the API and comment.
We need to figure out what we're going to do here, design-wise. I was thinking we have two classes, like so, where WebOutStream extends XmlOutStream and adds html methods.
XmlOutStream
|
+- WebOutStream
With XmlOutStream eventually moving into the xml pod (I would assume). I'm not sure what the XmlOutStream looks like yet - probably a more formalized and simplified version of WebOutStream:
Overall I think I like it - I'll have to play with the attributes passed as straight strings.
I think the two mixins are xml::XmlOutStream and web::HtmlOutStream - with maybe HtmlOutStream moving into an html module. We should go ahead and define the XmlOutStream API now in a stubbed xml module. It is important to figure out which role each one will play up front.
John really needs to figure out if we can do covariance because it would give us a lot more flexibility in designing APIs like this where methods commonly return this (for subclasses to override to return the narrowed type).
I think startTag should have a matching endTag - you don't consistently route all your methods to startTag, which I think you should do (and route to endTag too).
andy Sun 11 Jun 2006
I think I have narrowed down an API I like for the WebOutStream. Its mainly built around three methods:
And repeated for div, table, td, etc. I considered using dynamic invoke for this instead of repeating implementations for each tag:
This approach makes more sense for XmlOutStream - but since WebOutStream has a fixed element vocabulary, not sure if just implementing every method makes more sense. Also, there are rules about how certain elements can be used:
So I'm thinking we don't use dynamic invoke, and just provide API convience methods for the 10-15 most commonly used tags. What are your guys thoughts?
andy Mon 12 Jun 2006
Actually, I'm not sure that we just don't use string interpolation and multi-line strings now:
My previous post may be attempting to overcomplicate the situation.
brian Mon 12 Jun 2006
I would like to see the signatures you are planning for XmlOutStream because that is where we should standardize element start, end, and attributes.
First off I think we should use the standard XML term "element" rather than "span".
After some thought I think I'm against the idea of using map for the attributes - it is elegant from a source code perspective but very expensive from a runtime perspective because we have to allocate and populate a map on each call. Maybe we could come up with some compiler optimization, but otherwise I think we ought to do a more traditional approach with an attr(Str, Str) method.
So to rework your code above:
Also note that I don't think using -> dynamic invoke operator can return anything other than Obj because it is by definition not known at compile time. Therefore to chain you will have to use -> and never dot.
andy Mon 12 Jun 2006
Yeah, I think trying to force an API for HTML ends up being counter-productive when actually using it. The multi-line string and string interpolation approach is much closer to PHP or erb, which are both very productive.
brian Mon 12 Jun 2006
That doesn't work either because we need a standard way to escape into XML (or SQL or whatever it may be). I guess we could put an escape method into Str itself so that you do things like "<td>$name.xml</td>". We need to solve that problem though.
andy Mon 12 Jun 2006
Well I think that is actually the best way to solve that problem - adding a method to Str.
andy Thu 15 Jun 2006
I started to do some markup using the "PHP" way - and I realized that there is actually a ton of verbosity in doing HTML that gets in the way - especially when trying to make it XHTML valid (not to mention error prone).
So I decided to give my original idea another shot. And while its a much curter solution, I still hit the attributes problem. But then it hit me, just let the developer type in the entire attribute string:
And I found this was actually both pretty effective, as well as more readable. I'm going to mull on it some more before I commit to it, but I think this is the direction I am heading.
brian Thu 15 Jun 2006
Except use tab instead of in :)
andy Tue 20 Jun 2006
I checked in my initial version of WebOutStream - its incomplete, but the big picture exists. John, you should look at the API and comment.
We need to figure out what we're going to do here, design-wise. I was thinking we have two classes, like so, where WebOutStream extends XmlOutStream and adds html methods.
With XmlOutStream eventually moving into the xml pod (I would assume). I'm not sure what the XmlOutStream looks like yet - probably a more formalized and simplified version of WebOutStream:
Comments?
brian Wed 21 Jun 2006
Overall I think I like it - I'll have to play with the attributes passed as straight strings.
I think the two mixins are xml::XmlOutStream and web::HtmlOutStream - with maybe HtmlOutStream moving into an html module. We should go ahead and define the XmlOutStream API now in a stubbed xml module. It is important to figure out which role each one will play up front.
John really needs to figure out if we can do covariance because it would give us a lot more flexibility in designing APIs like this where methods commonly return this (for subclasses to override to return the narrowed type).
I think startTag should have a matching endTag - you don't consistently route all your methods to startTag, which I think you should do (and route to endTag too).