May 17, 2011
On 2011-05-16 15:43, Adam D. Ruppe wrote:
>> Instead you move the view layer into the model or controller
>> layer. How's that any different?
>
> Is that really what's happening? Any template has variables made
> available to it from the model. I'm just making them available
> at a higher level (pre-wrapped in semantic tags and grouped
> together).
>
> The actual layout and styling, sometimes even data formatting - the
> stuff I think of as the view - is still done entirely in the
> separate html and css files.
>
> I realize this isn't a perfect argument, but it's still worth it
> to me to have those other processing options available.

I got the impression that you basically did all HTML with D methods, maybe I don't understand your work flow.

-- 
/Jacob Carlborg
May 17, 2011
"Jacob Carlborg" <doob@me.com> wrote in message news:iqt6kb$1nd1$1@digitalmars.com...
> On 2011-05-16 15:43, Adam D. Ruppe wrote:
>>> Instead you move the view layer into the model or controller layer. How's that any different?
>>
>> Is that really what's happening? Any template has variables made available to it from the model. I'm just making them available at a higher level (pre-wrapped in semantic tags and grouped together).
>>
>> The actual layout and styling, sometimes even data formatting - the stuff I think of as the view - is still done entirely in the separate html and css files.
>>
>> I realize this isn't a perfect argument, but it's still worth it to me to have those other processing options available.
>
> I got the impression that you basically did all HTML with D methods, maybe I don't understand your work flow.
>

AIUI:

1. It starts out as ordinary HTML with no special non-standard tags or anything. But it might use id and class attributes to mean certain things.

2. In D, that HTML is loaded and parsed into an HTML DOM.

3. In D, the data is filled into the HTML DOM. Sometimes this might involve a amall amount of adding HTML tags/attributes or other weird tweaking if necessary.

4. The new HTML DOM is written out as straight HTML.

Basically just like DHTML, except on the server and using D.



May 17, 2011
"Nick Sabalausky" <a@a.a> wrote in message news:iqtarl$229l$1@digitalmars.com...
> "Jacob Carlborg" <doob@me.com> wrote in message news:iqt6kb$1nd1$1@digitalmars.com...
>> On 2011-05-16 15:43, Adam D. Ruppe wrote:
>>>> Instead you move the view layer into the model or controller layer. How's that any different?
>>>
>>> Is that really what's happening? Any template has variables made available to it from the model. I'm just making them available at a higher level (pre-wrapped in semantic tags and grouped together).
>>>
>>> The actual layout and styling, sometimes even data formatting - the stuff I think of as the view - is still done entirely in the separate html and css files.
>>>
>>> I realize this isn't a perfect argument, but it's still worth it to me to have those other processing options available.
>>
>> I got the impression that you basically did all HTML with D methods, maybe I don't understand your work flow.
>>
>
> AIUI:
>
> 1. It starts out as ordinary HTML with no special non-standard tags or anything. But it might use id and class attributes to mean certain things.
>
> 2. In D, that HTML is loaded and parsed into an HTML DOM.
>
> 3. In D, the data is filled into the HTML DOM. Sometimes this might involve a amall amount of adding HTML tags/attributes or other weird tweaking if necessary.
>
> 4. The new HTML DOM is written out as straight HTML.
>
> Basically just like DHTML, except on the server and using D.
>

And AIUI, it can also be thought of as being like an HTML templating engine, except instead of working with proprietary tags and text subsitution, it works with id/class attributes and an enhanced HTML DOM.



May 17, 2011
On 2011-05-17 10:11, Nick Sabalausky wrote:
> "Jacob Carlborg"<doob@me.com>  wrote in message
> news:iqt6kb$1nd1$1@digitalmars.com...
>> On 2011-05-16 15:43, Adam D. Ruppe wrote:
>>>> Instead you move the view layer into the model or controller
>>>> layer. How's that any different?
>>>
>>> Is that really what's happening? Any template has variables made
>>> available to it from the model. I'm just making them available
>>> at a higher level (pre-wrapped in semantic tags and grouped
>>> together).
>>>
>>> The actual layout and styling, sometimes even data formatting - the
>>> stuff I think of as the view - is still done entirely in the
>>> separate html and css files.
>>>
>>> I realize this isn't a perfect argument, but it's still worth it
>>> to me to have those other processing options available.
>>
>> I got the impression that you basically did all HTML with D methods, maybe
>> I don't understand your work flow.
>>
>
> AIUI:
>
> 1. It starts out as ordinary HTML with no special non-standard tags or
> anything. But it might use id and class attributes to mean certain things.
>
> 2. In D, that HTML is loaded and parsed into an HTML DOM.
>
> 3. In D, the data is filled into the HTML DOM. Sometimes this might involve
> a amall amount of adding HTML tags/attributes or other weird tweaking if
> necessary.
>
> 4. The new HTML DOM is written out as straight HTML.
>
> Basically just like DHTML, except on the server and using D.

Ok I see.

-- 
/Jacob Carlborg
May 17, 2011
On 2011-05-17 10:16, Nick Sabalausky wrote:
> "Nick Sabalausky"<a@a.a>  wrote in message
> news:iqtarl$229l$1@digitalmars.com...
>> "Jacob Carlborg"<doob@me.com>  wrote in message
>> news:iqt6kb$1nd1$1@digitalmars.com...
>>> On 2011-05-16 15:43, Adam D. Ruppe wrote:
>>>>> Instead you move the view layer into the model or controller
>>>>> layer. How's that any different?
>>>>
>>>> Is that really what's happening? Any template has variables made
>>>> available to it from the model. I'm just making them available
>>>> at a higher level (pre-wrapped in semantic tags and grouped
>>>> together).
>>>>
>>>> The actual layout and styling, sometimes even data formatting - the
>>>> stuff I think of as the view - is still done entirely in the
>>>> separate html and css files.
>>>>
>>>> I realize this isn't a perfect argument, but it's still worth it
>>>> to me to have those other processing options available.
>>>
>>> I got the impression that you basically did all HTML with D methods,
>>> maybe I don't understand your work flow.
>>>
>>
>> AIUI:
>>
>> 1. It starts out as ordinary HTML with no special non-standard tags or
>> anything. But it might use id and class attributes to mean certain things.
>>
>> 2. In D, that HTML is loaded and parsed into an HTML DOM.
>>
>> 3. In D, the data is filled into the HTML DOM. Sometimes this might
>> involve a amall amount of adding HTML tags/attributes or other weird
>> tweaking if necessary.
>>
>> 4. The new HTML DOM is written out as straight HTML.
>>
>> Basically just like DHTML, except on the server and using D.
>>
>
> And AIUI, it can also be thought of as being like an HTML templating engine,
> except instead of working with proprietary tags and text subsitution, it
> works with id/class attributes and an enhanced HTML DOM.

That would require a lot of otherwise (possibly) unnecessary id/class attributes (if they aren't removed). If you're not careful with your CSS you can accidentally style tags.

-- 
/Jacob Carlborg
May 17, 2011
Jacob Carlborg wrote:
> That would require a lot of otherwise (possibly) unnecessary
> id/class attributes (if they aren't removed).

Not that much in the sites I've done.

Here's another real example, that new d web site discussed on the newsgroup a while ago:

Dynamic page:
http://arsdnet.net/d-web-site/

The HTML template it manipulates with DOM: http://arsdnet.net/d-web-site/index.html


There's only three dynamic elements on that page, so the template is almost identical to the finished page.

There's three placeholders getting filled in:

<div id="announcements" />
<div id="commits" />

and <form id="code-runner">



And the relevant code:

form:

  auto f = cast(Form) document.getElementById("code-runner");
  f.setValue("code", `void main() { assert(0, "Hello, world!"); }`);


It fills the form, without caring about how the form is written. This does name="code" and sets value to that string given. It doesn't care how the HTML is written - here, it's a <textarea>, but this code remains the same if it's an <input> or <select>.

The view controls how the data is presented, the dom just tells it what to present.


Announcements and commits are done with more dom calls, but still, not much.

void addAnnouncements(Element holder) {
  auto document = holder.parentDocument;

  foreach(announcement; getAnnouncements()) {
    auto h = holder.addChild("div");

    auto date = std.date.parse(announcement.date);

    h.addChild("span", formatDate(date));
    h.appendText(" - ");
    h.appendChild(new Link(announcement.url, announcement.subject));
  }
}

Commits is a little longer since it has more data, but same idea.


Arguably, this crosses the line into presentation, especially
with that appendText call. (I guess it could do an #announcements >
span:after in css, but that's not reliable) But, you can see
that the vast majority of html is far away from here.

The #announcements id used to fill it in is also used to style the inside:

#announcements > div { style each announcement } #announcements > div > span { style the date } #announcements > div > a { style the link }


(man, css nesting is such a good thing to have!)




Side note: obviously, you don't *have* to do web apps my way, even with my libraries. cgi.d is template-agnostic. dom.d isn't going to kill you if you ask it to add logic to templates or do string replacement instead.

My way is just one possibility of many.
May 17, 2011
"Adam D. Ruppe" <destructionator@gmail.com> wrote in message news:iqua65$rm2$1@digitalmars.com...
>
>  auto f = cast(Form) document.getElementById("code-runner");
>  f.setValue("code", `void main() { assert(0, "Hello, world!"); }`);
>

Minor suggestion:

There should be an overload of getElementById that's defined like this:

T getElementById(T)(string str) if(is(T:WhateverYourBaseNodeTypeIs))
{
    auto node = cast(T) getElementById(str);
    if(node)
        return node;
    else
        throw new ElementNotFoundException(T.stringof, str);
}

class ElementNotFoundException : Exception
{
    this(string type, string str)
    {
        super("Element of type '"~type~"' matching '"~str~"' not found.");
    }
}

That way if it's missing, you get an accurate message instead of an awful null pointer exception. Or maybe call it requireElementById.

Or, of course, if it's in a class and can't have templated members (I really hate that limitation. Templated class members would be so much more useful than being able to ship .obj's and .lib's without the original source), then:

T getElementById(T)(WhateverYourBaseNodeTypeIs root, string str)
    if(is(T:WhateverYourBaseNodeTypeIs))
{
...
}

And, of course, just use the original getElementById if you want to allow the element to be optional.

Another separate thought:

What happens if you want to (or try to) put the same data in more than one place? Maybe there should be a way to detect and error if there's more than one of the same thing. Or maybe better yet, getElementById could return a special collection that contains all matching elements. And it could expose the same interface as a single element, but automatically applies it to all matched elements. Of course, you couldn't use "id=" for that since that's really not supposed to have duplicates. So you'd have to use "class=" instead. Which opens the possibility, if you're not doing this already, for the HTML importing (and maybe the DOM, too, or at least serializing the DOM at the end) to detect and error on multiple instances of the same "id=".


May 17, 2011
Nick Sabalausky wrote:
> There should be an overload of getElementById that's defined like this:

Aye, I've been thinking about that for a while, but could never think of a name I like (yeah, petty reason).

I've just trained myself to use assert to avoid the null pointers.

> Or maybe call it requireElementById.

That's a pretty good idea.

> Or, of course, if it's in a class and can't have templated members

It is a class, but the requireElementById (and it's counterpart, requireSelector*) could always be final. I can't think of a reason to override them anyway, especially since the underlying implementation in getElementById is still overridable anyway.

(same reason why I'm ok with opDispatch - it just forwards to
set/getAttribute)

This is definitely good though, it has the best cost/benefit ratio of things on the todo list. I take your name!


side note::

* After looking at haml yesterday, I'm tempted to do a nothrow requireSelector. Again, can't think of a name.

But what it'd do is try to get the first element that matches the css syntax. If it's not there, it starts from the best path that does exist and creates the rest.

So if you have a blank element <html></html> and you do:

makeSelector("html"); // that root node is returned since it exists

makeSelector("div > span.date");

That doesn't exist, so it does a

return document.root.addChild("div").addChild("span").className("date");


Though, I don't think I have a use for it; it'd be harder to use than just writing the html yourself in the template file.

:: end side note

> What happens if you want to (or try to) put the same data in more
> than one place?

Use a class or a custom attribute instead of id, then loop through the collection:

foreach(e; document.getElementsBySelector("div.announcements"))
    addAnnouncements(e);


Sometimes I do that even when there's just one because the return value there is guaranteed to never include null.


> Which opens the possibility, if you're not doing this already, for the HTML importing (and maybe the DOM, too, or at least serializing the DOM at the end) to detect and error on multiple instances of the same "id=".

No, it doesn't check that right now. It treats id as just another attribute for the most part. (getElementById returns the first one it sees in the tree.)

It always could, but I haven't felt it's worth the time yet.
May 18, 2011
On 2011-05-17 22:12, Adam D. Ruppe wrote:
> side note::
>
> * After looking at haml yesterday, I'm tempted to do a nothrow
> requireSelector. Again, can't think of a name.
>
> But what it'd do is try to get the first element that matches the
> css syntax. If it's not there, it starts from the best path that
> does exist and creates the rest.
>
> So if you have a blank element<html></html>  and you do:
>
> makeSelector("html"); // that root node is returned since it exists
>
> makeSelector("div>  span.date");
>
> That doesn't exist, so it does a
>
> return document.root.addChild("div").addChild("span").className("date");
>
>
> Though, I don't think I have a use for it; it'd be harder to use
> than just writing the html yourself in the template file.
>
> :: end side note

Sounds more like jQuery than HAML.

-- 
/Jacob Carlborg
May 19, 2011
On 5/13/2011 4:01 AM, Nick Sabalausky wrote:
> "Matthew Ong"<ongbp@yahoo.com>  wrote in message
> news:iqgo17$2nqv$1@digitalmars.com...
>> Hi Adam,
>>
>> Thanks again for the sharp pointed answer.
>>> What is the counterpart in D for replacing JSP/ASP/JRuby on Rail or
>>> some sort of dynamic web base development?
>>
>>> I use D for web work by using the standard CGI interface and>sometimes
>>> an embedded http server. It's the best thing I've ever used.
>> Could you share how or show an URL that provide sample code to do that in
>> D?
>>
>>
>>> How to also code digitally sign the DLL  that was compiled in D?
>> The same way you sign any other dll/exe.
>> So we use external tool to do that and not a build in one??
>> In java, we use jarsigner with some keygen.
>>
>> Please bear in mind I am new to D.
>>
>
> Here's a basic "Hello world" CGI app in D:
>
> // hellocgi.d
> import std.conv;
> import std.stdio;
>
> void main()
Hmm...Might be problem for it to be main... Security concerned because of the publicity done my M$ and others also. When they pushed for ASP/JSP...
> {
>      // Read in HTTP request headers
>      string[] requestHeaders;
>      while(true)
>      {
>          string line = readln();
>          if(line.length<= 1)
>              break;
>
>          requestHeaders ~= line;
>      }
>
>      // Send response headers
>      writeln("Status: 200 OK");
>      writeln("Content-Type: text/html; charset=UTF-8");
>      writeln();
>
>      // Send content
>      writeln("<b><i>Hello world</i></b>");
> }
>
> Compile with:
> dmd hellocgi.d
>
> And just stick the resulting "hellocgi.exe" (windows) or "hellocgi" (other)
> in whatever "cgi-bin"-capable directory you have on your server.
Thanks for this Example also. I will keep it for later trial.

> Everything else (such as fancy CGI libraries/frameworks like Adam's) can
> ultimately be built out of that basic idea.
>
> Keep in mind though, that since D is natively compiled, you'll have to
> compile it on either the same OS and CPU architecture as your server, or an
> OS/CPU that's compatible with your server. (This would be true of C/C++ as
> well.)
yes. I am aware about that. Thanks very much.
> I'm sure it's possible to make an ISAPI filter or Apache module in D, but
> I've never really done that in any langauge, and I haven't really dealt with
> DLLs much, so I wouldn't know how. But even as CGI, a web app in D is likely
> to still be much faster than one in, for instance, PHP or Ruby.
Why I am looking for DLL as compare to exe is becuase it is a well know security concern
published and accepted as minimum by the industry for MNC.


-- 
Matthew Ong
email: ongbp@yahoo.com